upload tizen1.0 source
[pkgs/o/oma-ds-service.git] / src / ServiceAdapter / SA_Session.c
1 /*
2  * oma-ds-service
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JuHak Park <juhaki.park@samsung.com>,
7  *          JuneHyuk Lee <junhyuk7.lee@samsung.com>,
8  *          SunBong Ha <sunbong.ha@samsung.com>
9  *
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
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
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.
21  *
22  */
23
24
25
26
27 /*
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.
32  *
33  * SeongWon Shim <seongwon.shim@samsung.com>
34  */
35
36 /**
37  *   @SA_Session.c
38  *   @version                                                                   0.1
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
40  */
41
42 /*FIXME temporary*/
43 #include "agent-framework/SyncAgent_Info.h"
44
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"
56
57 #define LOG_TAG "OMA_DS_SA"
58
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);
66
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);
74
75 static void __free_pending_status(PendingStatus *pendingStatus);
76 static SA_ErrorType __add_mapping(Session *session, char *guid, char *luid, int datastore_id);
77
78
79 static SA_ErrorType __receive_alert_status(Session *session, Status *status)
80 {
81         FW_LOGV("start");
82
83         SA_ErrorType errorType = SA_INTERNAL_OK;
84
85         unsigned int code = get_status_code(status);
86         FW_LOGV("code = %d", code);
87
88         if (code >= 400 && code != ERROR_REQUIRE_REFRESH) {
89                 /*401   unauthorized
90                 407     Authentication required
91                 405     command not allowed
92                 406     optional feature not supported
93                 500     command failed
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~!!!!!*/
98
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*/
105
106                 }
107         }
108
109         FW_LOGV("end");
110         return errorType;
111 }
112
113 static SA_ErrorType __receive_put_status(Session *session, Status *status)
114 {
115         FW_LOGV("start");
116
117         SA_ErrorType errorType = SA_INTERNAL_OK;
118
119         unsigned int code = get_status_code(status);
120         FW_LOGV("code = %d", code);
121
122         if (code >= 400) {
123                 /*TODO error handling it's error~!!!!!
124                 401 unauthorized
125                 407 authentication required
126                 411 size required
127                 413 request entity too large
128                 416 requested size too big
129                 415 unspported media type or format
130                 420 device full
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;
136                 else
137                         errorType = SA_INTERNAL_ERROR;
138         }
139
140         FW_LOGV("end");
141         return errorType;
142 }
143
144 static SA_ErrorType __receive_get_status(Session *session, Status *status)
145 {
146         FW_LOGV("start");
147
148         SA_ErrorType errorType = SA_INTERNAL_OK;
149
150         unsigned int code = get_status_code(status);
151         FW_LOGV("code = %d", code);
152
153         if (code >= 400) {
154                 /*TODO error handling it's error~!!!!!
155                 401 unauthorized
156                 407 authentication required
157                 404 not found
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;
167                 else
168                         errorType = SA_INTERNAL_ERROR;
169         }
170
171         FW_LOGV("end");
172         return errorType;
173 }
174
175 static SA_ErrorType __receive_results_status(Session *session, Status *status)
176 {
177         FW_LOGV("start");
178
179         SA_ErrorType errorType = SA_INTERNAL_OK;
180
181         unsigned int code = get_status_code(status);
182         FW_LOGV("code = %d", code);
183
184         if (code >= 400) {
185                 /*TODO error handling it's error~!!!!!
186                 401 unauthorized
187                 407 authentication required
188                 404 not found
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;
198                 else
199                         errorType = SA_INTERNAL_ERROR;
200         }
201
202         FW_LOGV("end");
203         return errorType;
204 }
205
206 static SA_ErrorType __receive_sync_status(Session *session, Status *status)
207 {
208         FW_LOGV("start");
209
210         SA_ErrorType errorType = SA_INTERNAL_OK;
211
212         unsigned int code = get_status_code(status);
213         FW_LOGV("code = %d", code);
214
215         if (code >= 400 && code != ERROR_REQUIRE_REFRESH) {
216                 /*TODO error handling it's error~!!!!!
217                 401 unauthorized
218                 407 authentication required
219                 403 forbidden
220                 404 not found
221                 405 command not allowed
222                 508 refresh required
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;
230                 else
231                         errorType = SA_INTERNAL_ERROR;
232         }
233
234         FW_LOGV("end");
235         return errorType;
236 }
237
238 static SA_ErrorType __receive_changes_status(Session *session, Status *status, GList **returnStatus)
239 {
240         FW_LOGV("start");
241
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);
247
248         unsigned int code = get_status_code(status);
249         FW_LOGV("code = %d", code);
250
251         SA_ErrorType errorType = SA_INTERNAL_OK;
252
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) {
257
258                         if (code == CHUNK_ACCEPTED) {
259                                 __free_pending_status(largeObj);
260                                 session->largeObj = NULL;
261                                 return errorType;
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) {
266
267                         }
268                 }
269         }
270
271         /*pass to engine*/
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;
278                 }
279                 *returnStatus = g_list_append(*returnStatus, appliedStatus);
280         }
281
282         FW_LOGV("end");
283         return errorType;
284 }
285
286 static SA_ErrorType __receive_map_status(Session *session, Status *status)
287 {
288         FW_LOGV("start");
289
290         SA_ErrorType errorType = SA_INTERNAL_OK;
291         DACI_RETURN da_err ;
292
293         GList *iter = NULL;
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;
298
299                 if (pCommand->msgID == status->msgRef && pCommand->cmdID == status->cmdRef) {
300                         code = get_status_code(status);
301                         FW_LOGV("code = %d", code);
302
303                         if (code == 200) {
304                                 GList *itemIter = NULL;
305                                 Item *item = 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");
313                                                 return errorType;
314                                         }
315                                 }
316                                 session->mapCommand  = g_list_remove(session->mapCommand , pCommand);
317                                 free_command(pCommand);
318                                 break;
319                         } else if (code >= 400) {
320                                 /*401 unauthorized
321                                 407 authentication required
322                                 420 device full
323                                 510 data store failure
324                                 500 command failed*/
325
326                                 if (code >= 500) {
327                                         /*map command has failed so delete failed map command from session->mapCpmmand*/
328                                         GList *itemIter = NULL;
329                                         Item *item = 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");
337                                                         return errorType;
338                                                 }
339                                         }
340                                         session->mapCommand  = g_list_remove(session->mapCommand , pCommand);
341                                         free_command(pCommand);
342                                         break;
343                                 }
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;
350                                 else
351                                         errorType = SA_INTERNAL_ERROR;
352                         }
353                 }
354         }
355
356         FW_LOGV("end");
357         return errorType;
358 }
359
360 static SA_ErrorType __receive_alert_command(Session *session, Command *command, GList **returnDatastore)
361 {
362         FW_LOGV("start");
363
364         SA_ErrorType errorType = SA_INTERNAL_OK;
365
366         if (!command->source) {
367                 errorType = SA_INTERNAL_NOT_DEFINED;
368                 goto error;
369         }
370
371         if (!command->target) {
372                 errorType = SA_INTERNAL_NOT_DEFINED;
373                 goto error;
374         }
375         /*401   unauthorized
376         407     Authentication required
377         405     command not allowed
378         406     optional feature not supported
379         500     command failed
380         412     Incomplete command
381         415 unsupported media type or format*/
382
383         Status *temp = NULL;
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) {
388
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;
392                         goto error;
393                 }
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);
398
399                 *returnDatastore = g_list_append(*returnDatastore, datastore);
400
401                 errorType = create_new_status(session, NO_ERROR, command,  COMMAND_TYPE_ALERT , &temp);
402                 if (errorType != SA_INTERNAL_OK)
403                         goto error;
404
405                 temp->item = create_item();
406                 if (!(temp->item)) {
407                         errorType = SA_INTERNAL_NO_MEMORY;
408                         goto error;
409                 }
410                 set_item_anchor(temp->item,  command->private.alert.anchor);
411                 session->status = g_list_append(session->status, temp);
412
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) {
415
416                 errorType = create_new_status(session, NO_ERROR, command,  COMMAND_TYPE_ALERT , &temp);
417                 if (errorType != SA_INTERNAL_OK)
418                         goto error;
419
420                 session->status = g_list_append(session->status, temp);
421         } else
422                 goto not_found_error;
423
424         FW_LOGV("end");
425
426         return errorType;
427
428 not_found_error:
429         errorType = create_new_status(session, ERROR_NOT_FOUND, command,  COMMAND_TYPE_ALERT , &temp);
430         if (errorType != SA_INTERNAL_OK)
431                 goto error;
432
433         session->status = g_list_append(session->status, temp);
434         return SA_INTERNAL_NOT_FOUND;
435
436 error:
437         FW_LOGE("error: %d", errorType);
438         return errorType;
439 }
440
441 static SA_ErrorType __receive_put_command(Session *session, Command *command)
442 {
443         FW_LOGV("start");
444
445         SA_ErrorType errorType = SA_INTERNAL_OK;
446
447         /*401 unauthorized
448         407 authentication required
449         411 size required
450         413 request entity too large
451         416 requested size too big
452         415 unspported media type or format
453         420 device full
454         500 command failed*/
455
456         Status *temp = NULL;
457
458         if (strcmp(command->private.access.type , ELEMENT_DEVINF_XML) == 0 ||
459                         strcmp(command->private.access.type , ELEMENT_DEVINF_WBXML) == 0) {
460                 /*if it is devinf*/
461                 if (command->private.access.item) {
462                         session->remoteDevInf = command->private.access.item->private.devInf;
463                 }
464                 errorType = create_new_status(session, NO_ERROR,  command,  COMMAND_TYPE_PUT, &temp);
465                 if (errorType != SA_INTERNAL_OK)
466                         goto error;
467         } else
468                 goto not_found_error;
469
470
471
472         session->status = g_list_append(session->status, temp);
473
474         FW_LOGV("end");
475
476         return errorType;
477
478 not_found_error:
479         errorType = create_new_status(session, ERROR_NOT_FOUND, command,  COMMAND_TYPE_PUT , &temp);
480         if (errorType != SA_INTERNAL_OK)
481                 goto error;
482
483         session->status = g_list_append(session->status, temp);
484         return SA_INTERNAL_NOT_FOUND;
485
486 error:
487         FW_LOGE("error: %d", errorType);
488         return errorType;
489 }
490
491 static SA_ErrorType __receive_get_command(Session *session, Command *command)
492 {
493         FW_LOGV("start");
494
495         SA_ErrorType errorType = SA_INTERNAL_OK;
496         Status *temp = NULL;
497         Command *pCommand = NULL;
498         Location *pLocation = NULL;
499
500         if (strcmp(command->private.access.type , ELEMENT_DEVINF_XML) == 0 ||
501                         strcmp(command->private.access.type , ELEMENT_DEVINF_WBXML) == 0) {
502
503                 errorType = create_new_status(session, NO_ERROR,  command,  COMMAND_TYPE_GET, &temp);
504                 if (errorType != SA_INTERNAL_OK)
505                         goto error;
506
507                 session->status = g_list_append(session->status, temp);
508
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;
516
517                 errorType = create_location(sourceDevInf, NULL, &pLocation);
518                 if (errorType != SA_INTERNAL_OK)
519                         goto error;
520
521                 errorType = create_results_command(session, pLocation, ELEMENT_DEVINF_XML, session->devInf, &pCommand);
522                 if (errorType != SA_INTERNAL_OK)
523                         goto error;
524
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);
528
529                 session->resultsCommand = g_list_append(session->resultsCommand, pCommand);
530         } else
531                 goto not_found_error;
532
533
534         FW_LOGV("end");
535
536         return errorType;
537
538 not_found_error:
539         errorType = create_new_status(session, ERROR_NOT_FOUND, command,  COMMAND_TYPE_GET , &temp);
540         if (errorType != SA_INTERNAL_OK)
541                 goto error;
542
543         session->status = g_list_append(session->status, temp);
544         return SA_INTERNAL_NOT_FOUND;
545
546 error:
547         FW_LOGE("error: %d", errorType);
548         return errorType;
549 }
550
551 static SA_ErrorType __receive_results_command(Session *session, Command *command)
552 {
553         FW_LOGV("start");
554
555         SA_ErrorType errorType = SA_INTERNAL_OK;
556
557         Status *temp = NULL;
558
559         if (strcmp(command->private.results.type , ELEMENT_DEVINF_XML) == 0 ||
560                         strcmp(command->private.results.type , ELEMENT_DEVINF_WBXML) == 0) {
561                 /*if it is devinf*/
562                 if (command->private.results.item) {
563                         session->remoteDevInf = command->private.results.item->private.devInf;
564
565                         errorType = create_new_status(session, NO_ERROR,  command,  COMMAND_TYPE_RESULTS, &temp);
566                         if (errorType != SA_INTERNAL_OK)
567                                 goto error;
568
569                         session->status = g_list_append(session->status, temp);
570                 }
571         } else
572                 goto not_found_error;
573
574         FW_LOGV("end");
575
576         return errorType;
577
578 not_found_error:
579         errorType = create_new_status(session, ERROR_NOT_FOUND, command,  COMMAND_TYPE_RESULTS , &temp);
580         if (errorType != SA_INTERNAL_OK)
581                 goto error;
582
583         session->status = g_list_append(session->status, temp);
584         return SA_INTERNAL_NOT_FOUND;
585
586 error:
587         FW_LOGE("error: %d", errorType);
588         return errorType;
589 }
590
591 static SA_ErrorType  __receive_sync_command(Session *session, Command *command, ChangedDatastore **changedDatastore)
592 {
593         FW_LOGV("start");
594
595         SA_ErrorType errorType = SA_INTERNAL_OK;
596
597         if (!command->source) {
598                 errorType = SA_INTERNAL_NOT_DEFINED;
599                 return errorType;
600         }
601
602         if (!command->target) {
603                 errorType = SA_INTERNAL_NOT_DEFINED;
604                 return errorType;
605         }
606
607         /*TODO
608         need to check that if target has not exist in client
609         it's a error(return status)
610         and return Datastore index
611
612         401 unauthorized
613         407 authentication required
614         403 forbidden
615         404 not founc
616         405 command not allowed
617         508 refresh required
618         500 command failed
619
620         TODO compare with alert command(?)*/
621
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;
627
628         Status *temp = NULL;
629         errorType = create_new_status(session, NO_ERROR, command,  COMMAND_TYPE_SYNC_START , &temp);
630         if (errorType != SA_INTERNAL_OK)
631                 goto error;
632
633         session->status = g_list_append(session->status, temp);
634
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;
641                 goto error;
642         } else
643                 *changedDatastore = pChangedDatastore;
644
645         FW_LOGV("end");
646
647         return errorType;
648
649 not_found_error:
650         errorType = create_new_status(session, ERROR_NOT_FOUND, command,  COMMAND_TYPE_SYNC_START , &temp);
651         if (errorType != SA_INTERNAL_OK)
652                 goto error;
653
654         session->status = g_list_append(session->status, temp);
655         return SA_INTERNAL_NOT_FOUND;
656
657 error:
658         FW_LOGE("error: %d", errorType);
659         return errorType;
660 }
661
662 static SA_ErrorType __receive_changes_command(Session *session, Command *command, char **luid_str_list,
663                                                                                                                                                         int *index, ChangedDatastore **changedDatastore)
664 {
665         FW_LOGV("start command type :  %d\n",  command->private.change.type);
666
667         SA_ErrorType errorType = SA_INTERNAL_OK;
668
669         GList *iter = NULL;
670         ChangedItem *changed = NULL;
671         char *luid;
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);
675
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*/
681
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;
696                                                 } else {
697                                                         item->private.data = strdup(changedItem->private.data);
698                                                 }
699                                                 Status *temp = NULL;
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");
704                                                         goto error;
705                                                 }
706                                                 session->status = g_list_append(session->status, temp);
707                                                 alertType = ALERT_NEXT_MESSAGE;
708                                         } else{
709                                                 /* it's a new data object or command but this command also have a moreData*/
710                                                 alertType = ALERT_NO_END_OF_DATA;
711                                         }
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");
718                                                 goto error;
719                                         }
720                                         session->alertCommand = g_list_append(session->alertCommand, pAlertCommand);
721                                 }
722                         } else{
723                                 /*first chunked item
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) {
727                                         /*size required*/
728                                         statusErrorType = ERROR_SIZE_REQUIRED;
729                                 } else{
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;
734                                         } else{
735                                                 /*chunked item accepted*/
736                                                 session->pLargeObjCmd = command;
737                                                 increase_command_refcount(command);
738
739                                                 statusErrorType = CHUNK_ACCEPTED;
740
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");
748                                                         goto error;
749                                                 }
750                                                 session->alertCommand = g_list_append(session->alertCommand, pAlertCommand);
751                                         }
752
753                                         Status *temp = NULL;
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");
758                                                 goto error;
759                                         }
760                                         session->status = g_list_append(session->status, temp);
761                                 }
762                         }
763                 } else{
764                         if (session->pLargeObjCmd) {
765
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*/
769
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;
776
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;
784                                                 } else {
785                                                         item->private.data = strdup(changedItem->private.data);
786
787                                                         if (item->private.data == NULL) {
788                                                                 FW_LOGE("item->private.data is null !!");
789                                                                 goto error;
790                                                         }
791                                                 }
792
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*/
801                                                         iter->data = item;
802                                                         changedItem = item;
803                                                         FW_LOGV("pointing to Merged item in incomming Cmd");
804
805                                                         free_command(session->pLargeObjCmd);
806                                                         session->pLargeObjCmd = NULL;
807                                                 } else{
808                                                         Status *temp = 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");
814                                                                 goto error;
815                                                         }
816                                                         session->status = g_list_append(session->status, temp);
817                                                 }
818                                         } else{
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");
827                                                         goto error;
828                                                 }
829                                                 session->alertCommand = g_list_append(session->alertCommand, pAlertCommand);
830                                         }
831                                 }
832                         }
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;
842
843                                 luid = luid_str_list[(*index)++];
844                                 if (luid == NULL) {
845                                         FW_LOGE("luid is null");
846                                         errorType = SA_INTERNAL_ERROR;
847                                         goto error;
848                                 }
849
850                                 FW_LOGV("index = %d", *index);
851                                 FW_LOGV("luid = %s", luid);
852
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");
856                                         goto error;
857                                 }
858                         } else{
859                                 luid = get_location_locuri(changedItem->target);
860                                 if (luid == NULL) {
861                                         FW_LOGE("luid is null");
862                                         errorType = SA_INTERNAL_ERROR;
863                                         goto error;
864                                 }
865                         }
866
867                         changed = create_changeditem(changeType, luid);
868                         if (changed == NULL) {
869                                 FW_LOGE("changed is null");
870                                 errorType = SA_INTERNAL_NO_MEMORY;
871                                 goto error;
872                         }
873
874                         if (changeType != CHANGE_DELETE) {
875                                 set_changeditem_contenttype(changed, changedItem->contenttype);
876                                 set_changeditem_data(changed, changedItem->private.data);
877                         }
878
879                         Status *temp = NULL;
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");
885                                 goto error;
886                         }
887                         session->tempStatus = g_list_append(session->tempStatus, temp);
888
889                         (*changedDatastore)->changeItem = g_list_append((*changedDatastore)->changeItem, changed);
890                 }
891         }
892         FW_LOGV("end");
893
894         return errorType;
895
896 error:
897         FW_LOGE("error: %d", errorType);
898         return errorType;
899 }
900
901 static void __free_pending_status(PendingStatus *pendingStatus)
902 {
903         FW_LOGV("start");
904
905         if (!pendingStatus)
906                 return;
907
908         free(pendingStatus);
909         pendingStatus = NULL;
910
911         FW_LOGV("end");
912
913         return;
914 }
915
916 static SA_ErrorType __add_mapping(Session *session, char *guid, char *luid, int datastore_id)
917 {
918         FW_LOGV("start");
919
920         SA_ErrorType errorType = SA_INTERNAL_OK;
921
922         daci_mapping mapping;
923         mapping.account_id = session->accountId;
924         mapping.data_store_id = datastore_id;
925         mapping.luid =  luid;
926         mapping.guid = guid;
927         mapping.access_name = "SA";
928
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;
933                 goto error;
934         }
935
936         FW_LOGV("end");
937         return errorType;
938
939 error:
940
941         FW_LOGE("error: %d", errorType);
942         return errorType;
943 }
944
945 SA_ErrorType create_session(ProtocolVersion protocolVersion, ProtocolType protocolType, int accountId,
946                                                                                         char *sessID,  char *source, char *target, Session** pSession)
947 {
948         FW_LOGV("start");
949
950         SA_ErrorType errorType = SA_INTERNAL_OK;
951         Location *pSourceLocation  = NULL;
952         Location *pTargetLocation = NULL;
953
954         *pSession = (Session *) calloc(1, sizeof(Session));
955
956         if ((*pSession) == NULL) {
957                 errorType = SA_INTERNAL_NO_MEMORY;
958                 goto error;
959         }
960
961         errorType = create_location(source, NULL, &pSourceLocation);
962         if (errorType != SA_INTERNAL_OK)
963                 goto error;
964
965         errorType = create_location(target, NULL, &pTargetLocation);
966         if (errorType != SA_INTERNAL_OK)
967                 goto error;
968
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;
977
978         (*pSession)->sourceMaxMsgSize = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_MSG_SIZE;
979         (*pSession)->sourceMaxObjSize = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_OBJ_SIZE;
980
981         (*pSession)->targetMaxMsgSize = 0;
982         (*pSession)->targetMaxObjSize = 0;
983
984         (*pSession)->NACI_sessionID = 0;
985         (*pSession)->hasOpend = 0;
986
987         FW_LOGV("end");
988
989         return errorType;
990
991 error:
992         FW_LOGE("error: %d", errorType);
993         return errorType;
994 }
995
996 void free_session(Session *session)
997 {
998         FW_LOGV("start");
999
1000         if (!session)
1001                 return;
1002
1003         if (session->sessionID) {
1004                 free(session->sessionID);
1005                 session->sessionID = NULL;
1006         }
1007
1008         free_statuses(session->status);
1009         session->status = NULL;
1010
1011         free_statuses(session->tempStatus);
1012         session->status = NULL;
1013
1014         if (session->target) {
1015                 free_location(session->target);
1016                 session->target = NULL;
1017         }
1018
1019         if (session->source) {
1020                 free_location(session->source);
1021                 session->source = NULL;
1022         }
1023
1024         if (session->orgTarget) {
1025                 free_location(session->orgTarget);
1026                 session->orgTarget = NULL;
1027         }
1028
1029         if (session->cred) {
1030                 free_cred(session->cred);
1031                 session->cred = NULL;
1032         }
1033
1034         if (session->chal) {
1035                 free_chal(session->chal);
1036                 session->chal = NULL;
1037         }
1038
1039         if (session->devInf) {
1040                 free_devinf(session->devInf);
1041                 session->devInf = NULL;
1042         }
1043
1044         if (session->remoteDevInf) {
1045                 free_devinf(session->remoteDevInf);
1046                 session->remoteDevInf = NULL;
1047         }
1048
1049         if (session->pLargeObjCmd) {
1050                 free_command(session->pLargeObjCmd);
1051                 session->pLargeObjCmd = NULL;
1052         }
1053
1054         free_commands(session->resultsCommand);
1055         session->resultsCommand = NULL;
1056
1057         free_commands(session->mapCommand);
1058         session->mapCommand = NULL;
1059
1060         if (session)
1061                 free(session);
1062
1063         FW_LOGV("end");
1064
1065         return;
1066
1067 }
1068
1069 SA_ErrorType create_pending_status(unsigned int msgID, unsigned int cmdID, PendingStatus **pPendingStatus)
1070 {
1071         FW_LOGV("start");
1072
1073         SA_ErrorType errorType = SA_INTERNAL_OK;
1074
1075         *pPendingStatus = (PendingStatus *)calloc(1, sizeof(PendingStatus));
1076
1077         if (*pPendingStatus == NULL) {
1078                 errorType = SA_INTERNAL_NO_MEMORY;
1079                 goto error;
1080         }
1081
1082         (*pPendingStatus)->msgID = msgID;
1083         (*pPendingStatus)->cmdID = cmdID;
1084
1085         FW_LOGV("end");
1086
1087         return errorType;
1088
1089 error:
1090         FW_LOGE("error: %d", errorType);
1091         return errorType;
1092 }
1093
1094 void set_session_cred(Session *session, Cred *cred)
1095 {
1096         FW_LOGV("start");
1097
1098         SA_ErrorType errorType = SA_INTERNAL_OK;
1099
1100         if (!session) {
1101                 errorType = SA_INTERNAL_NOT_DEFINED;
1102                 goto error;
1103         }
1104
1105         if (!cred) {
1106                 errorType = SA_INTERNAL_NOT_DEFINED;
1107                 goto error;
1108         }
1109
1110         session->cred = cred;
1111
1112         FW_LOGV("end");
1113         return;
1114
1115 error:
1116         FW_LOGE("error: %d", errorType);
1117         return;
1118
1119 }
1120
1121 void set_session_devinf(Session *session, DevInf *devInf)
1122 {
1123         FW_LOGV("start");
1124
1125         SA_ErrorType errorType = SA_INTERNAL_OK;
1126
1127         if (!session) {
1128                 errorType = SA_INTERNAL_NOT_DEFINED;
1129                 goto error;
1130         }
1131
1132         if (!devInf) {
1133                 errorType = SA_INTERNAL_NOT_DEFINED;
1134                 goto error;
1135         }
1136
1137         session->devInf = devInf;
1138
1139         FW_LOGV("end");
1140         return ;
1141
1142 error:
1143         FW_LOGE("error: %d", errorType);
1144         return ;
1145
1146 }
1147
1148 SA_ErrorType receive_header(Session *session, SyncHdr *header)
1149 {
1150         FW_LOGV("start");
1151
1152         SA_ErrorType errorType = SA_INTERNAL_OK;
1153         Location *pLocation = NULL;
1154
1155         if (!session) {
1156                 errorType = SA_INTERNAL_NOT_DEFINED;
1157                 goto error;
1158         }
1159
1160         if (!header) {
1161                 errorType = SA_INTERNAL_NOT_DEFINED;
1162                 goto error;
1163         }
1164         if (session->sessionID && header->sessionID) {
1165                 if (strcmp(session->sessionID, header->sessionID) != 0) {
1166                         errorType = SA_INTERNAL_SERVER_ERROR;
1167                         goto error;
1168                 }
1169         }
1170
1171         session->lastRecievedMsgID = header->messageID;
1172
1173         if (0 < header->maxmsgsize)
1174                 session->targetMaxMsgSize = header->maxmsgsize;
1175         else
1176                 session->targetMaxMsgSize = OMA_DS_HTTP_DEFAULT_SERVER_MAX_MSG_SIZE;
1177
1178         if (0 < header->maxobjsize)
1179                 session->targetMaxObjSize = header->maxobjsize;
1180
1181         if (header->responseURI) {
1182                 if (!session->orgTarget) {
1183                         session->orgTarget = session->target;
1184                         session->target = NULL;
1185                 }
1186
1187                 if (session->target)
1188                         free_location(session->target);
1189
1190                 errorType = create_location(header->responseURI, get_location_locname(session->orgTarget), &pLocation);
1191                 if (errorType != SA_INTERNAL_OK)
1192                         goto error;
1193                 session->target = pLocation;
1194
1195                 if (!session->target) {
1196                         errorType = SA_INTERNAL_NO_MEMORY;
1197                         goto error;
1198                 }
1199         }
1200
1201         Status *temp = NULL;
1202         OMA_StatusType statusData = ERROR_UNKNOWN;
1203         if (header->cred) {
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;
1209                 } else
1210                         goto error;
1211         } else{
1212                 statusData = NO_ERROR;
1213         }
1214
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)
1218                 goto error;
1219
1220         session->status = g_list_append(session->status, temp);
1221
1222         FW_LOGV("end");
1223
1224         return errorType;
1225
1226 error:
1227         FW_LOGE("error: %d", errorType);
1228         return errorType;
1229 }
1230
1231 SA_ErrorType receive_statuses(Session *session, GList *receiveStatus, GList **returnStatus)
1232 {
1233         FW_LOGV("start");
1234
1235         SA_ErrorType errorType = SA_INTERNAL_OK;
1236
1237         GList *statusItem = receiveStatus;
1238         Status *status = NULL;
1239         while (statusItem) {
1240                 status = statusItem->data;
1241
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);
1247
1248                         if (statusType == AUTH_ACCEPTED) {
1249                                 /*212
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;
1254                                         if (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);
1257
1258                                                 char *value;
1259                                                 daci_config config;
1260                                                 config.config_id = session->accountId;
1261
1262                                                 if (chal->format == FORMAT_TYPE_BASE64)
1263                                                         value = chal->nonce_b64;
1264                                                 else
1265                                                         value = g_base64_encode((const unsigned char *)chal->nonce_plain, chal->nonce_length);
1266
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");
1271                                                         goto error;
1272                                                 }
1273                                         }
1274                                 } else if (session->cred->type == AUTH_TYPE_BASIC) {
1275                                         /*do not need cred anymore
1276                                         but we just send it again*/
1277                                 }
1278                         } else if (statusType == NO_ERROR) {
1279                                 /*200
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*/
1284                                         if (status->chal) {
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);
1288                                         }
1289                                 }
1290                         } else if (statusType == ERROR_AUTH_REQUIRED || statusType == ERROR_AUTH_REJECTED) {
1291                                 if (status->chal)
1292                                         session->chal = dup_chal(status->chal);
1293                                 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
1294                                 goto error;
1295                         } else if (statusType == ERROR_SERVER_FAILURE) {
1296                                 errorType = SA_INTERNAL_SERVER_FAILURE;
1297                                 goto error;
1298                         } else if (statusType == IN_PROGRESS) {
1299                                 /*busy signaling*/
1300                                 errorType = SA_INTERNAL_BUSY_SIGNALING;
1301                                 goto error;
1302                         }
1303                 } else{
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);
1321                         }
1322
1323                         if (errorType != SA_INTERNAL_OK)
1324                                 goto error;
1325                 }
1326                 statusItem = g_list_next(statusItem);
1327         }
1328
1329         FW_LOGV("end");
1330
1331         return errorType;
1332
1333 error:
1334         FW_LOGE(" error, Error Type %d", errorType);
1335         return errorType;
1336 }
1337
1338 SA_ErrorType receive_commands(Session *session, GList *receiveCommand, bool autoConfig, GList **returnDatastore)
1339 {
1340         FW_LOGV("start");
1341
1342         SA_ErrorType errorType = SA_INTERNAL_OK;
1343         int item_luid_count = 0;
1344         int index = 0;
1345         int i;
1346         char **luid_str_list = NULL;
1347
1348         GList *iter = NULL;
1349         Command *command = NULL;
1350         for (iter = receiveCommand; iter != NULL; iter = g_list_next(iter)) {
1351                 command = iter->data;
1352
1353                 if (command->type == COMMAND_TYPE_ADD)
1354                         item_luid_count += g_list_length(command->private.change.items);
1355         }
1356
1357         FW_LOGV("item_luid_count = %d", item_luid_count);
1358
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;
1364                         goto error;
1365                 }
1366         }
1367
1368         ChangedDatastore *changedDatastore = NULL;
1369         for (iter = receiveCommand; iter != NULL; iter = g_list_next(iter)) {
1370                 command = iter->data;
1371
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*/
1378                                 break;
1379                         case COMMAND_TYPE_ALERT:
1380                                 errorType = __receive_alert_command(session, command, returnDatastore);
1381                                 break;
1382                         case COMMAND_TYPE_PUT:
1383                                 errorType = __receive_put_command(session, command);
1384                                 break;
1385                         case COMMAND_TYPE_GET:
1386                                         errorType = __receive_get_command(session, command);
1387                                 break;
1388                         case COMMAND_TYPE_RESULTS:
1389                                 errorType = __receive_results_command(session, command);
1390                                 break;
1391                         case COMMAND_TYPE_SYNC_START:
1392                                 errorType = __receive_sync_command(session, command, &changedDatastore);
1393                                 break;
1394                         case COMMAND_TYPE_SYNC_END:
1395                                 if (changedDatastore) {
1396                                         *returnDatastore = g_list_append(*returnDatastore, changedDatastore);
1397                                         changedDatastore = NULL;
1398                                 }
1399                                 break;
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);
1404                                 break;
1405                         }
1406
1407                         if (errorType != SA_INTERNAL_OK)
1408                                 goto error;
1409                 }
1410         }
1411
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]);
1416
1417                 free(luid_str_list);
1418         }
1419
1420         FW_LOGV("end");
1421
1422         return errorType;
1423
1424 error:
1425
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]);
1430
1431                 free(luid_str_list);
1432         }
1433
1434         FW_LOGE("error: %d", errorType);
1435         return errorType;
1436 }
1437
1438 void reset_cmdID_session(Session *session)
1439 {
1440         if (session)
1441                 session->cmdID = 1;
1442 }