Tizen 2.0 Release
[pkgs/o/oma-ds-service.git] / src / agent / service-adapter / sa_session.c
1 /*
2  * oma-ds-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /**
19  *   @SA_Session.c
20  *   @version                                                                   0.1
21  *   @brief                                                                             This file is the source file of implementation of functions for Session structure which is used in Service Adapter and processing receive command & status
22  */
23
24 #include <sync_agent.h>
25
26 #include "common/common_util.h"
27 #include "service-adapter/sa_session.h"
28 #include "service-adapter/sa_session_internal.h"
29 #include "service-adapter/sa_elements.h"
30 #include "service-adapter/sa_elements_internal.h"
31 #include "service-adapter/sa_command.h"
32 #include "service-adapter/sa_command_internal.h"
33 #include "service-adapter/sa_devinf.h"
34
35 #ifndef OMADS_AGENT_LOG
36 #undef LOG_TAG
37 #define LOG_TAG "OMA_DS_SA"
38 #endif
39
40 static sa_error_type_e _receive_alert_status(session_s * session, status_s * status);
41 static sa_error_type_e _receive_put_status(session_s * session, status_s * status);
42 static sa_error_type_e _receive_get_status(session_s * session, status_s * status);
43 static sa_error_type_e _receive_results_status(session_s * session, status_s * status);
44 static sa_error_type_e _receive_sync_status(session_s * session, status_s * status);
45 static sa_error_type_e _receive_changes_status(session_s * session, status_s * status, GList ** return_status);
46 static sa_error_type_e _receive_map_status(session_s * session, status_s * status);
47
48 static sa_error_type_e _receive_alert_command(session_s * session, command_s * command, GList ** return_datastore);
49 static sa_error_type_e _receive_put_command(session_s * session, command_s * command);
50 static sa_error_type_e _receive_get_command(session_s * session, command_s * command);
51 static sa_error_type_e _receive_results_command(session_s * session, command_s * command);
52 static sa_error_type_e _receive_sync_command(session_s * session, command_s * command, changed_datastore_s ** changed_datastore);
53 static sa_error_type_e _receive_changes_command(session_s * session, command_s * command, char **luid_str_list, int *index, changed_datastore_s ** changed_datastore);
54
55 static void __free_pending_status(command_status_s * command_status);
56 static sa_error_type_e __add_mapping(session_s * session, char *guid, char *luid, int datastore_id);
57
58 static sa_error_type_e _receive_alert_status(session_s * session, status_s * status)
59 {
60         _INNER_FUNC_ENTER;
61
62         sa_error_type_e errorType = SA_INTERNAL_OK;
63
64         unsigned int code = get_status_code(status);
65         _DEBUG_TRACE("code = %d", code);
66
67         if (code >= 400 && code != ERROR_REQUIRE_REFRESH) {
68                 /*401   unauthorized
69                    407  Authentication required
70                    405  command not allowed
71                    406  optional feature not supported
72                    500  command failed
73                    412  Incomplete command
74                    415 unsupported media type or format
75                    404 not found ->it have to be considered
76                    TODO error handling it's error~!!!!! */
77
78                 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
79                         errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
80                 else if (code == ERROR_COMMAND_NOT_ALLOWED || code == ERROR_UNSUPPORTED_FEATURE || code == ERROR_GENERIC)
81                         errorType = SA_INTERNAL_SERVER_ERROR;
82                 else if (code == ERROR_NOT_FOUND) {
83                         /*do not need to return errorType when code is ERROR_NOT_FOUND */
84
85                 }
86         }
87
88         /* delete mapping when receive 508 status for alert command */
89         if (code == ERROR_REQUIRE_REFRESH) {
90                 sync_agent_da_return_e ret = SYNC_AGENT_DA_ERRORS;
91
92                 sync_agent_da_delete_mapping_query_s query;
93                 query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_ACCOUNT_ID;
94                 query.account_id = session->account_id;
95
96                 ret = sync_agent_delete_mapping(&query);
97                 if (ret != SYNC_AGENT_DA_SUCCESS) {
98                         _DEBUG_ERROR("failed in sync_agent_delete_mapping !!");
99                 }
100         }
101
102         /* TODO off resume flag if status is not 200 */
103         if (session->pkg_status == SYNCML_SUSPEND) {
104                 if (code != 200) {
105                         errorType = SA_INTERNAL_SUSPEND_FAIL;
106                 }
107         }
108
109         _INNER_FUNC_ENTER;
110         return errorType;
111 }
112
113 static sa_error_type_e _receive_put_status(session_s * session, status_s * status)
114 {
115         _INNER_FUNC_ENTER;
116
117         sa_error_type_e errorType = SA_INTERNAL_OK;
118
119         unsigned int code = get_status_code(status);
120         _DEBUG_TRACE("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         _INNER_FUNC_ENTER;
141         return errorType;
142 }
143
144 static sa_error_type_e _receive_get_status(session_s * session, status_s * status)
145 {
146         _INNER_FUNC_ENTER;
147
148         sa_error_type_e errorType = SA_INTERNAL_OK;
149
150         unsigned int code = get_status_code(status);
151         _DEBUG_TRACE("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         _INNER_FUNC_ENTER;
172         return errorType;
173 }
174
175 static sa_error_type_e _receive_results_status(session_s * session, status_s * status)
176 {
177         _INNER_FUNC_ENTER;
178
179         sa_error_type_e errorType = SA_INTERNAL_OK;
180
181         unsigned int code = get_status_code(status);
182         _DEBUG_TRACE("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         _INNER_FUNC_ENTER;
203         return errorType;
204 }
205
206 static sa_error_type_e _receive_sync_status(session_s * session, status_s * status)
207 {
208         _INNER_FUNC_ENTER;
209
210         sa_error_type_e errorType = SA_INTERNAL_OK;
211
212         unsigned int code = get_status_code(status);
213         _DEBUG_TRACE("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         _INNER_FUNC_ENTER;
235         return errorType;
236 }
237
238 static sa_error_type_e _receive_changes_status(session_s * session, status_s * status, GList ** return_status)
239 {
240         _INNER_FUNC_ENTER;
241
242         _DEBUG_TRACE("cmdID = %d", status->cmd_id);
243         _DEBUG_TRACE("msgRef = %d", status->msg_ref);
244         _DEBUG_TRACE("cmdRef = %d", status->cmd_ref);
245         _DEBUG_TRACE("type = %d", status->type);
246         _DEBUG_TRACE("data = %s", status->data);
247
248         unsigned int code = get_status_code(status);
249         _DEBUG_TRACE("code = %d", code);
250
251         sa_error_type_e errorType = SA_INTERNAL_OK;
252
253         if (session->large_obj != NULL) {
254                 /*LargeObj status it does not need to pass engine */
255                 command_status_s *largeObj = session->large_obj;
256                 if (largeObj->cmd_id == status->cmd_ref && largeObj->msg_id == status->msg_ref) {
257
258                         if (code == CHUNK_ACCEPTED) {
259                                 __free_pending_status(largeObj);
260                                 session->large_obj = 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->source_ref != NULL) {
273                 applied_status_s *appliedStatus = create_applied_status(get_location_loc_uri(status->source_ref),
274                                                                         convert_change_type_command_type(status->type), code);
275                 if (appliedStatus == NULL) {
276                         _DEBUG_ERROR("failed in create_appliedstatus");
277                         return SA_INTERNAL_NO_MEMORY;
278                 }
279                 *return_status = g_list_append(*return_status, appliedStatus);
280         }
281
282         _INNER_FUNC_ENTER;
283         return errorType;
284 }
285
286 static sa_error_type_e _receive_map_status(session_s * session, status_s * status)
287 {
288         _INNER_FUNC_ENTER;
289
290         sa_error_type_e errorType = SA_INTERNAL_OK;
291         sync_agent_da_return_e da_err;
292
293         GList *iter = NULL;
294         command_s *pCommand = NULL;
295         unsigned int code = 0;
296         for (iter = session->map_command; iter != NULL; iter = g_list_next(iter)) {
297                 pCommand = iter->data;
298
299                 if (pCommand->msg_id == status->msg_ref && pCommand->cmd_id == status->cmd_ref) {
300                         code = get_status_code(status);
301                         _DEBUG_TRACE("code = %d", code);
302
303                         if (code == 200) {
304                                 GList *itemIter = NULL;
305                                 item_s *item = NULL;
306                                 for (itemIter = pCommand->private.map.items; itemIter != NULL; itemIter = g_list_next(itemIter)) {
307                                         item = itemIter->data;
308                                         _DEBUG_TRACE(" LUID  = %s has been removed\n", get_location_loc_uri(item->source));
309
310                                         sync_agent_da_delete_mapping_query_s query;
311                                         query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_LUID;
312                                         query.account_id = session->account_id;
313                                         query.luid = get_location_loc_uri(item->source);
314
315                                         da_err = sync_agent_delete_mapping(&query);
316                                         if (da_err != SYNC_AGENT_DA_SUCCESS) {
317                                                 errorType = SA_INTERNAL_DA_ERROR;
318                                                 _DEBUG_ERROR("failed in sync_agent_delete_mapping !!");
319                                                 return errorType;
320                                         }
321                                 }
322                                 session->map_command = g_list_remove(session->map_command, pCommand);
323                                 free_command(pCommand);
324                                 break;
325                         } else if (code >= 400) {
326                                 /*401 unauthorized
327                                    407 authentication required
328                                    420 device full
329                                    510 data store failure
330                                    500 command failed */
331
332                                 if (code >= 500) {
333                                         /*map command has failed so delete failed map command from session->mapCpmmand */
334                                         GList *itemIter = NULL;
335                                         item_s *item = NULL;
336                                         for (itemIter = pCommand->private.map.items; itemIter != NULL; itemIter = g_list_next(itemIter)) {
337                                                 item = itemIter->data;
338                                                 _DEBUG_TRACE("LUID  = %s has been removed\n", get_location_loc_uri(item->source));
339
340                                                 sync_agent_da_delete_mapping_query_s query;
341                                                 query.option = SYNC_AGENT_DA_DELETE_MAPPING_OPTION_LUID;
342                                                 query.account_id = session->account_id;
343                                                 query.luid = get_location_loc_uri(item->source);
344
345                                                 da_err = sync_agent_delete_mapping(&query);
346                                                 if (da_err != SYNC_AGENT_DA_SUCCESS) {
347                                                         errorType = SA_INTERNAL_DA_ERROR;
348                                                         _DEBUG_ERROR("failed in sync_agent_delete_mapping !!");
349                                                         return errorType;
350                                                 }
351                                         }
352                                         session->map_command = g_list_remove(session->map_command, pCommand);
353                                         free_command(pCommand);
354                                         break;
355                                 }
356                                 if (code == ERROR_AUTH_REJECTED || code == ERROR_AUTH_REQUIRED)
357                                         errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
358                                 else if (code == ERROR_NOT_FOUND)
359                                         errorType = SA_INTERNAL_NOT_FOUND;
360                                 /* for prevent */
361 //                              else if (code == ERROR_GENERIC)
362 //                                      errorType = SA_INTERNAL_SERVER_ERROR;
363                                 else
364                                         errorType = SA_INTERNAL_ERROR;
365                         }
366                 }
367         }
368
369         _INNER_FUNC_ENTER;
370         return errorType;
371 }
372
373 static sa_error_type_e _receive_alert_command(session_s * session, command_s * command, GList ** return_datastore)
374 {
375         _INNER_FUNC_ENTER;
376
377         sa_error_type_e errorType = SA_INTERNAL_OK;
378         status_s *temp = NULL;
379
380         if (command->source == NULL) {
381                 errorType = SA_INTERNAL_NOT_DEFINED;
382                 goto error;
383         }
384
385         if (command->target == NULL) {
386                 errorType = SA_INTERNAL_NOT_DEFINED;
387                 goto error;
388         }
389         /*401   unauthorized
390            407  Authentication required
391            405  command not allowed
392            406  optional feature not supported
393            500  command failed
394            412  Incomplete command
395            415 unsupported media type or format */
396
397 //      if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source)  == 0 ||
398 //                      strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source)  == 0 ||
399 //                      strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source)  == 0 ||
400 //                      strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source)  == 0) {
401 //
402 //              DatastoreInfo *datastore = create_datastoreinfo(get_location_locuri(command->target), get_location_locuri(command->source));
403 //              if (datastore == NULL) {
404 //                      errorType = SA_INTERNAL_NO_MEMORY;
405 //                      goto error;
406 //              }
407 //
408 //              if (command->private.alert.anchor != NULL){
409 //                      set_datastoreinfo_lastanchor(datastore, command->private.alert.anchor->lastAnchor);
410 //                      set_datastoreinfo_nextanchor(datastore, command->private.alert.anchor->nextAnchor);
411 //              }
412 //
413 //              set_datastoreInfo_synctype(datastore, command->private.alert.type);
414 //              set_datastoreinfo_maxobjsize(datastore, command->private.alert.maxObjSize);
415 //
416 //              *returnDatastore = g_list_append(*returnDatastore, datastore);
417 //
418 //              errorType = create_new_status(session, NO_ERROR, command,  COMMAND_TYPE_ALERT , &temp);
419 //              if (errorType != SA_INTERNAL_OK)
420 //                      goto error;
421 //
422 //              temp->item = create_item();
423 //              if (temp->item == NULL) {
424 //                      errorType = SA_INTERNAL_NO_MEMORY;
425 //                      goto error;
426 //              }
427 //              set_item_anchor(temp->item,  command->private.alert.anchor);
428 //              session->status = g_list_append(session->status, temp);
429 //
430 //      } else if (strcmp(get_location_locuri(command->target), get_location_locuri(session->source)) == 0 &&
431 //                      strcmp(get_location_locuri(command->source), get_location_locuri(session->target)) == 0) {
432 //
433 //              errorType = create_new_status(session, NO_ERROR, command,  COMMAND_TYPE_ALERT , &temp);
434 //              if (errorType != SA_INTERNAL_OK)
435 //                      goto error;
436 //
437 //              session->status = g_list_append(session->status, temp);
438 //      } else
439 //              goto not_found_error;
440
441         int content_type;
442         bool is_data_store = false;
443         for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) {
444                 if (datastoreinfo_per_content_type[content_type] != NULL)
445                         if (strcmp(get_location_loc_uri(command->target), datastoreinfo_per_content_type[content_type]->source) == 0) {
446                                 is_data_store = true;
447                                 break;
448                         }
449         }
450
451         if (is_data_store) {
452                 datastore_info_s *datastore = create_datastore_info(get_location_loc_uri(command->target), get_location_loc_uri(command->source));
453                 if (datastore == NULL) {
454                         errorType = SA_INTERNAL_NO_MEMORY;
455                         goto error;
456                 }
457
458                 if (command->private.alert.anchor != NULL) {
459                         set_datastore_info_last_anchor(datastore, command->private.alert.anchor->last_anchor);
460                         set_datastore_info_next_anchor(datastore, command->private.alert.anchor->next_anchor);
461                 }
462
463                 set_datastore_info_sync_type(datastore, command->private.alert.type);
464                 set_datastore_info_max_obj_size(datastore, command->private.alert.max_obj_size);
465
466                 *return_datastore = g_list_append(*return_datastore, datastore);
467
468                 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT, &temp);
469                 if (errorType != SA_INTERNAL_OK)
470                         goto error;
471
472                 temp->item = create_item();
473                 if (temp->item == NULL) {
474                         errorType = SA_INTERNAL_NO_MEMORY;
475                         goto error;
476                 }
477                 set_item_anchor(temp->item, command->private.alert.anchor);
478                 session->status = g_list_append(session->status, temp);
479
480         } else if (strcmp(get_location_loc_uri(command->target), get_location_loc_uri(session->source)) == 0 && strcmp(get_location_loc_uri(command->source), get_location_loc_uri(session->target)) == 0) {
481
482                 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_ALERT, &temp);
483                 if (errorType != SA_INTERNAL_OK)
484                         goto error;
485
486                 session->status = g_list_append(session->status, temp);
487         } else
488                 goto not_found_error;
489
490         _INNER_FUNC_ENTER;
491         return errorType;
492
493  not_found_error:
494         errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_ALERT, &temp);
495         if (errorType != SA_INTERNAL_OK)
496                 goto error;
497
498         session->status = g_list_append(session->status, temp);
499
500         _INNER_FUNC_ENTER;
501         return SA_INTERNAL_NOT_FOUND;
502
503  error:
504
505         if (temp != NULL)
506                 free(temp);
507
508         _INNER_FUNC_ENTER;
509         return errorType;
510 }
511
512 static sa_error_type_e _receive_put_command(session_s * session, command_s * command)
513 {
514         _INNER_FUNC_ENTER;
515
516         sa_error_type_e errorType = SA_INTERNAL_OK;
517
518         /*401 unauthorized
519            407 authentication required
520            411 size required
521            413 request entity too large
522            416 requested size too big
523            415 unspported media type or format
524            420 device full
525            500 command failed */
526
527         status_s *temp = NULL;
528
529         if (strcmp(command->private.access.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.access.type, ELEMENT_DEVINF_WBXML) == 0) {
530                 /*if it is devinf */
531                 if (command->private.access.item != NULL) {
532                         session->remote_devinf = command->private.access.item->private.devinf;
533                 }
534                 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_PUT, &temp);
535                 if (errorType != SA_INTERNAL_OK)
536                         goto error;
537         } else
538                 goto not_found_error;
539
540         session->status = g_list_append(session->status, temp);
541
542         _INNER_FUNC_ENTER;
543         return errorType;
544
545  not_found_error:
546         errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_PUT, &temp);
547         if (errorType != SA_INTERNAL_OK)
548                 goto error;
549
550         session->status = g_list_append(session->status, temp);
551
552         _INNER_FUNC_ENTER;
553         return SA_INTERNAL_NOT_FOUND;
554
555  error:
556
557         _INNER_FUNC_ENTER;
558         return errorType;
559 }
560
561 static sa_error_type_e _receive_get_command(session_s * session, command_s * command)
562 {
563         _INNER_FUNC_ENTER;
564
565         sa_error_type_e errorType = SA_INTERNAL_OK;
566         status_s *temp = NULL;
567         command_s *pCommand = NULL;
568         location_s *pLocation = NULL;
569
570         if (strcmp(command->private.access.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.access.type, ELEMENT_DEVINF_WBXML) == 0) {
571
572                 errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_GET, &temp);
573                 if (errorType != SA_INTERNAL_OK)
574                         goto error;
575
576                 session->status = g_list_append(session->status, temp);
577
578                 char *sourceDevInf = NULL;
579                 if (session->protocol_version == VERSION_10)
580                         sourceDevInf = ELEMENT_DEVINF_10;
581                 else if (session->protocol_version == VERSION_11)
582                         sourceDevInf = ELEMENT_DEVINF_11;
583                 else if (session->protocol_version == VERSION_12)
584                         sourceDevInf = ELEMENT_DEVINF_12;
585
586                 errorType = create_location(sourceDevInf, NULL, &pLocation);
587                 if (errorType != SA_INTERNAL_OK)
588                         goto error;
589
590                 errorType = create_results_command(session, pLocation, ELEMENT_DEVINF_XML, session->devinf, &pCommand);
591                 if (errorType != SA_INTERNAL_OK)
592                         goto error;
593
594                 set_results_command_msg_ref(pCommand, command->msg_id);
595                 set_results_command_cmd_ref(pCommand, command->cmd_id);
596                 set_results_command_target_ref(pCommand, command->private.access.item->target);
597
598                 session->results_command = g_list_append(session->results_command, pCommand);
599         } else
600                 goto not_found_error;
601
602         _INNER_FUNC_ENTER;
603         return errorType;
604
605  not_found_error:
606         errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_GET, &temp);
607         if (errorType != SA_INTERNAL_OK)
608                 goto error;
609
610         session->status = g_list_append(session->status, temp);
611
612         _INNER_FUNC_ENTER;
613         return SA_INTERNAL_NOT_FOUND;
614
615  error:
616
617         _INNER_FUNC_ENTER;
618         return errorType;
619 }
620
621 static sa_error_type_e _receive_results_command(session_s * session, command_s * command)
622 {
623         _INNER_FUNC_ENTER;
624
625         sa_error_type_e errorType = SA_INTERNAL_OK;
626
627         status_s *temp = NULL;
628
629         if (strcmp(command->private.results.type, ELEMENT_DEVINF_XML) == 0 || strcmp(command->private.results.type, ELEMENT_DEVINF_WBXML) == 0) {
630                 /*if it is devinf */
631                 if (command->private.results.item != NULL) {
632                         session->remote_devinf = command->private.results.item->private.devinf;
633
634                         errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_RESULTS, &temp);
635                         if (errorType != SA_INTERNAL_OK)
636                                 goto error;
637
638                         session->status = g_list_append(session->status, temp);
639                 }
640         } else
641                 goto not_found_error;
642
643         _INNER_FUNC_ENTER;
644         return errorType;
645
646  not_found_error:
647         errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_RESULTS, &temp);
648         if (errorType != SA_INTERNAL_OK)
649                 goto error;
650
651         session->status = g_list_append(session->status, temp);
652
653         _INNER_FUNC_ENTER;
654         return SA_INTERNAL_NOT_FOUND;
655
656  error:
657
658         _INNER_FUNC_ENTER;
659         return errorType;
660 }
661
662 static sa_error_type_e _receive_sync_command(session_s * session, command_s * command, changed_datastore_s ** changed_datastore)
663 {
664         _INNER_FUNC_ENTER;
665
666         sa_error_type_e errorType = SA_INTERNAL_OK;
667         status_s *temp = NULL;
668
669         retvm_if(command == NULL, SA_INTERNAL_NOT_DEFINED, "command is NULL");
670
671         retvm_if(command->source == NULL, SA_INTERNAL_NOT_DEFINED, "command->source is NULL");
672         retvm_if(command->target == NULL, SA_INTERNAL_NOT_DEFINED, "command->target is NULL");
673
674         /*TODO
675            need to check that if target has not exist in client
676            it's a error(return status)
677            and return Datastore index
678
679            401 unauthorized
680            407 authentication required
681            403 forbidden
682            404 not founc
683            405 command not allowed
684            508 refresh required
685            500 command failed
686
687            TODO compare with alert command(?) */
688
689 //      if (strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CONTACT]->source)  != 0 &&
690 //                      strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALENDAR]->source)  != 0 &&
691 //                      strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_MEMO]->source)  != 0 &&
692 //                      strcmp(get_location_locuri(command->target), datastoreinfo_per_content_type[TYPE_CALLLOG]->source)  != 0)
693 //              goto not_found_error;
694 //
695 //      Status *temp = NULL;
696 //      errorType = create_new_status(session, NO_ERROR, command,  COMMAND_TYPE_SYNC_START , &temp);
697 //      if (errorType != SA_INTERNAL_OK)
698 //              goto error;
699 //
700 //      session->status = g_list_append(session->status, temp);
701 //
702 //      _DEBUG_TRACE("hasNumChanged = %d",command->private.sync.hasNumChanged);
703 //      _DEBUG_TRACE("numberOfChanges = %d",command->private.sync.numChanged);
704 //
705 //      /*for return to engine*/
706 //      ChangedDatastore *pChangedDatastore = create_changeddatastore(get_location_locuri(command->source),
707 //                                                                                                                                      get_location_locuri(command->target), command->private.sync.hasNumChanged,
708 //                                                                                                                                      command->private.sync.hasNumChanged ? command->private.sync.numChanged : 0);
709 //      if (pChangedDatastore == NULL) {
710 //              errorType = SA_INTERNAL_NO_MEMORY;
711 //              goto error;
712 //      } else
713 //              *changedDatastore = pChangedDatastore;
714
715         int content_type;
716         bool exist = false;
717         for (content_type = 0; content_type < TYPE_SERVICE_COUNT; content_type++) {
718                 if (datastoreinfo_per_content_type[content_type] != NULL)
719                         if (strcmp(get_location_loc_uri(command->target), datastoreinfo_per_content_type[content_type]->source) == 0) {
720                                 exist = true;
721                                 break;
722                         }
723         }
724
725         if (!exist)
726                 goto not_found_error;
727
728         errorType = create_new_status(session, NO_ERROR, command, COMMAND_TYPE_SYNC_START, &temp);
729         if (errorType != SA_INTERNAL_OK)
730                 goto error;
731
732         session->status = g_list_append(session->status, temp);
733
734         _DEBUG_TRACE("hasNumChanged = %d", command->private.sync.has_num_changed);
735         _DEBUG_TRACE("numberOfChanges = %d", command->private.sync.num_changed);
736
737         /*for return to engine */
738         changed_datastore_s *pChangedDatastore = create_changed_datastore(get_location_loc_uri(command->source),
739                                                                           get_location_loc_uri(command->target), command->private.sync.has_num_changed,
740                                                                           command->private.sync.has_num_changed ? command->private.sync.num_changed : 0);
741         if (pChangedDatastore == NULL) {
742                 errorType = SA_INTERNAL_NO_MEMORY;
743                 goto error;
744         } else
745                 *changed_datastore = pChangedDatastore;
746
747         _INNER_FUNC_ENTER;
748         return errorType;
749
750  not_found_error:
751         errorType = create_new_status(session, ERROR_NOT_FOUND, command, COMMAND_TYPE_SYNC_START, &temp);
752         if (errorType != SA_INTERNAL_OK)
753                 goto error;
754
755         session->status = g_list_append(session->status, temp);
756
757         _INNER_FUNC_ENTER;
758         return SA_INTERNAL_NOT_FOUND;
759
760  error:
761
762         _INNER_FUNC_ENTER;
763         return errorType;
764 }
765
766 static sa_error_type_e _receive_changes_command(session_s * session, command_s * command, char **luid_str_list, int *index, changed_datastore_s ** changed_datastore)
767 {
768         _INNER_FUNC_ENTER;
769         _DEBUG_TRACE("start command type :  %d\n", command->private.change.type);
770
771         sa_error_type_e errorType = SA_INTERNAL_OK;
772
773         GList *iter = NULL;
774         changed_item_s *changed = NULL;
775         char *luid;
776         change_type_e changeType = command->private.change.type;
777         for (iter = command->private.change.items; iter != NULL; iter = g_list_next(iter)) {
778                 item_s *changedItem = (iter->data);
779
780                 if (changedItem->more_data) {
781                         if (session->large_obj_cmd != NULL) {
782                                 /*if there is a chunked item before...
783                                    it's not firest chunked item.... data have to be merged(check source location)
784                                    there will be another chunked item */
785
786                                 command_s *pLargeObjcmd = session->large_obj_cmd;
787                                 if (pLargeObjcmd->private.change.items != NULL) {
788                                         /*moreData item must be last item in item list */
789                                         GList *largeObjItems = session->large_obj_cmd->private.change.items;
790                                         GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1);
791                                         item_s *item = largeObjLastItem->data;
792                                         alert_type_e alertType = ALERT_UNKNOWN;
793                                         if (strcmp(get_location_loc_uri(item->source), get_location_loc_uri(changedItem->source)) == 0) {
794                                                 /*two item's source are equal
795                                                    append incomming string */
796                                                 if (item->private.data != NULL) {
797                                                         char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data);
798                                                         free(item->private.data);
799                                                         item->private.data = tmp;
800                                                 } else {
801                                                         item->private.data = strdup(changedItem->private.data);
802                                                 }
803                                                 status_s *temp = NULL;
804                                                 errorType = create_new_status_location(session, CHUNK_ACCEPTED, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
805                                                 if (errorType != SA_INTERNAL_OK) {
806                                                         _DEBUG_ERROR("failed in create_new_status_location");
807                                                         goto error;
808                                                 }
809                                                 session->status = g_list_append(session->status, temp);
810                                                 alertType = ALERT_NEXT_MESSAGE;
811                                         } else {
812                                                 /* it's a new data object or command but this command also have a moreData */
813                                                 alertType = ALERT_NO_END_OF_DATA;
814                                         }
815                                         /* create alert command */
816                                         command_s *pAlertCommand = NULL;
817                                         errorType = create_alert_command(session, alertType, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand);
818                                         if (errorType != SA_INTERNAL_OK) {
819                                                 _DEBUG_ERROR("failed in create_alert_command");
820                                                 goto error;
821                                         }
822                                         session->alert_command = g_list_append(session->alert_command, pAlertCommand);
823                                 }
824                         } else {
825                                 /*first chunked item
826                                    just buffered it. does not generate LUID, and does not pass to engine */
827                                 oma_status_type_e statusErrorType = ERROR_UNKNOWN;
828                                 if (changedItem->size == 0) {
829                                         /*size required */
830                                         statusErrorType = ERROR_SIZE_REQUIRED;
831                                 } else {
832                                         /* size is specified */
833                                         if (changedItem->size > session->source_max_obj_size) {
834                                                 /*but it is bigger than client maxObjSize */
835                                                 statusErrorType = ERROR_REQUESTED_SIZE_TOO_BIG;
836                                         } else {
837                                                 /*chunked item accepted */
838                                                 session->large_obj_cmd = command;
839                                                 increase_command_ref_count(command);
840
841                                                 statusErrorType = CHUNK_ACCEPTED;
842
843                                                 /* create alert command */
844                                                 command_s *pAlertCommand = NULL;
845                                                 errorType = create_alert_command(session, ALERT_NEXT_MESSAGE, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand);
846                                                 if (errorType != SA_INTERNAL_OK) {
847                                                         _DEBUG_ERROR("failed in create_alert_command");
848                                                         goto error;
849                                                 }
850                                                 session->alert_command = g_list_append(session->alert_command, pAlertCommand);
851                                         }
852
853                                         status_s *temp = NULL;
854                                         errorType = create_new_status_location(session, statusErrorType, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
855                                         if (errorType != SA_INTERNAL_OK) {
856                                                 _DEBUG_ERROR("failed in create_new_status_location");
857                                                 goto error;
858                                         }
859                                         session->status = g_list_append(session->status, temp);
860                                 }
861                         }
862                 } else {
863                         if (session->large_obj_cmd != NULL) {
864
865                                 /*if there is a chunked item before...
866                                    it's not firest chunked item.... data have to be merged(check source location)
867                                    there will be no more chunked item. this command have to be pass to engine */
868
869                                 command_s *pLargeObjcmd = session->large_obj_cmd;
870                                 if (pLargeObjcmd->private.change.items != NULL) {
871                                         /*moreData item must be last item in item list */
872                                         GList *largeObjItems = session->large_obj_cmd->private.change.items;
873                                         GList *largeObjLastItem = g_list_nth(largeObjItems, g_list_length(largeObjItems) - 1);
874                                         item_s *item = largeObjLastItem->data;
875
876                                         if (strcmp(get_location_loc_uri(item->source), get_location_loc_uri(changedItem->source)) == 0) {
877                                                 /* two item's source are equal
878                                                    append incomming string */
879                                                 if (item->private.data != NULL) {
880                                                         char *tmp = g_strdup_printf("%s%s", item->private.data, changedItem->private.data);
881                                                         free(item->private.data);
882                                                         item->private.data = tmp;
883                                                 } else {
884                                                         item->private.data = strdup(changedItem->private.data);
885
886                                                         if (item->private.data == NULL) {
887                                                                 _DEBUG_ERROR("item->private.data is null !!");
888                                                                 goto error;
889                                                         }
890                                                 }
891
892                                                 if (item->size == strlen(item->private.data)) {
893                                                         /*delete pointing from pLargeObjCmd */
894                                                         largeObjLastItem->data = NULL;
895                                                         _DEBUG_TRACE("delete pointing from pLargeObjCmd");
896                                                         /*free Item from incomming Cmd */
897                                                         free_item(changedItem);
898                                                         _DEBUG_TRACE("free Item from incomming Cmd");
899                                                         /*pointing to Merged item in incomming Cmd */
900                                                         iter->data = item;
901                                                         changedItem = item;
902                                                         _DEBUG_TRACE("pointing to Merged item in incomming Cmd");
903
904                                                         free_command(session->large_obj_cmd);
905                                                         session->large_obj_cmd = NULL;
906                                                 } else {
907                                                         status_s *temp = NULL;
908                                                         errorType = create_new_status_location(session, ERROR_SIZE_MISMATCH, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
909                                                         if (errorType != SA_INTERNAL_OK) {
910                                                                 _DEBUG_ERROR("failed in create_new_status_location");
911                                                                 goto error;
912                                                         }
913                                                         session->status = g_list_append(session->status, temp);
914                                                 }
915                                         } else {
916                                                 /* it's a new data object or command send 223
917                                                    create alert command */
918                                                 command_s *pAlertCommand = NULL;
919                                                 errorType = create_alert_command(session, ALERT_NO_END_OF_DATA, dup_location(session->source), dup_location(session->target), NULL, NULL, NULL, &pAlertCommand);
920                                                 if (errorType != SA_INTERNAL_OK) {
921                                                         _DEBUG_ERROR("failed in create_alert_command");
922                                                         goto error;
923                                                 }
924                                                 session->alert_command = g_list_append(session->alert_command, pAlertCommand);
925                                         }
926                                 }
927                         }
928                         if (changeType == CHANGE_ADD) {
929                                 int datastore_id = 0;
930                                 if (strcmp(changedItem->content_type, ELEMENT_TEXT_VCARD) == 0 || strcmp(changedItem->content_type, ELEMENT_TEXT_VCARD_30) == 0)
931                                         datastore_id = TYPE_CONTACT;
932                                 else if (strcmp(changedItem->content_type, ELEMENT_TEXT_VCAL) == 0)
933                                         datastore_id = TYPE_CALENDAR;
934                                 else if (strcmp(changedItem->content_type, ELEMENT_TEXT_PLAIN) == 0)
935                                         datastore_id = TYPE_MEMO;
936
937                                 luid = luid_str_list[(*index)++];
938                                 if (luid == NULL) {
939                                         _DEBUG_ERROR("luid is null");
940                                         errorType = SA_INTERNAL_ERROR;
941                                         goto error;
942                                 }
943
944                                 _DEBUG_TRACE("index = %d", *index);
945                                 _DEBUG_TRACE("luid = %s", luid);
946
947                                 errorType = __add_mapping(session, get_location_loc_uri(changedItem->source), luid, datastore_id);
948                                 if (errorType != SA_INTERNAL_OK) {
949                                         _DEBUG_ERROR("failed in __add_mapping");
950                                         goto error;
951                                 }
952                         } else {
953                                 luid = get_location_loc_uri(changedItem->target);
954                                 if (luid == NULL) {
955                                         _DEBUG_ERROR("luid is null");
956                                         errorType = SA_INTERNAL_ERROR;
957                                         goto error;
958                                 }
959                         }
960
961                         changed = create_changed_item(changeType, luid);
962                         if (changed == NULL) {
963                                 _DEBUG_ERROR("changed is null");
964                                 errorType = SA_INTERNAL_NO_MEMORY;
965                                 goto error;
966                         }
967
968                         if (changeType != CHANGE_DELETE) {
969                                 set_changed_item_content_type(changed, changedItem->content_type);
970                                 set_changed_item_data(changed, changedItem->private.data);
971                         }
972
973                         status_s *temp = NULL;
974                         errorType = create_new_status_location(session, ERROR_UNKNOWN, command, changedItem->source, changedItem->target, convert_command_type_change_type(changeType), &temp);
975                         if (errorType != SA_INTERNAL_OK) {
976                                 _DEBUG_ERROR("failed in create_new_status_location");
977                                 goto error;
978                         }
979                         session->temp_status = g_list_append(session->temp_status, temp);
980
981                         (*changed_datastore)->change_item = g_list_append((*changed_datastore)->change_item, changed);
982                         changed = NULL;
983                 }
984         }
985
986  error:
987
988         if (changed != NULL)
989                 free_changed_item(changed);
990
991         _INNER_FUNC_ENTER;
992         return errorType;
993 }
994
995 static void __free_pending_status(command_status_s * command_status)
996 {
997         _INNER_FUNC_ENTER;
998
999         retm_if(command_status == NULL, "pendingStatus is NULL");
1000
1001         free(command_status);
1002         command_status = NULL;
1003
1004         _INNER_FUNC_EXIT;
1005         return;
1006 }
1007
1008 static sa_error_type_e __add_mapping(session_s * session, char *guid, char *luid, int datastore_id)
1009 {
1010         _INNER_FUNC_ENTER;
1011
1012         sa_error_type_e errorType = SA_INTERNAL_OK;
1013         sync_agent_da_return_e da_err = SYNC_AGENT_DA_ERRORS;
1014
1015         sync_agent_da_mapping_s *mapping = NULL;
1016         da_err = sync_agent_create_mapping(&mapping);
1017         if (da_err != SYNC_AGENT_DA_SUCCESS) {
1018                 _DEBUG_ERROR("failed in sync_agent_create_mapping !!");
1019                 goto error;
1020         }
1021
1022         mapping->account_id = session->account_id;
1023         mapping->data_store_id = datastore_id;
1024         mapping->luid = strdup(luid);
1025         mapping->guid = strdup(guid);
1026         mapping->access_name = strdup("SA");
1027
1028         _DEBUG_VERBOSE("account_id = %d", mapping->account_id);
1029         _DEBUG_VERBOSE("data_store_id = %d", mapping->data_store_id);
1030         _DEBUG_VERBOSE("luid = %s", mapping->luid);
1031         _DEBUG_VERBOSE("guid = %s", mapping->guid);
1032         _DEBUG_VERBOSE("access_name = %s", mapping->access_name);
1033
1034         da_err = sync_agent_add_mapping(mapping);
1035         if (da_err != SYNC_AGENT_DA_SUCCESS) {
1036                 _DEBUG_ERROR("failed in sync_agent_add_mapping = %d", da_err);
1037                 sync_agent_free_mapping(mapping);
1038                 errorType = SA_INTERNAL_DA_ERROR;
1039                 goto error;
1040         }
1041
1042         sync_agent_free_mapping(mapping);
1043
1044  error:
1045
1046         _INNER_FUNC_EXIT;
1047         return errorType;
1048 }
1049
1050 sa_error_type_e create_session(protocol_version_e protocol_version, protocol_type_e protocol_type, int account_id, char *sess_id, location_s * source_location, location_s * target_location, session_s ** session)
1051 {
1052         _EXTERN_FUNC_ENTER;
1053
1054         sa_error_type_e errorType = SA_INTERNAL_OK;
1055
1056         *session = (session_s *) calloc(1, sizeof(session_s));
1057         if (*session == NULL) {
1058                 errorType = SA_INTERNAL_NO_MEMORY;
1059                 goto error;
1060         }
1061
1062         if (sess_id != NULL)
1063                 (*session)->session_id = strdup(sess_id);
1064
1065         if (source_location != NULL)
1066                 (*session)->source = source_location;
1067
1068         if (target_location != NULL)
1069                 (*session)->target = target_location;
1070
1071         (*session)->protocol_type = protocol_type;
1072         (*session)->protocol_version = protocol_version;
1073         (*session)->account_id = account_id;
1074
1075         (*session)->msg_id = 0;
1076         (*session)->cmd_id = 1;
1077
1078         (*session)->source_max_msg_size = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_MSG_SIZE;
1079         (*session)->source_max_obj_size = OMA_DS_HTTP_DEFAULT_CLIENT_MAX_OBJ_SIZE;
1080
1081         (*session)->target_max_msg_size = 0;
1082         (*session)->target_max_obj_size = 0;
1083
1084         (*session)->naci_session_id = 0;
1085         (*session)->has_opend = 0;
1086
1087  error:
1088
1089         _EXTERN_FUNC_EXIT;
1090         return errorType;
1091 }
1092
1093 void free_session(session_s * session)
1094 {
1095         _EXTERN_FUNC_ENTER;
1096
1097         retm_if(session == NULL, "session is NULL");
1098
1099         if (session->session_id != NULL) {
1100                 free(session->session_id);
1101                 session->session_id = NULL;
1102         }
1103
1104         if (session->jsession_id != NULL) {
1105                 free(session->jsession_id);
1106                 session->jsession_id = NULL;
1107         }
1108
1109         _DEBUG_INFO("session->status");
1110         free_statuses(session->status);
1111         session->status = NULL;
1112
1113         _DEBUG_INFO("session->tempStatus");
1114         free_statuses(session->temp_status);
1115         session->temp_status = NULL;
1116
1117         _DEBUG_INFO("session->suspendStatus");
1118         free_statuses(session->suspend_status);
1119         session->suspend_status = NULL;
1120
1121         if (session->target != NULL) {
1122                 free_location(session->target);
1123                 session->target = NULL;
1124         }
1125
1126         if (session->source != NULL) {
1127                 free_location(session->source);
1128                 session->source = NULL;
1129         }
1130
1131         if (session->org_target != NULL) {
1132                 free_location(session->org_target);
1133                 session->org_target = NULL;
1134         }
1135
1136         if (session->cred != NULL) {
1137                 free_cred(session->cred);
1138                 session->cred = NULL;
1139         }
1140
1141         if (session->chal != NULL) {
1142                 free_chal(session->chal);
1143                 session->chal = NULL;
1144         }
1145
1146         if (session->devinf != NULL) {
1147                 free_devinf(session->devinf);
1148                 session->devinf = NULL;
1149         }
1150
1151         if (session->remote_devinf != NULL) {
1152                 free_devinf(session->remote_devinf);
1153                 session->remote_devinf = NULL;
1154         }
1155
1156         if (session->large_obj_cmd != NULL) {
1157                 free_command(session->large_obj_cmd);
1158                 session->large_obj_cmd = NULL;
1159         }
1160
1161         free_commands(session->map_command);
1162         session->map_command = NULL;
1163
1164         free_commands(session->alert_command);
1165         session->alert_command = NULL;
1166
1167         free_commands(session->results_command);
1168         session->results_command = NULL;
1169
1170         if (session->large_obj != NULL)
1171                 free(session->large_obj);
1172
1173         if (session != NULL)
1174                 free(session);
1175
1176         _EXTERN_FUNC_EXIT;
1177         return;
1178 }
1179
1180 sa_error_type_e create_command_status(unsigned int msg_id, unsigned int cmd_id, command_status_s ** command_status)
1181 {
1182         _EXTERN_FUNC_ENTER;
1183
1184         sa_error_type_e errorType = SA_INTERNAL_OK;
1185
1186         *command_status = (command_status_s *) calloc(1, sizeof(command_status_s));
1187         if (*command_status == NULL) {
1188                 errorType = SA_INTERNAL_NO_MEMORY;
1189                 goto error;
1190         }
1191
1192         (*command_status)->msg_id = msg_id;
1193         (*command_status)->cmd_id = cmd_id;
1194
1195  error:
1196
1197         _EXTERN_FUNC_EXIT;
1198         return errorType;
1199 }
1200
1201 void set_session_cred(session_s * session, cred_s * cred)
1202 {
1203         _EXTERN_FUNC_ENTER;
1204
1205         sa_error_type_e errorType = SA_INTERNAL_OK;
1206
1207         if (session == NULL) {
1208                 errorType = SA_INTERNAL_NOT_DEFINED;
1209                 goto error;
1210         }
1211
1212         if (cred == NULL) {
1213                 errorType = SA_INTERNAL_NOT_DEFINED;
1214                 goto error;
1215         }
1216
1217         session->cred = cred;
1218
1219  error:
1220
1221         _EXTERN_FUNC_EXIT;
1222         return;
1223
1224 }
1225
1226 void set_session_devinf(session_s * session, devinf_s * devinf)
1227 {
1228         _EXTERN_FUNC_ENTER;
1229
1230         sa_error_type_e errorType = SA_INTERNAL_OK;
1231
1232         if (session == NULL) {
1233                 errorType = SA_INTERNAL_NOT_DEFINED;
1234                 goto error;
1235         }
1236
1237         if (devinf == NULL) {
1238                 errorType = SA_INTERNAL_NOT_DEFINED;
1239                 goto error;
1240         }
1241
1242         session->devinf = devinf;
1243
1244  error:
1245
1246         _EXTERN_FUNC_EXIT;
1247         return;
1248
1249 }
1250
1251 sa_error_type_e receive_header(session_s * session, sync_hdr_s * header)
1252 {
1253         _EXTERN_FUNC_ENTER;
1254
1255         sa_error_type_e errorType = SA_INTERNAL_OK;
1256         location_s *pLocation = NULL;
1257
1258         if (session == NULL) {
1259                 _DEBUG_ERROR("session is NULL");
1260                 errorType = SA_INTERNAL_NOT_DEFINED;
1261                 goto error;
1262         }
1263
1264         if (header == NULL) {
1265                 _DEBUG_ERROR("header is NULL");
1266                 errorType = SA_INTERNAL_NOT_DEFINED;
1267                 goto error;
1268         }
1269         if (session->session_id && header->session_id) {
1270                 if (strcmp(session->session_id, header->session_id) != 0) {
1271                         errorType = SA_INTERNAL_SERVER_ERROR;
1272                         goto error;
1273                 }
1274         }
1275
1276         session->last_recieved_msg_id = header->message_id;
1277
1278         if (0 < header->max_msg_size)
1279                 session->target_max_msg_size = header->max_msg_size;
1280         else
1281                 session->target_max_msg_size = OMA_DS_HTTP_DEFAULT_SERVER_MAX_MSG_SIZE;
1282
1283         if (0 < header->max_obj_size)
1284                 session->target_max_obj_size = header->max_obj_size;
1285
1286         if (header->response_uri != NULL) {
1287                 if (session->org_target == NULL) {
1288                         session->org_target = session->target;
1289                         session->target = NULL;
1290                 }
1291
1292                 if (session->target != NULL)
1293                         free_location(session->target);
1294
1295                 errorType = create_location(header->response_uri, get_location_loc_name(session->org_target), &pLocation);
1296                 if (errorType != SA_INTERNAL_OK)
1297                         goto error;
1298                 session->target = pLocation;
1299
1300                 if (session->target == NULL) {
1301                         errorType = SA_INTERNAL_NO_MEMORY;
1302                         goto error;
1303                 }
1304         }
1305
1306         status_s *temp = NULL;
1307         oma_status_type_e statusData = ERROR_UNKNOWN;
1308         if (header->cred != NULL) {
1309                 errorType = compare_cred(header->cred, session->cred);
1310                 if (errorType == SA_INTERNAL_OK)
1311                         statusData = AUTH_ACCEPTED;
1312                 else if (errorType == SA_INTERNAL_AUTHENTICATION_ERROR) {
1313                         statusData = ERROR_AUTH_REJECTED;
1314                 } else
1315                         goto error;
1316         } else {
1317                 statusData = NO_ERROR;
1318         }
1319
1320         errorType = create_status(statusData, session->cmd_id++, session->last_recieved_msg_id, 0, header->source, header->target, COMMAND_TYPE_HEADER, &temp);
1321         if (errorType != SA_INTERNAL_OK)
1322                 goto error;
1323
1324         session->status = g_list_append(session->status, temp);
1325
1326  error:
1327
1328         _EXTERN_FUNC_EXIT;
1329         return errorType;
1330 }
1331
1332 sa_error_type_e receive_statuses(session_s * session, GList * receive_status, GList ** return_status)
1333 {
1334         _EXTERN_FUNC_ENTER;
1335
1336         sa_error_type_e errorType = SA_INTERNAL_OK;
1337
1338         GList *statusItem = receive_status;
1339         status_s *status = NULL;
1340         while (statusItem) {
1341                 status = statusItem->data;
1342
1343                 if (status->cmd_ref == 0) {
1344                         /*status of SyncHdr */
1345                         assert(status->type == COMMAND_TYPE_HEADER);
1346                         assert(status->data);
1347                         oma_status_type_e statusType = atoi(status->data);
1348
1349                         /* TODO off resume flag if status is 400(bad request) */
1350                         if (session->pkg_status == SYNCML_SUSPEND) {
1351                                 if (statusType == ERROR_BAD_REQUEST) {
1352                                         errorType = SA_INTERNAL_SUSPEND_FAIL;
1353                                         goto error;
1354                                 }
1355                         }
1356
1357                         if (statusType == AUTH_ACCEPTED) {
1358                                 /*212
1359                                    when auth type is AUTH_TYPE_BASIC does not need to send cred in syncHdr in same session
1360                                    when auth type is AUTH_TYPE_MD5 the next nonce in Chal MUST used for the digest when the next sync session is started. */
1361                                 if (session->cred->type == AUTH_TYPE_MD5) {
1362                                         chal_s *chal = status->chal;
1363                                         if (chal != NULL) {
1364                                                 /*chal in status have to be stored in config_tbl because it have to be used next sync session */
1365                                                 _DEBUG_INFO("format type :%d", chal->format);
1366
1367                                                 char *value;
1368                                                 sync_agent_da_config_s config;
1369                                                 config.config_id = session->account_id;
1370
1371                                                 if (chal->format == FORMAT_TYPE_BASE64)
1372                                                         value = chal->nonce_b64;
1373                                                 else
1374                                                         value = g_base64_encode((unsigned char *)chal->nonce_plain, chal->nonce_length);
1375
1376                                                 bool result = set_config_str(session->account_id, DEFINE_CONFIG_KEY_PROFILE_NEXT_NONCE, value, "string", "SA");
1377                                                 if (result == false) {
1378                                                         errorType = SA_INTERNAL_ERROR;
1379                                                         _DEBUG_ERROR("failed in set_Config");
1380                                                         goto error;
1381                                                 }
1382                                         }
1383                                 } else if (session->cred->type == AUTH_TYPE_BASIC) {
1384                                         /*do not need cred anymore
1385                                            but we just send it again */
1386                                 }
1387                         } else if (statusType == NO_ERROR) {
1388                                 /*200
1389                                    when auth type is AUTH_TYPE_BASIC sam credentials must be sent within the next request
1390                                    when auth type is AUTH_TYPE_MD5  The next nonce in Chal MUST used when the next request is sent */
1391                                 if (session->cred->type == AUTH_TYPE_MD5) {
1392                                         /*if auth type is AUTH_TYPE_MD5 */
1393                                         if (status->chal != NULL) {
1394                                                 /*if there is a chal in status duplicate to session
1395                                                    chal have to used when next request is sent */
1396                                                 if (session->chal != NULL) {
1397                                                         free_chal(session->chal);
1398                                                         session->chal = NULL;
1399                                                 }
1400                                                 session->chal = status->chal;
1401                                                 status->chal = NULL;
1402                                         }
1403                                 }
1404                         } else if (statusType == ERROR_AUTH_REQUIRED || statusType == ERROR_AUTH_REJECTED) {
1405                                 if (status->chal != NULL) {
1406                                         if (session->chal != NULL) {
1407                                                 free_chal(session->chal);
1408                                                 session->chal = NULL;
1409                                         }
1410                                         session->chal = status->chal;
1411                                         status->chal = NULL;
1412                                 }
1413                                 errorType = SA_INTERNAL_AUTHENTICATION_ERROR;
1414                                 goto error;
1415                         } else if (statusType == ERROR_SERVER_FAILURE) {
1416                                 errorType = SA_INTERNAL_SERVER_FAILURE;
1417                                 goto error;
1418                         } else if (statusType == IN_PROGRESS) {
1419                                 /*busy signaling */
1420                                 errorType = SA_INTERNAL_BUSY_SIGNALING;
1421                                 goto error;
1422                         }
1423                 } else {
1424                         /*status except status of SyncHdr */
1425                         if (status->type == COMMAND_TYPE_ALERT) {
1426                                 errorType = _receive_alert_status(session, status);
1427                         } else if (status->type == COMMAND_TYPE_PUT) {
1428                                 errorType = _receive_put_status(session, status);
1429                         } else if (status->type == COMMAND_TYPE_GET) {
1430                                 errorType = _receive_get_status(session, status);
1431                         } else if (status->type == COMMAND_TYPE_RESULTS) {
1432                                 errorType = _receive_results_status(session, status);
1433                         } else if (status->type == COMMAND_TYPE_SYNC_START) {
1434                                 errorType = _receive_sync_status(session, status);
1435                         } else if (status->type == COMMAND_TYPE_MAP) {
1436                                 errorType = _receive_map_status(session, status);
1437                         } else if (status->type == COMMAND_TYPE_ADD || status->type == COMMAND_TYPE_REPLACE || status->type == COMMAND_TYPE_DELETE) {
1438                                 errorType = _receive_changes_status(session, status, return_status);
1439                         }
1440
1441                         if (errorType != SA_INTERNAL_OK)
1442                                 goto error;
1443                 }
1444                 statusItem = g_list_next(statusItem);
1445         }
1446
1447  error:
1448
1449         _EXTERN_FUNC_EXIT;
1450         return errorType;
1451 }
1452
1453 sa_error_type_e receive_commands(session_s * session, GList * receive_command, bool auto_config, GList ** return_datastore)
1454 {
1455         _EXTERN_FUNC_ENTER;
1456
1457         sa_error_type_e errorType = SA_INTERNAL_OK;
1458         int item_luid_count = 0;
1459         int index = 0;
1460         int i;
1461         char **luid_str_list = NULL;
1462         changed_datastore_s *changedDatastore = NULL;
1463
1464         GList *iter = NULL;
1465         command_s *command = NULL;
1466         for (iter = receive_command; iter != NULL; iter = g_list_next(iter)) {
1467                 command = iter->data;
1468
1469                 if (command->type == COMMAND_TYPE_ADD)
1470                         item_luid_count += g_list_length(command->private.change.items);
1471         }
1472
1473         _DEBUG_INFO("item_luid_count = %d", item_luid_count);
1474
1475         if (item_luid_count > 0) {
1476                 luid_str_list = sync_agent_generate_item_luid(1, item_luid_count);
1477                 if (luid_str_list == NULL) {
1478                         _DEBUG_ERROR("failed in sync_agent_generate_item_luid");
1479                         errorType = SA_INTERNAL_ERROR;
1480                         goto error;
1481                 }
1482         }
1483
1484         for (iter = receive_command; iter != NULL; iter = g_list_next(iter)) {
1485                 command = iter->data;
1486
1487                 if (auto_config != true || (auto_config == true && command->type == COMMAND_TYPE_RESULTS)) {
1488                         switch (command->type) {
1489                         case COMMAND_TYPE_UNKNOWN:
1490                         case COMMAND_TYPE_HEADER:
1491                         case COMMAND_TYPE_MAP:
1492                                 /*never receive theses commands */
1493                                 break;
1494                         case COMMAND_TYPE_ALERT:
1495                                 errorType = _receive_alert_command(session, command, return_datastore);
1496                                 break;
1497                         case COMMAND_TYPE_PUT:
1498                                 errorType = _receive_put_command(session, command);
1499                                 break;
1500                         case COMMAND_TYPE_GET:
1501                                 errorType = _receive_get_command(session, command);
1502                                 break;
1503                         case COMMAND_TYPE_RESULTS:
1504                                 errorType = _receive_results_command(session, command);
1505                                 break;
1506                         case COMMAND_TYPE_SYNC_START:
1507                                 errorType = _receive_sync_command(session, command, &changedDatastore);
1508                                 break;
1509                         case COMMAND_TYPE_SYNC_END:
1510                                 {
1511                                         if (changedDatastore != NULL) {
1512                                                 if (changedDatastore->has_number_of_changes || g_list_length(changedDatastore->change_item) > 0) {
1513                                                         *return_datastore = g_list_append(*return_datastore, changedDatastore);
1514                                                         changedDatastore = NULL;
1515                                                 } else {
1516                                                         if (changedDatastore != NULL) {
1517                                                                 free_changed_datastore(changedDatastore);
1518                                                                 changedDatastore = NULL;
1519                                                         }
1520                                                 }
1521                                         }
1522                                 }
1523                                 break;
1524                         case COMMAND_TYPE_ADD:
1525                         case COMMAND_TYPE_REPLACE:
1526                         case COMMAND_TYPE_DELETE:
1527                                 {
1528                                         if (command->type != COMMAND_TYPE_ADD || luid_str_list != NULL) {
1529                                                 errorType = _receive_changes_command(session, command, luid_str_list, &index, &changedDatastore);
1530                                         } else {
1531                                                 _DEBUG_ERROR("luid_str_list is NULL !!");
1532                                                 errorType = SA_INTERNAL_ERROR;
1533                                                 if (changedDatastore != NULL) {
1534                                                         free_changed_datastore(changedDatastore);
1535                                                         changedDatastore = NULL;
1536                                                 }
1537                                                 goto error;
1538                                         }
1539                                 }
1540                                 break;
1541                         }
1542
1543                         if (errorType != SA_INTERNAL_OK) {
1544                                 if (changedDatastore != NULL) {
1545                                         free_changed_datastore(changedDatastore);
1546                                         changedDatastore = NULL;
1547                                 }
1548                                 goto error;
1549                         }
1550                 }
1551         }
1552
1553  error:
1554
1555         if (changedDatastore != NULL)
1556                 free_changed_datastore(changedDatastore);
1557
1558         if (luid_str_list != NULL) {
1559                 /*free luid_str_list */
1560                 for (i = 0; i < item_luid_count; i++)
1561                         free(luid_str_list[i]);
1562
1563                 free(luid_str_list);
1564         }
1565
1566         _EXTERN_FUNC_EXIT;
1567         return errorType;
1568 }
1569
1570 void reset_cmd_id_session(session_s * session)
1571 {
1572         _EXTERN_FUNC_ENTER;
1573
1574         if (session != NULL)
1575                 session->cmd_id = 1;
1576
1577         _EXTERN_FUNC_EXIT;
1578 }