Tizen 2.0 Release
[pkgs/o/oma-ds-service.git] / src / plugins / ds-public / vcard / src / plugin_interface.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 #include <stdio.h>
19 #include <contacts.h>
20 #include <glib.h>
21
22 #include <sync_agent.h>
23
24 #include "plugin_spec.h"
25 #include "in_datastore_info_vcard.h"
26 #include "encoding_util.h"
27
28 #ifndef EXPORT_API
29 #define EXPORT_API __attribute__ ((visibility("default")))
30 #endif
31
32 #ifndef OMADS_AGENT_LOG
33 #undef LOG_TAG
34 #define LOG_TAG "PLUGIN_VCARD"
35 #endif
36
37 static int _free_obj_field_info(sync_agent_plugin_field_info_s * field_list, int count);
38 static int _set_obj_field_info(sync_agent_plugin_field_info_s ** field_list, int count, vcard_field_list_s * input_list);
39 static char *_convert_key_name(int key);
40
41 static int _get_content(const char *value, void *data);
42
43 static sync_agent_da_return_e _convert_service_error_to_common_error(contacts_error_e err);
44 static char *_contacts_vcard_put_content(const char *vcard_stream, const char *content_type, const char *content_value);
45 static int _contacts_vcard_get_content(const char *vcard_stream, const char *content_type, int (*fn) (const char *content_value, void *data), void *data);
46
47 static void _contacts_struct_merge(contacts_record_h old, contacts_record_h new);
48 static void __contacts_struct_property_merge(contacts_record_h old, contacts_record_h new);
49 static void __contacts_struct_child_property_merge(unsigned int property_id, contacts_record_h old, contacts_record_h new);
50
51 //static void _remove_vcard_field(CTSstruct *contact);
52 //static void _remove_vcard_gslist_field(gpointer data, gpointer user_data);
53
54 EXPORT_API sync_agent_da_return_e sync_agent_plugin_converter(const void *agent_data, void **service_data)
55 {
56         _EXTERN_FUNC_ENTER;
57
58 //      retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
59 //
60 //      sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
61 //      int err = 0;
62 //      CTSstruct *temp_service_data = 0;
63 //
64 //      /* decoding & convert */
65 //      _DEBUG_INFO("[dc_vcard_plugIn] agent data : %s\n", agent_data);
66 //      char *de_agent_data;
67 //      int src_len = strlen(agent_data);
68 //      int de_agent_data_len = 0;
69 //
70 //      if (check_encoding_data(agent_data) == 1) {
71 //              err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
72 //              if (err == 0) {
73 //                      _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
74 //                      ret = SYNC_AGENT_DA_ERRORS;
75 //                      return ret;
76 //              }
77 //
78 //              err = contacts_svc_get_contact_from_vcard((const void *)de_agent_data, &temp_service_data);
79 //
80 //              /*memory free */
81 //              if (de_agent_data != NULL)
82 //                      free(de_agent_data);
83 //      } else {
84 //              err = contacts_svc_get_contact_from_vcard(agent_data, &temp_service_data);
85 //      }
86 //
87 //      if (err < CTS_SUCCESS) {
88 //              _DEBUG_ERROR("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Fail!\n");
89 //              ret = _convert_service_error_to_common_error(err);
90 //              *service_data = 0;
91 //      } else {
92 //              _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Success!\n");
93 //              *service_data = (void *)temp_service_data;
94 //      }
95
96         retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
97
98         sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
99         contacts_error_e err = CONTACTS_ERROR_NONE;
100         contacts_list_h list = NULL;
101         contacts_record_h record = NULL;
102         contacts_record_h cloned_record = NULL;
103
104         /* decoding & convert */
105         _DEBUG_INFO("[dc_vcard_plugIn] agent data : %s\n", agent_data);
106         char *de_agent_data;
107         int src_len = strlen(agent_data);
108         int de_agent_data_len = 0;
109
110         if (check_encoding_data(agent_data) == 1) {
111                 err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
112                 if (err == 0) {
113                         _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
114                         ret = SYNC_AGENT_DA_ERRORS;
115                         return ret;
116                 }
117
118                 err = contacts_vcard_parse_to_contacts(de_agent_data, &list);
119
120                 /*memory free */
121                 if (de_agent_data != NULL)
122                         free(de_agent_data);
123         } else {
124                 err = contacts_vcard_parse_to_contacts(agent_data, &list);
125         }
126
127         if (err != CONTACTS_ERROR_NONE) {
128                 _DEBUG_ERROR("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Fail!\n");
129                 ret = _convert_service_error_to_common_error(err);
130                 *service_data = 0;
131         } else {
132                 _DEBUG_INFO("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Success!\n");
133                 err = contacts_list_get_current_record_p(list, &record);
134                 if (err != CONTACTS_ERROR_NONE) {
135                         _DEBUG_ERROR("[dc_vcard_plugIn] contacts_list_get_current_record_p() Fail!\n");
136                         ret = _convert_service_error_to_common_error(err);
137                         *service_data = 0;
138                         contacts_list_destroy(list, true);
139                         return ret;
140                 }
141
142                 err = contacts_record_clone(record, &cloned_record);
143                 if (err != CONTACTS_ERROR_NONE) {
144                         _DEBUG_ERROR("[dc_vcard_plugIn] contacts_record_clone() Fail!\n");
145                         ret = _convert_service_error_to_common_error(err);
146                         *service_data = 0;
147                         contacts_list_destroy(list, true);
148                         return ret;
149                 }
150
151                 *service_data = (void *)cloned_record;
152                 contacts_list_destroy(list, true);
153         }
154
155         _EXTERN_FUNC_EXIT;
156         return ret;
157 }
158
159 EXPORT_API sync_agent_da_return_e sync_agent_plugin_replace_converter(void *old_service_data, const void *agent_data, void **new_service_data)
160 {
161         _EXTERN_FUNC_ENTER;
162
163 //      retvm_if(old_service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] old_service_data is NULL");
164 //      retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
165 //
166 //      sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
167 //      int err = 0;
168 //      CTSstruct *temp_new_service_data = 0;
169 //      CTSstruct *temp_old_service_data = (CTSstruct *)old_service_data;
170 //
171 //      /* 1. agent_data  encoding check
172 //       *  2. decoding
173 //       *  3. copy to new_service_data
174 //       */
175 //      /* decoding */
176 //      char *de_agent_data;
177 //      int src_len = strlen(agent_data);
178 //      int de_agent_data_len = 0;
179 //
180 //      if (check_encoding_data(agent_data) == 1) {
181 //              err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
182 //              if (err == 0) {
183 //                      _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
184 ///*                    ret = SYNC_AGENT_DA_ERRORS;
185 //                      return ret;*/
186 //                      err = contacts_svc_get_contact_from_vcard(agent_data, &temp_new_service_data);
187 //              } else {
188 //                      _DEBUG_INFO("[dc_vcard_plugIn] proc_decoding() Success l!\n");
189 //                      err = contacts_svc_get_contact_from_vcard((const void *)de_agent_data, &temp_new_service_data);
190 //
191 //                      /*memory free */
192 //                      if (de_agent_data != NULL)
193 //                              free(de_agent_data);
194 //              }
195 //      } else {
196 //              err = contacts_svc_get_contact_from_vcard(agent_data, &temp_new_service_data);
197 //      }
198 //
199 //      if (err < CTS_SUCCESS) {
200 //              _DEBUG_ERROR("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Fail!\n");
201 //              ret = _convert_service_error_to_common_error(err);
202 //              *new_service_data = 0;
203 //
204 //              /*  memory free */
205 //              if (temp_old_service_data != NULL)
206 //                      contacts_svc_struct_free(temp_old_service_data);
207 //
208 //      } else {
209 //              _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_contact_from_vcard() Success!\n");
210 //              _remove_vcard_field(temp_old_service_data);
211 //              err = contacts_svc_struct_merge(temp_old_service_data, temp_new_service_data);
212 //              if (err < CTS_SUCCESS) {
213 //                      _DEBUG_ERROR("[dc_vcard_plugIn] contacts_svc_struct_merge() Fail!\n");
214 //                      ret = _convert_service_error_to_common_error(err);
215 //                      *new_service_data = 0;
216 //
217 //                      /*  memory free */
218 //                      if (temp_old_service_data != NULL)
219 //                              contacts_svc_struct_free(temp_old_service_data);
220 //              } else {
221 //                      _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_struct_merge() Success!\n");
222 //                      *new_service_data = (void *)temp_old_service_data;
223 //              }
224 //      }
225 //
226 //      /* memory free */
227 //      if (temp_new_service_data != NULL)
228 //              contacts_svc_struct_free(temp_new_service_data);
229
230         retvm_if(old_service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] old_service_data is NULL");
231         retvm_if(agent_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] agent_data is NULL");
232
233         sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
234
235         contacts_error_e err = CONTACTS_ERROR_NONE;
236         contacts_list_h list = NULL;
237
238         contacts_record_h temp_new_service_data = NULL;
239         contacts_record_h temp_old_service_data = (contacts_record_h) old_service_data;
240
241         /* 1. agent_data  encoding check
242          *  2. decoding
243          *  3. copy to new_service_data
244          */
245         /* decoding */
246         char *de_agent_data;
247         int src_len = strlen(agent_data);
248         int de_agent_data_len = 0;
249
250         if (check_encoding_data(agent_data) == 1) {
251                 err = proc_decoding(agent_data, src_len, &de_agent_data, &de_agent_data_len);
252                 if (err == 0) {
253                         _DEBUG_ERROR("[dc_vcard_plugIn] proc_decoding() Fail!\n");
254 /*                      ret = SYNC_AGENT_DA_ERRORS;
255                         return ret;*/
256                         err = contacts_vcard_parse_to_contacts(agent_data, &list);
257                 } else {
258                         _DEBUG_INFO("[dc_vcard_plugIn] proc_decoding() Success l!\n");
259                         err = contacts_vcard_parse_to_contacts(de_agent_data, &list);
260
261                         /*memory free */
262                         if (de_agent_data != NULL)
263                                 free(de_agent_data);
264                 }
265         } else {
266                 err = contacts_vcard_parse_to_contacts(agent_data, &list);
267         }
268
269         if (err != CONTACTS_ERROR_NONE) {
270                 _DEBUG_ERROR("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Fail!\n");
271                 ret = _convert_service_error_to_common_error(err);
272                 *new_service_data = 0;
273
274         } else {
275                 _DEBUG_INFO("[dc_vcard_plugIn] contacts_vcard_parse_to_contacts() Success!\n");
276
277                 err = contacts_list_get_current_record_p(list, &temp_new_service_data);
278                 if (err != CONTACTS_ERROR_NONE) {
279                         _DEBUG_ERROR("[dc_vcard_plugIn] contacts_list_get_current_record_p() Fail!\n");
280                         ret = _convert_service_error_to_common_error(err);
281                         *new_service_data = 0;
282                         goto DACI_FINISH;
283                 }
284
285                 _contacts_struct_merge(temp_old_service_data, temp_new_service_data);
286
287                 *new_service_data = (void *)temp_old_service_data;
288         }
289
290  DACI_FINISH:
291
292         contacts_list_destroy(list, true);
293
294         _EXTERN_FUNC_EXIT;
295         return ret;
296 }
297
298 EXPORT_API sync_agent_da_return_e sync_agent_plugin_reverse_converter(void *service_data, void **agent_data)
299 {
300         _EXTERN_FUNC_ENTER;
301
302 //      retvm_if(service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] service_data is NULL");
303 //
304 //      sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
305 //      int err = 0;
306 //      char *temp_agent_data = 0;
307 //      CTSstruct *temp_service_data = (CTSstruct *)service_data;
308 //
309 //      /* Reverse_Converter */
310 //      err = contacts_svc_get_vcard_from_contact(temp_service_data, &temp_agent_data);
311 //      if (err < CTS_SUCCESS) {
312 //              _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_vcard_from_contact() Fail!\n");
313 //              ret = _convert_service_error_to_common_error(err);
314 //              *agent_data = 0;
315 //      } else {
316 //              _DEBUG_INFO("[dc_vcard_plugIn] contacts_svc_get_vcard_from_contact() Success!\n");
317 //              *agent_data = (void *)temp_agent_data;
318 //      }
319 //
320 //      /*  memory free */
321 //      if (temp_service_data != NULL)
322 //              contacts_svc_struct_free(temp_service_data);
323
324         retvm_if(service_data == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] service_data is NULL");
325
326         sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
327         contacts_error_e err = CONTACTS_ERROR_NONE;
328
329         char *temp_agent_data = 0;
330         contacts_record_h record = (contacts_record_h) service_data;
331
332         char *display_name = NULL;
333         int id;
334         contacts_record_get_str_p(record, _contacts_contact.display_name, &display_name);
335         contacts_record_get_int(record, _contacts_contact.id, &id);
336
337         _DEBUG_INFO("display_name = %s", display_name);
338         _DEBUG_INFO("id = %d", id);
339
340         /* Reverse_Converter */
341         err = contacts_vcard_make_from_contact(record, &temp_agent_data);
342         if (err != CONTACTS_ERROR_NONE) {
343                 _DEBUG_ERROR("[dc_vcard_plugIn] contacts_vcard_make_from_contact() Fail!\n");
344                 ret = _convert_service_error_to_common_error(err);
345                 *agent_data = 0;
346         } else {
347                 _DEBUG_INFO("[dc_vcard_plugIn] contacts_vcard_make_from_contact() Success!\n");
348                 *agent_data = (void *)temp_agent_data;
349                 _DEBUG_INFO("temp_agent_data = %s", temp_agent_data);
350         }
351
352         contacts_record_destroy(record, true);
353
354         _EXTERN_FUNC_EXIT;
355         return ret;
356 }
357
358 EXPORT_API void *sync_agent_plugin_alloc_object()
359 {
360         _EXTERN_FUNC_ENTER;
361
362         char *agent_data = "BEGIN:VCARD\r\n\
363 VERSION:2.1\r\n\
364 END:VCARD";
365
366         _EXTERN_FUNC_EXIT;
367         return (void *)agent_data;
368 }
369
370 EXPORT_API int sync_agent_plugin_free_object(void *in_object)
371 {
372         _EXTERN_FUNC_ENTER;
373         _DEBUG_INFO("[dc_vcard_plugIn] Do nothing\n");
374
375         return 1;
376 }
377
378 EXPORT_API void *sync_agent_plugin_set_value(void *in_object, int key, char *extension_key, void *value)
379 {
380         _EXTERN_FUNC_ENTER;
381
382         char *new_agent_data = 0;
383         char *key_name = 0;
384
385         if (key == VCARD_CONTENT_NO_TYPE)
386                 return (void *)new_agent_data;
387         else if (key == VCARD_CONTENT_EXTENSION)
388                 key_name = extension_key;
389         else
390                 key_name = _convert_key_name(key);
391
392         new_agent_data = _contacts_vcard_put_content((const char *)in_object, (const char *)key_name, (const char *)value);
393
394         _EXTERN_FUNC_EXIT;
395         return (void *)new_agent_data;
396 }
397
398 EXPORT_API void *sync_agent_plugin_get_value(void *in_object, int key, char *extension_key)
399 {
400         _EXTERN_FUNC_ENTER;
401
402         char data[5000] = { 0, };       /* hard coding : size 1000 */
403         char *key_name = 0;
404         int result;
405
406         if (key == VCARD_CONTENT_NO_TYPE)
407                 return 0;
408         else if (key == VCARD_CONTENT_EXTENSION)
409                 key_name = extension_key;
410         else
411                 key_name = _convert_key_name(key);
412
413         result = _contacts_vcard_get_content((const char *)in_object, (const char *)key_name, _get_content, data);
414         if (result == 0) {
415                 _EXTERN_FUNC_EXIT;
416                 return 0;
417         }
418
419         _EXTERN_FUNC_EXIT;
420
421         if (strlen(data) == 0)
422                 return 0;
423         else
424                 return strdup(data);
425 }
426
427 EXPORT_API sync_agent_plugin_object_info_s *sync_agent_plugin_get_obj_info()
428 {
429         _EXTERN_FUNC_ENTER;
430
431         sync_agent_plugin_object_info_s *obj_info = (sync_agent_plugin_object_info_s *) calloc(1, sizeof(sync_agent_plugin_object_info_s));
432         if (obj_info == NULL) {
433                 _DEBUG_ERROR("CALLOC failed !!!");
434                 return NULL;
435         }
436
437         obj_info->type = VCARD_TYPE;
438         obj_info->version = VCARD_VERSION;
439         obj_info->field_cnt = sizeof(vcard_field_list) / sizeof(vcard_field_list_s);
440
441         if (obj_info->field_cnt > 0)
442                 if (_set_obj_field_info(&(obj_info->field_list), obj_info->field_cnt, vcard_field_list) == 0) {
443                         /* for prevent */
444                         if (obj_info != NULL)
445                                 free(obj_info);
446
447                         return NULL;
448                 }
449
450         _EXTERN_FUNC_EXIT;
451         return obj_info;
452 }
453
454 EXPORT_API int sync_agent_plugin_free_obj_info(sync_agent_plugin_object_info_s * obj_info)
455 {
456         _EXTERN_FUNC_ENTER;
457
458         if (obj_info != NULL) {
459                 if (obj_info->field_cnt > 0)
460                         if (_free_obj_field_info(obj_info->field_list, obj_info->field_cnt) == 0)
461                                 return 0;
462
463                 free(obj_info);
464         }
465
466         _EXTERN_FUNC_EXIT;
467         return 1;
468 }
469
470 static int _free_obj_field_info(sync_agent_plugin_field_info_s * field_list, int count)
471 {
472         _INNER_FUNC_ENTER;
473
474         int field_count = 0;
475         sync_agent_plugin_field_info_s *child = NULL;
476
477         if (field_list != NULL) {
478                 for (field_count = 0; field_count < count; field_count++) {
479                         child = field_list + field_count;
480                         if (child->field_child_cnt > 0)
481                                 if (_free_obj_field_info(child->field_child_list, child->field_child_cnt) == 0)
482                                         return 0;
483                 }
484                 free(field_list);
485         }
486
487         _INNER_FUNC_EXIT;
488         return 1;
489 }
490
491 static int _set_obj_field_info(sync_agent_plugin_field_info_s ** field_list, int count, vcard_field_list_s * input_list)
492 {
493         _INNER_FUNC_ENTER;
494
495         int field_count = 0;
496         sync_agent_plugin_field_info_s *child = NULL;
497
498         *field_list = (sync_agent_plugin_field_info_s *) calloc(count, sizeof(sync_agent_plugin_field_info_s));
499         if (*field_list == NULL) {
500                 _DEBUG_ERROR("CALLOC failed !!!");
501                 return 0;
502         }
503
504         for (field_count = 0; field_count < count; field_count++) {
505                 child = (*field_list) + field_count;
506                 child->field_name = input_list[field_count].field_name;
507                 _DEBUG_TRACE("[%s]", child->field_name);
508
509                 if (input_list[field_count].field_enum == VCARD_FIELD_BEGIN || input_list[field_count].field_enum == VCARD_FIELD_END) {
510                         child->field_child_cnt = sizeof(vcard_field_list_begin_end) / sizeof(vcard_field_list_s);
511                         _DEBUG_TRACE("----------");
512                         _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_begin_end);
513                         _DEBUG_TRACE("==========");
514                 } else if (input_list[field_count].field_enum == VCARD_FIELD_VERSION) {
515                         child->field_child_cnt = sizeof(vcard_field_list_version) / sizeof(vcard_field_list_s);
516                         _DEBUG_TRACE("----------");
517                         _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_version);
518                         _DEBUG_TRACE("==========");
519                 } else if (input_list[field_count].field_enum == VCARD_FIELD_ADR) {
520                         child->field_child_cnt = sizeof(vcard_field_list_adr) / sizeof(vcard_field_list_s);
521                         _DEBUG_TRACE("----------");
522                         _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_adr);
523                         _DEBUG_TRACE("==========");
524                 } else if (input_list[field_count].field_enum == VCARD_FIELD_TEL) {
525                         child->field_child_cnt = sizeof(vcard_field_list_tel) / sizeof(vcard_field_list_s);
526                         _DEBUG_TRACE("----------");
527                         _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_tel);
528                         _DEBUG_TRACE("==========");
529                 } else if (input_list[field_count].field_enum == VCARD_FIELD_EMAIL) {
530                         child->field_child_cnt = sizeof(vcard_field_list_email) / sizeof(vcard_field_list_s);
531                         _DEBUG_TRACE("----------");
532                         _set_obj_field_info(&(child->field_child_list), child->field_child_cnt, vcard_field_list_email);
533                         _DEBUG_TRACE("==========");
534                 }
535         }
536
537         _INNER_FUNC_EXIT;
538         return 1;
539 }
540
541 static char *_convert_key_name(int key)
542 {
543         _INNER_FUNC_ENTER;
544
545         char *key_name = 0;
546
547         switch (key) {
548         case VCARD_CONTENT_FN:
549                 key_name = "FN";
550                 break;
551         case VCARD_CONTENT_N:
552                 key_name = "N";
553                 break;
554         case VCARD_CONTENT_NICKNAME:
555                 key_name = "NICKNAME";
556                 break;
557         case VCARD_CONTENT_PHOTO:
558                 key_name = "PHOTO";
559                 break;
560         case VCARD_CONTENT_BDAY:
561                 key_name = "BDAY";
562                 break;
563         case VCARD_CONTENT_ADR:
564                 key_name = "ADR";
565                 break;
566         case VCARD_CONTENT_LABEL:
567                 key_name = "LABEL";
568                 break;
569         case VCARD_CONTENT_TEL:
570                 key_name = "TEL";
571                 break;
572         case VCARD_CONTENT_EMAIL:
573                 key_name = "EMAIL";
574                 break;
575         case VCARD_CONTENT_TITLE:
576                 key_name = "TITLE";
577                 break;
578         case VCARD_CONTENT_ROLE:
579                 key_name = "ROLE";
580                 break;
581         case VCARD_CONTENT_ORG:
582                 key_name = "ORG";
583                 break;
584         case VCARD_CONTENT_NOTE:
585                 key_name = "NOTE";
586                 break;
587         case VCARD_CONTENT_REV:
588                 key_name = "REV";
589                 break;
590         case VCARD_CONTENT_UID:
591                 key_name = "UID";
592                 break;
593         case VCARD_CONTENT_URL:
594                 key_name = "URL";
595                 break;
596         case VCARD_CONTENT_X_ANNIVERSARY:
597                 key_name = "X-ANNIVERSARY";
598                 break;
599         case VCARD_CONTENT_X_IRMC_LUID:
600                 key_name = "X-IRMC-LUID";
601                 break;
602         default:
603                 break;
604         }
605
606         _INNER_FUNC_EXIT;
607         return key_name;
608 }
609
610 static int _get_content(const char *value, void *data)
611 {
612         _INNER_FUNC_ENTER;
613
614         retvm_if(value == NULL, SYNC_AGENT_DA_ERRORS, "[dc_vcard_plugIn] value is NULL");
615
616         const char *line_breaker = "\r";
617         char *colon_loc = 0;
618         char *line_breaker_loc = 0;
619         int data_size = 0;
620
621         colon_loc = (char *)value;
622         line_breaker_loc = strstr(colon_loc, line_breaker);
623         data_size = line_breaker_loc - colon_loc;
624         _DEBUG_TRACE("[dc_vcard_plugIn] value : %s", value);
625         _DEBUG_TRACE("[dc_vcard_plugIn] colon_loc : %s", colon_loc);
626         _DEBUG_TRACE("[dc_vcard_plugIn] line_breaker_loc : %s", line_breaker_loc);
627         _DEBUG_TRACE("[dc_vcard_plugIn] data_size : %d", data_size);
628
629         /* hard coding : size 5000 */
630         memcpy((char *)data, colon_loc, data_size);
631
632         _INNER_FUNC_EXIT;
633         return 1;
634 }
635
636 static sync_agent_da_return_e _convert_service_error_to_common_error(contacts_error_e err)
637 {
638         _INNER_FUNC_ENTER;
639
640         sync_agent_da_return_e ret = SYNC_AGENT_DA_SUCCESS;
641         _DEBUG_TRACE("[da_contact_plugIn] Error Code : %d\n", err);
642
643         switch (err) {
644         case CONTACTS_ERROR_NONE:
645                 ret = SYNC_AGENT_DA_SUCCESS;
646                 break;
647         case CONTACTS_ERROR_OUT_OF_MEMORY:
648                 ret = SYNC_AGENT_DA_ERR_MEMORY_FULL;
649                 break;
650         case CONTACTS_ERROR_INVALID_PARAMETER:
651                 ret = SYNC_AGENT_DA_ERR_INVALID_PARAMETER;
652                 break;
653         case CONTACTS_ERROR_NO_DATA:
654                 ret = SYNC_AGENT_DA_ERR_NO_DATA;
655                 break;
656         case CONTACTS_ERROR_DB:
657                 ret = SYNC_AGENT_DA_ERR_SERVICE_DB;
658                 break;
659         case CONTACTS_ERROR_IPC:
660                 ret = SYNC_AGENT_DA_ERR_SERVICE_IPC;
661                 break;
662         default:
663                 ret = SYNC_AGENT_DA_ERRORS;
664                 break;
665         }
666
667         _INNER_FUNC_EXIT;
668
669         return ret;
670 }
671
672 static char *_contacts_vcard_put_content(const char *vcard_stream, const char *content_type, const char *content_value)
673 {
674         _INNER_FUNC_ENTER;
675
676         int i, org_len, new_len;
677         char *new_stream, *cur;
678         const char *end_content = "END:VCARD";
679
680         retvm_if(NULL == vcard_stream, NULL, "vcard_stream is NULL");
681         retvm_if(NULL == content_type, NULL, "content_type is NULL");
682         retvm_if(NULL == content_value, NULL, "content_value is NULL");
683
684         org_len = strlen(vcard_stream);
685         new_len = org_len + strlen(content_type) + strlen(content_value) + 8;
686
687         new_stream = malloc(new_len);
688         retvm_if(NULL == new_stream, NULL, "malloc() Failed");
689
690         memcpy(new_stream, vcard_stream, org_len);
691
692         i = 1;
693         for (cur = new_stream + new_len - 1; cur; cur--) {
694                 if (end_content[9 - i] == *cur) {
695                         if (9 == i)
696                                 break;
697                         i++;
698                         continue;
699                 } else {
700                         i = 1;
701                 }
702         }
703         if (9 != i) {
704                 _DEBUG_ERROR("vcard_stream is invalid(%s)", vcard_stream);
705                 free(new_stream);
706                 _INNER_FUNC_EXIT;
707                 return NULL;
708         }
709
710         cur += snprintf(cur, new_len - (cur - new_stream), "%s:", content_type);
711         cur = strncpy(cur, content_value, new_len - (cur - new_stream));
712         snprintf(cur, new_len - (cur - new_stream), "\r\n%s\r\n", end_content);
713
714         _INNER_FUNC_EXIT;
715
716         return new_stream;
717 }
718
719 static int _contacts_vcard_get_content(const char *vcard_stream, const char *content_type, int (*fn) (const char *content_value, void *data), void *data)
720 {
721         _INNER_FUNC_ENTER;
722
723         int len, buf_size, type_len;
724         char *cursor, *found, *value;
725
726         retv_if(NULL == vcard_stream, 0);
727         retv_if(NULL == content_type, 0);
728         retv_if(NULL == fn, 0);
729
730         type_len = strlen(content_type);
731         value = malloc(1024);
732         retvm_if(NULL == value, 0, "malloc() Failed");
733         buf_size = 1024;
734
735         while ((found = strstr(vcard_stream, content_type))) {
736                 if ((found != vcard_stream && '\n' != *(found - 1))
737                     && ':' != *(found + type_len + 1))
738                         continue;
739
740                 cursor = found;
741                 while (*cursor) {
742                         if ('\r' == *cursor)
743                                 cursor++;
744                         if ('\n' == *cursor) {
745                                 if (' ' != *(cursor + 1))
746                                         break;
747                         }
748
749                         cursor++;
750                 }
751                 len = cursor - found;
752                 if (len < buf_size)
753                         memcpy(value, found, len);
754                 else {
755                         value = realloc(value, len + 1);
756                         if (value) {
757                                 buf_size = len + 1;
758                                 memcpy(value, found, len);
759                         } else {
760                                 vcard_stream = found + type_len;
761                                 continue;
762                         }
763                 }
764                 value[len] = '\0';
765                 if (fn)
766                         if (fn(value + type_len + 1, data)) {
767                                 free(value);
768                                 _INNER_FUNC_EXIT;
769                                 return 0;
770                         }
771                 vcard_stream = found + type_len;
772         }
773
774         free(value);
775
776         _INNER_FUNC_EXIT;
777         return 1;
778 }
779
780 static void _contacts_struct_merge(contacts_record_h old, contacts_record_h new)
781 {
782         _INNER_FUNC_ENTER;
783
784         __contacts_struct_property_merge(old, new);
785
786         __contacts_struct_child_property_merge(_contacts_contact.name, old, new);
787         __contacts_struct_child_property_merge(_contacts_contact.image, old, new);
788         __contacts_struct_child_property_merge(_contacts_contact.company, old, new);
789         __contacts_struct_child_property_merge(_contacts_contact.note, old, new);
790         __contacts_struct_child_property_merge(_contacts_contact.number, old, new);
791         __contacts_struct_child_property_merge(_contacts_contact.email, old, new);
792         __contacts_struct_child_property_merge(_contacts_contact.event, old, new);
793         __contacts_struct_child_property_merge(_contacts_contact.messenger, old, new);
794         __contacts_struct_child_property_merge(_contacts_contact.address, old, new);
795         __contacts_struct_child_property_merge(_contacts_contact.url, old, new);
796         __contacts_struct_child_property_merge(_contacts_contact.nickname, old, new);
797         __contacts_struct_child_property_merge(_contacts_contact.profile, old, new);
798 //      __contacts_struct_child_property_merge(_contacts_contact.relationship, old, new);
799 //      __contacts_struct_child_property_merge(_contacts_contact.group_relation, old, new);
800         __contacts_struct_child_property_merge(_contacts_contact.extension, old, new);
801
802         _INNER_FUNC_EXIT;
803 }
804
805 static void __contacts_struct_property_merge(contacts_record_h old, contacts_record_h new)
806 {
807         _INNER_FUNC_ENTER;
808
809 //      contacts_error_e err = CONTACTS_ERROR_NONE;
810 //
811 //      char *ringtone_path = NULL;
812 //      char *image_thumbnail_path = NULL;
813 //      char *uid = NULL;
814 //      char *vibration = NULL;
815 //
816 //      err = contacts_record_get_str_p(new, _contacts_contact.ringtone_path, &ringtone_path);
817 //      if (err != CONTACTS_ERROR_NONE)
818 //              _DEBUG_ERROR("contacts_record_get_str_p(ringtone_path) is failed");
819 //
820 //      if (ringtone_path != NULL) {
821 //              _DEBUG_TRACE("ringtone_path = %s", ringtone_path);
822 //              err = contacts_record_set_str(old, _contacts_contact.ringtone_path, ringtone_path);
823 //              if (err != CONTACTS_ERROR_NONE)
824 //                      _DEBUG_ERROR("contacts_record_set_str(%s) is failed", ringtone_path);
825 //      }
826 //
827 //      err = contacts_record_get_str_p(new, _contacts_contact.image_thumbnail_path, &image_thumbnail_path);
828 //      if (err != CONTACTS_ERROR_NONE)
829 //              _DEBUG_ERROR("contacts_record_get_str_p(image_thumbnail_path) is failed");
830 //
831 //      if (image_thumbnail_path != NULL) {
832 //              _DEBUG_TRACE("image_thumbnail_path = %s", image_thumbnail_path);
833 //              err = contacts_record_set_str(old, _contacts_contact.image_thumbnail_path, image_thumbnail_path);
834 //              if (err != CONTACTS_ERROR_NONE)
835 //                      _DEBUG_ERROR("contacts_record_set_str(%s) is failed", image_thumbnail_path);
836 //      }
837 //
838 //      err = contacts_record_get_str_p(new, _contacts_contact.uid, &uid);
839 //      if (err != CONTACTS_ERROR_NONE)
840 //              _DEBUG_ERROR("contacts_record_get_str_p(uid) is failed");
841 //
842 //      if (uid != NULL) {
843 //              _DEBUG_TRACE("uid = %s", uid);
844 //              err = contacts_record_set_str(old, _contacts_contact.uid, uid);
845 //              if (err != CONTACTS_ERROR_NONE)
846 //                      _DEBUG_ERROR("contacts_record_set_str(%s) is failed", uid);
847 //      }
848 //
849 //      err = contacts_record_get_str_p(new, _contacts_contact.vibration, &vibration);
850 //      if (err != CONTACTS_ERROR_NONE)
851 //              _DEBUG_ERROR("contacts_record_get_str_p(vibration) is failed");
852 //
853 //      if (vibration != NULL) {
854 //              _DEBUG_TRACE("vibration = %s", vibration);
855 //              err = contacts_record_set_str(old, _contacts_contact.vibration, vibration);
856 //              if (err != CONTACTS_ERROR_NONE)
857 //                      _DEBUG_ERROR("contacts_record_set_str(%s) is failed", vibration);
858 //      }
859
860         contacts_error_e err = CONTACTS_ERROR_NONE;
861
862         char *image_thumbnail_path = NULL;
863
864         err = contacts_record_get_str_p(new, _contacts_contact.image_thumbnail_path, &image_thumbnail_path);
865         if (err != CONTACTS_ERROR_NONE)
866                 _DEBUG_ERROR("contacts_record_get_str_p(image_thumbnail_path) is failed");
867
868         if (image_thumbnail_path != NULL) {
869                 _DEBUG_TRACE("image_thumbnail_path = %s", image_thumbnail_path);
870                 err = contacts_record_set_str(old, _contacts_contact.image_thumbnail_path, image_thumbnail_path);
871                 if (err != CONTACTS_ERROR_NONE)
872                         _DEBUG_ERROR("contacts_record_set_str(%s) is failed", image_thumbnail_path);
873         }
874
875         _INNER_FUNC_EXIT;
876 }
877
878 static void __contacts_struct_child_property_merge(unsigned int property_id, contacts_record_h old, contacts_record_h new)
879 {
880         _INNER_FUNC_ENTER;
881
882         contacts_error_e err = CONTACTS_ERROR_NONE;
883
884         unsigned int old_count = 0;
885         unsigned int new_count = 0;
886
887         contacts_record_h old_record = NULL;
888         contacts_record_h new_record = NULL;
889         contacts_record_h new_cloned_record = NULL;
890
891         _DEBUG_TRACE("property_id = %d", property_id);
892
893         err = contacts_record_get_child_record_count(old, property_id, &old_count);
894         if (err != CONTACTS_ERROR_NONE)
895                 _DEBUG_ERROR("contacts_record_get_child_record_count is failed");
896
897         _DEBUG_TRACE("old_count = %d", old_count);
898
899         int i;
900         for (i = 0; i < old_count; i++) {
901
902                 err = contacts_record_get_child_record_at_p(old, property_id, 0, &old_record);
903                 if (err != CONTACTS_ERROR_NONE)
904                         _DEBUG_ERROR("contacts_record_get_child_record_at_p is failed");
905
906                 err = contacts_record_remove_child_record(old, property_id, old_record);
907                 if (err != CONTACTS_ERROR_NONE)
908                         _DEBUG_ERROR("contacts_record_remove_child_record is failed");
909         }
910
911         err = contacts_record_get_child_record_count(new, property_id, &new_count);
912         if (err != CONTACTS_ERROR_NONE)
913                 _DEBUG_ERROR("contacts_record_get_child_record_count is failed");
914
915         _DEBUG_TRACE("new_count = %d", new_count);
916
917         for (i = 0; i < new_count; i++) {
918
919                 err = contacts_record_get_child_record_at_p(new, property_id, i, &new_record);
920                 if (err != CONTACTS_ERROR_NONE)
921                         _DEBUG_ERROR("contacts_record_get_child_record_at_p is failed");
922
923                 err = contacts_record_clone(new_record, &new_cloned_record);
924                 if (err != CONTACTS_ERROR_NONE)
925                         _DEBUG_ERROR("contacts_record_clone is failed");
926
927                 err = contacts_record_add_child_record(old, property_id, new_cloned_record);
928                 if (err != CONTACTS_ERROR_NONE)
929                         _DEBUG_ERROR("contacts_record_add_child_record is failed");
930         }
931
932         _INNER_FUNC_EXIT;
933 }
934
935 //static void _remove_vcard_field(CTSstruct *contact)
936 //{
937 //      _INNER_FUNC_ENTER;
938 //
939 //      GSList *numbers = 0, *email = 0, *event = 0, *postal = 0, *web = 0, *nick = 0;
940 //      CTSvalue *name = 0, *company = 0, *base = 0;
941 //
942 //      /* free name */
943 //      contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &name);
944 //      contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, 0);
945 //      contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, 0);
946 //      contacts_svc_value_set_str(name, CTS_NAME_VAL_ADDITION_STR, 0);
947 //      contacts_svc_value_set_str(name, CTS_NAME_VAL_SUFFIX_STR, 0);
948 //      contacts_svc_value_set_str(name, CTS_NAME_VAL_PREFIX_STR, 0);
949 //      contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, 0);
950 //
951 //      /* free company */
952 //      contacts_svc_struct_get_value(contact, CTS_VALUE_COMPANY, &company);
953 //      contacts_svc_value_set_str(company, CTS_COMPANY_VAL_NAME_STR, 0);
954 //      contacts_svc_value_set_str(company, CTS_COMPANY_VAL_DEPARTMENT_STR, 0);
955 //      contacts_svc_value_set_str(company, CTS_COMPANY_VAL_JOB_TITLE_STR, 0);
956 //      contacts_svc_value_set_str(company, CTS_COMPANY_VAL_ROLE_STR, 0);
957 //
958 //      /* free base */
959 //      contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &base);
960 //      contacts_svc_value_set_str(base, CTS_BASE_VAL_IMG_PATH_STR, 0);
961 //      //contacts_svc_value_set_str(base, CTS_BASE_VAL_FULL_IMG_PATH_STR, 0);
962 //      contacts_svc_value_set_str(base, CTS_NOTE_VAL_NOTE_STR, 0);
963 //
964 //      /* free number */
965 //      contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &numbers);
966 //      g_slist_foreach(numbers, _remove_vcard_gslist_field, (gpointer) CTS_NUM_VAL_DELETE_BOOL);
967 //
968 //      /* free email */
969 //      contacts_svc_struct_get_list(contact, CTS_CF_EMAIL_LIST, &email);
970 //      g_slist_foreach(email, _remove_vcard_gslist_field, (gpointer) CTS_EMAIL_VAL_DELETE_BOOL);
971 //
972 //      /* free event */
973 //      contacts_svc_struct_get_list(contact, CTS_CF_EVENT_LIST, &event);
974 //      g_slist_foreach(event, _remove_vcard_gslist_field, (gpointer) CTS_EVENT_VAL_DELETE_BOOL);
975 //
976 //      /* free postal */
977 //      contacts_svc_struct_get_list(contact, CTS_CF_POSTAL_ADDR_LIST, &postal);
978 //      g_slist_foreach(postal, _remove_vcard_gslist_field, (gpointer) CTS_POSTAL_VAL_DEFAULT_BOOL);
979 //
980 //      /* free web */
981 //      contacts_svc_struct_get_list(contact, CTS_CF_WEB_ADDR_LIST, &web);
982 //      g_slist_foreach(web, _remove_vcard_gslist_field, (gpointer) CTS_WEB_VAL_DELETE_BOOL);
983 //
984 //      /* free nick */
985 //      contacts_svc_struct_get_list(contact, CTS_CF_NICKNAME_LIST, &nick);
986 //      g_slist_foreach(nick, _remove_vcard_gslist_field, (gpointer) CTS_NICKNAME_VAL_DELETE_BOOL);
987 //
988 //      _INNER_FUNC_EXIT;
989 //}
990 //
991 //static void _remove_vcard_gslist_field(gpointer data, gpointer user_data)
992 //{
993 //      _INNER_FUNC_ENTER;
994 //
995 //      contacts_svc_value_set_bool((CTSvalue *) data, (int)user_data, 1);
996 //
997 //      _INNER_FUNC_EXIT;
998 //}