Merge branch 'master' into tizen_2.1
[platform/core/connectivity/bluetooth-agent.git] / pb-agent / bluetooth_pb_vcard.c
1 /*
2  * bluetooth-agent
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <time.h>
21 #include <string.h>
22 #include <stdarg.h>
23
24
25 #include <glib.h>
26 #include <dbus/dbus-glib.h>
27
28 #include <vconf.h>
29 #include <dlog.h>
30 #include <contacts.h>
31
32 #include "bluetooth_pb_vcard.h"
33
34 #define BT_PB_AGENT     "BT_PB_AGENT"
35 #define DBG(fmt, args...) SLOG(LOG_DEBUG, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
36 #define ERR(fmt, args...) SLOG(LOG_ERROR, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
37
38 #define VCARD_FORMAT_2_1 0x0
39 #define VCARD_FORMAT_3_0 0x1
40
41 #define VCARD_VERSION   (0x1)
42 #define VCARD_FN        (0x1 << 1)
43 #define VCARD_N         (0x1 << 2)
44 #define VCARD_PHOTO     (0x1 << 3)
45 #define VCARD_BDAY      (0x1 << 4)
46 #define VCARD_ADR       (0x1 << 5)
47 #define VCARD_LABEL     (0x1 << 6)      /* not supported */
48 #define VCARD_TEL       (0x1 << 7)
49 #define VCARD_EMAIL     (0x1 << 8)
50 #define VCARD_MAILER    (0x1 << 9)      /* not supported */
51 #define VCARD_TZ        (0x1 << 10)     /* not supported */
52 #define VCARD_GEO       (0x1 << 11)     /* not supported */
53 #define VCARD_TITLE     (0x1 << 12)
54 #define VCARD_ROLE      (0x1 << 13)
55 #define VCARD_LOGO      (0x1 << 14)     /* not supported */
56 #define VCARD_AGENT     (0x1 << 15)     /* not supported */
57 #define VCARD_ORG       (0x1 << 16)
58 #define VCARD_NOTE      (0x1 << 17)
59 #define VCARD_REV       (0x1 << 18)
60 #define VCARD_SOUND     (0x1 << 19)     /* not supported */
61 #define VCARD_URL       (0x1 << 20)
62 #define VCARD_UID       (0x1 << 21)
63 #define VCARD_KEY       (0x1 << 22)     /* not supported */
64 #define VCARD_NICKNAME  (0x1 << 23)
65 #define VCARD_CATEGORIES        (0x1 << 24)     /* not supported */
66 #define VCARD_PROID     (0x1 << 25)     /* not supported */
67 #define VCARD_CLASS     (0x1 << 26)     /* not supported */
68 #define VCARD_SORT_STRING       (0x1 << 27)     /* not supported */
69
70 #define VCARD_X_IRMC_CALL_DATETIME      (0x1 << 28)
71
72 #define QP_ENC_LEN      3
73 #define LINEBREAK_LEN   75
74
75 static gchar *__bluetooth_pb_vcard_escape(const gchar *str);
76
77 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
78                                         const gchar *delimeter);
79
80 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str);
81
82 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
83                                                 gint len);
84
85 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
86                                                         const gchar *str,
87                                                         gint len,
88                                                         gint *line_pos);
89
90 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
91                                                         gchar ch,
92                                                         gint *line_pos);
93
94 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
95                                                 const gchar *str,
96                                                 gint len,
97                                                 gint *line_pos);
98
99 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str);
100
101 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
102                                                  const gchar *param);
103
104 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
105                                         const gchar *name,
106                                         const gchar *param,
107                                         const gchar *value);
108
109 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
110                                                         const gchar *name,
111                                                         const gchar *param,
112                                                         const gchar *value,
113                                                         gsize len,
114                                                         gboolean folding);
115
116 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
117                                         contacts_record_h contact);
118
119 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
120                                                 contacts_record_h conatct);
121
122 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
123                                         contacts_record_h person);
124
125 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
126                                                 contacts_record_h person);
127
128 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
129                                                 contacts_record_h contact);
130
131 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
132                                                 contacts_record_h contact);
133
134 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
135                                                 contacts_record_h contact);
136
137 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
138                                                 contacts_record_h contact);
139
140 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
141                                                 contacts_record_h contact);
142
143 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
144                                                 contacts_record_h contact);
145
146 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
147                                                 contacts_record_h contact);
148
149 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
150                                                 contacts_record_h contact);
151
152 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
153                                                 contacts_record_h contact);
154
155 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
156                                                 contacts_record_h contact);
157
158 static void __bluetooth_pb_vcard_append_v30(GString *string,
159                                         const gchar *name,
160                                         const gchar *param,
161                                         const gchar *value);
162
163 static void __bluetooth_pb_vcard_remove_v30(GString *string,
164                                         const gchar *property_name);
165
166 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
167                                         guint64 filter);
168
169 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
170                                                         gint phonelog_id,
171                                                         guint64 filter,
172                                                         const gchar *first_name,
173                                                         va_list args);
174
175 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
176                                                         gint phonelog_id,
177                                                         guint64 filter,
178                                                         const gchar *first_name,
179                                                         va_list args);
180
181 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
182                                                                 gint phonelog_id,
183                                                                 guint64 filter,
184                                                                 guint8 format,
185                                                                 const gchar *first_name,
186                                                                 ...);
187
188 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
189                                                 guint filter,
190                                                 const gchar *attr);
191
192 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
193                                                 guint filter,
194                                                 const gchar *attr);
195
196 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
197                                         guint filter,
198                                         guint8 format,
199                                         const gchar *attr);
200
201 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
202                                                 int *field,
203                                                 gint field_size);
204
205 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number);
206
207 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename);
208
209 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address);
210
211 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address);
212
213 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id);
214
215 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
216
217 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
218
219 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
220
221
222 static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
223 {
224         GString *escaped;
225
226         gchar *st = NULL;
227         gchar *pos = NULL;
228
229         if (str == NULL)
230                 return NULL;
231
232         escaped = g_string_new(NULL);
233
234         st = (gchar *)str;
235         pos = st;
236
237         while (*pos != '\0') {
238                 if (*pos == ';') {
239                         g_string_append_len(escaped, st, (pos - st));
240                         g_string_append(escaped, "\\;");
241
242                         pos++;
243                         st = pos;
244                 }
245                 else {
246                         pos++;
247                 }
248         }
249
250         g_string_append_len(escaped, st, (pos - st));
251         return g_string_free(escaped, FALSE);
252 }
253
254 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
255                                         const gchar *separator)
256 {
257         GString *string = g_string_new(NULL);
258         gint i;
259
260         for (i = 0; strv[i] != NULL; i++) {
261                 if (i > 0)
262                         g_string_append(string, ";");
263
264                 g_string_append(string, strv[i]);
265         }
266
267         return g_string_free(string, FALSE);
268 }
269
270 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
271 {
272         gchar *pos = NULL;
273
274         if (str == NULL)
275                 return FALSE;
276
277         pos = (gchar *)str;
278         while (*pos != '\0') {
279                 /* ascii code ' ' : 32, '~' : 126 */
280                 if ((guchar)*pos < ' ' || (guchar)*pos > '~')
281                         return TRUE;
282
283                 pos++;
284         }
285         return FALSE;
286 }
287
288 /* get string length, which convert to quoted-printable encoding */
289 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
290                                                 gint len)
291 {
292         gchar *pos;
293
294         gint count = 0;
295         gint length = len;
296
297         if (str == NULL)
298                 return 0;
299
300         if (strlen(str) < len )
301                 length = -1;
302
303         pos = (gchar *)str;
304
305         while (*pos != '\0' && (((pos - str) < length) || length < 0)) {
306                 if ((guchar)*pos == '\t') {
307                         count++;
308                         pos++;
309                         continue;
310                 }
311
312                 if ((guchar)*pos < ' ' || (guchar)*pos == '=') {
313                         count += QP_ENC_LEN;
314                         pos++;
315                         continue;
316                 }
317
318                 /* check no-ascii utf-8 character */
319                 if ((guchar)*pos > '~') {
320
321                         gchar *next;
322
323                         next = g_utf8_next_char(pos);
324
325                         count += QP_ENC_LEN * (next - pos);
326                         pos = next;
327                         continue;
328                 }
329
330                 pos++;
331                 count++;
332         }
333
334         return count;
335 }
336
337 /* convert to quoted printable code */
338 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
339                                                         const gchar *str,
340                                                         gint len,
341                                                         gint *line_pos)
342 {
343         int i;
344
345         if (str == NULL || len == 0)
346                 return;
347
348         /* add soft linebreak when it exceed */
349         if ((*line_pos + (QP_ENC_LEN * len) > LINEBREAK_LEN)) {
350                 g_string_append(string, "=\r\n");
351                 *line_pos = 0;
352         }
353
354         for (i = 0; i < len; i++) {
355                 g_string_append_printf(string, "=%02X", (guchar)*(str+i));
356                 *line_pos += QP_ENC_LEN;
357         }
358 }
359
360 /* append plain visiable ascii character */
361 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
362                                                         gchar ch,
363                                                         gint *line_pos)
364 {
365         /* add soft linebreak when it exceed */
366         if (*line_pos + 1 > LINEBREAK_LEN) {
367                 g_string_append(string, "=\r\n");
368                 *line_pos = 0;
369         }
370         g_string_append_c(string, ch);
371         (*line_pos)++;
372 }
373
374 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
375                                                 const gchar *str,
376                                                 gint len,
377                                                 gint *line_pos)
378 {
379         gint length;
380         gint encode_len;
381
382         gint i = 0;
383
384         if (string == NULL)
385                 return;
386
387         encode_len = __bluetooth_pb_vcard_qp_encode_strlen(str, len);
388
389         /* add soft linebreak when it exceed */
390         if (((*line_pos + encode_len) > LINEBREAK_LEN) && (*line_pos > 1)) {
391                 g_string_append(string, "=\r\n");
392                 *line_pos = 0;
393         }
394
395         length = strlen(str);
396         if (length > len)
397                 length = len;
398
399         while (i < len) {
400                 gchar *pos;
401
402                 pos = ((gchar *)str) + i;
403
404                 /* converts invisiable character and escape character '=' to quoted-printable */
405                 if ((guchar)*pos != '\t' &&
406                                 ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
407                         __bluetooth_pb_vcard_qp_encode_append_to_hex(string, pos,
408                                         1, line_pos);
409                         i++;
410
411                         continue;
412                 }
413
414                 /* converts non-ascii utf-8 character to quoted-printable */
415                 if ((guchar)*pos > '~') {
416                         gchar *next;
417                         int ch_len;
418
419                         next = g_utf8_next_char(pos);
420
421                         ch_len = next - pos;
422                         __bluetooth_pb_vcard_qp_encode_append_to_hex(string, pos,
423                                         ch_len, line_pos);
424                         i += ch_len;
425
426                         continue;
427                 }
428
429                 __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos, line_pos);
430                 i++;
431         }
432 }
433
434 static gchar* __bluetooth_pb_vcard_qp_encode(const gchar *str)
435 {
436         GString *enc;
437
438         gchar *st_pos;
439         gchar *pos;
440
441         gint line_pos = 0;
442
443         if (str == NULL)
444                 return NULL;
445
446         enc = g_string_new(NULL);
447
448         st_pos = (gchar *)str;
449         pos = (gchar *)str;
450
451         while (*pos != '\0') {
452                 /* split string with given delimeter ' ' or '\t' */
453                 if (*pos == ' ' || *pos == '\t') {
454                         __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
455                                         (pos - st_pos), &line_pos);
456
457                         st_pos = pos;
458                         pos++;
459
460                         continue;
461                 }
462
463                 /* split string with given delimeter '\r', '\n' or '\r\n' - newline */
464                 if (*pos == '\r' || *pos == '\n' ) {
465                         __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
466                                         (pos - st_pos), &line_pos);
467
468                         /* converts newline to qp_encode with soft linebreak
469                          for example, converts \r\n to =0D=0A=\r\n */
470                         __bluetooth_pb_vcard_qp_encode_append_to_hex(enc, "\r\n",
471                                         2, &line_pos);
472                         g_string_append(enc, "=\r\n ");
473
474                         line_pos = 1;
475
476                         if (*pos == '\r' && *(pos + 1) == '\n')
477                                 pos += 2;
478                         else
479                                 pos++;
480
481                         st_pos = pos;
482
483                         continue;
484                 }
485
486                 pos++;
487         }
488
489         __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
490                         (pos - st_pos), &line_pos);
491
492         return g_string_free(enc, FALSE);
493 }
494
495 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
496                                                  const gchar *param)
497 {
498         gchar *pos = NULL;
499
500         if (param == NULL)
501                 return;
502
503         pos = (gchar *)param;
504
505         /* trim ';' on first */
506         while (*pos != '\0') {
507                 if (*pos != ';')
508                         break;
509
510                 pos++;
511         }
512
513         if (*pos != '\0')
514                 g_string_append_printf(string, ";%s", pos);
515 }
516
517 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
518                                                 const gchar *name,
519                                                 const gchar *param,
520                                                 const gchar *value)
521 {
522         GString *property = NULL;
523
524         if (name == NULL)
525                 return;
526
527         property = g_string_new(name);
528         __bluetooth_pb_vcard_append_param_v21(property, param);
529
530         if (__bluetooth_pb_vcard_qp_encode_check(value)) {
531                 gchar *enc = NULL;
532
533                 __bluetooth_pb_vcard_append_param_v21(property,
534                                 "CHARSET=UTF-8");
535                 __bluetooth_pb_vcard_append_param_v21(property,
536                                 "ENCODING=QUOTED-PRINTABLE");
537                 g_string_append(property, ":");
538
539                 enc = __bluetooth_pb_vcard_qp_encode(value);
540
541                 if (enc) {
542                         g_string_append(property, enc);
543                         g_free(enc);
544                 }
545         } else {
546                 g_string_append(property, ":");
547                 if (value)
548                         g_string_append(property , value);
549         }
550
551         g_string_append_printf(string, "%s\r\n", property->str);
552
553         g_string_free(property, TRUE);
554 }
555
556
557 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
558                                                         const gchar *name,
559                                                         const gchar *param,
560                                                         const gchar *value,
561                                                         gsize len,
562                                                         gboolean folding)
563 {
564         gchar *enc = NULL;
565
566         if (name == NULL)
567                 return;
568
569         g_string_append(string, name);
570
571         __bluetooth_pb_vcard_append_param_v21(string, param);
572         __bluetooth_pb_vcard_append_param_v21(string, "ENCODING=BASE64");
573
574         g_string_append(string, ":");
575
576         if (value == NULL)
577                 return;
578
579         enc = g_base64_encode((const guchar *)value, len);
580
581
582         if (folding == FALSE) {
583                 g_string_append(string, enc);
584         } else {
585                 gint enc_len = strlen(enc);
586                 gint i = 0;
587
588                 /* count ' ' size for folding */
589                 gint fline_len = LINEBREAK_LEN -1;
590
591                 for (i = 0; (i * fline_len) < enc_len; i++) {
592                         g_string_append(string, "\r\n ");
593                         if ((i * fline_len) + fline_len > enc_len)
594                                 g_string_append(string, enc + (i * fline_len));
595                         else
596                                 g_string_append_len(string, enc + (i * fline_len), fline_len);
597                 }
598
599                 /* some application requires more \r\n */
600                 g_string_append(string, "\r\n");
601         }
602         g_string_append(string, "\r\n");
603
604         g_free(enc);
605 }
606
607 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
608                                         contacts_record_h contact)
609 {
610         gchar *str;
611
612         str = __bluetooth_pb_name_from_contact(contact);
613         __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
614
615         g_free(str);
616 }
617
618 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
619                                                 contacts_record_h contact)
620 {
621         guint count = 0;
622
623         gint i;
624         gint status;
625
626         status = contacts_record_get_child_record_count(contact,
627                         _contacts_contact.number,
628                         &count);
629
630         if (status != CONTACTS_ERROR_NONE)
631                 return;
632
633         for (i = 0; i < count; i++) {
634                 contacts_record_h number = NULL;
635
636                 gchar **paramv = NULL;
637                 gchar *param = NULL;
638
639                 gchar *tel = NULL;
640                 gchar *escaped = NULL;
641
642                 status = contacts_record_get_child_record_at_p(contact,
643                                 _contacts_contact.number, i, &number);
644
645                 if (status != CONTACTS_ERROR_NONE)
646                         continue;
647
648                 status = contacts_record_get_str_p(number,
649                                 _contacts_number.number,
650                                 &tel);
651
652                 if (status != CONTACTS_ERROR_NONE)
653                         continue;
654
655                 escaped = __bluetooth_pb_vcard_escape(tel);
656
657                 paramv = __bluetooth_pb_contact_tel_param(number);
658                 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
659
660                 g_strfreev(paramv);
661
662                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param, escaped);
663
664                 g_free(escaped);
665                 g_free(param);
666         }
667 }
668
669 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
670                                         contacts_record_h person)
671 {
672         gint status;
673
674         gchar *fn = NULL;
675         gchar *tmp = NULL;
676
677         status = contacts_record_get_str_p(person,
678                         _contacts_person.display_name,
679                         &tmp);
680
681         if (status != CONTACTS_ERROR_NONE)
682                 return;
683
684         fn = __bluetooth_pb_vcard_escape(tmp);
685
686         __bluetooth_pb_vcard_append_qp_encode_v21(string, "FN", NULL, fn);
687
688         g_free(fn);
689 }
690
691 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
692                                                 contacts_record_h person)
693 {
694         gint status;
695
696         gsize len = 0;
697
698         gchar *filename = NULL;
699
700         gchar *type = NULL;
701         gchar *param = NULL;
702         gchar *contents = NULL;
703
704
705         status = contacts_record_get_str_p(person,
706                         _contacts_person.image_thumbnail_path,
707                         &filename);
708
709         if (status != CONTACTS_ERROR_NONE)
710                 return;
711
712         type = __bluetooth_pb_contact_photo_type(filename);
713
714         if (type) {
715                 param = g_strdup_printf("TYPE=%s", type);
716                 g_free(type);
717         }
718
719         if (g_file_get_contents(filename, &contents, &len, NULL) == FALSE) {
720                 ERR("can not read file contents:%s\n", filename);
721                 return;
722         }
723
724         __bluetooth_pb_vcard_append_base64_encode_v21(string,
725                         "PHOTO", param, contents, len, TRUE);
726
727         g_free(param);
728         g_free(contents);
729 }
730
731 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
732                                                 contacts_record_h contact)
733 {
734         guint count = 0;
735
736         gint status;
737         gint i;
738
739         status = contacts_record_get_child_record_count(contact,
740                         _contacts_contact.event, &count);
741
742         if (status != CONTACTS_ERROR_NONE)
743                 return;
744
745         for (i = 0; i < count; i++) {
746                 contacts_record_h event = NULL;
747
748                 gint date;
749
750                 gchar *bday;
751
752                 contacts_event_type_e type;
753
754                 status = contacts_record_get_child_record_at_p(contact,
755                                 _contacts_contact.event, i, &event);
756
757                 if (status != CONTACTS_ERROR_NONE)
758                         continue;
759
760                 status = contacts_record_get_int(event,
761                                 _contacts_event.type,
762                                 (gint *) &type);
763
764                 if (status != CONTACTS_ERROR_NONE)
765                         continue;
766
767                 if (type != CONTACTS_EVENT_TYPE_BIRTH)
768                         continue;
769
770                 status = contacts_record_get_int(event,
771                                 _contacts_event.date,
772                                 &date);
773
774                 if (status != CONTACTS_ERROR_NONE)
775                         continue;
776
777                 if (date <= 0)
778                         continue;
779
780                 bday = g_strdup_printf("%04d-%02d-%02d",
781                                 (date/10000), (date/100)%100, date%100);
782                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "BDAY",
783                                 NULL, bday);
784                 g_free(bday);
785         }
786 }
787
788 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
789                                                 contacts_record_h contact)
790 {
791         guint count = 0;
792
793         gint status;
794         gint i;
795
796         status = contacts_record_get_child_record_count(contact,
797                         _contacts_contact.address,
798                         &count);
799
800         if (status != CONTACTS_ERROR_NONE)
801                 return;
802
803         for (i = 0; i < count; i++) {
804                 contacts_record_h address = NULL;
805
806                 gchar **addrv;
807                 gchar **paramv;
808
809                 gchar *addr;
810                 gchar *param;
811
812                 status = contacts_record_get_child_record_at_p(contact,
813                                 _contacts_contact.address, i, &address);
814
815                 if (status != CONTACTS_ERROR_NONE)
816                         continue;
817
818                 addrv = __bluetooth_pb_contact_addr(address);
819
820                 if (addrv == NULL)
821                         continue;
822
823                 addr = __bluetooth_pb_vcard_strv_concat(addrv, ";");
824                 g_strfreev(addrv);
825
826                 paramv = __bluetooth_pb_contact_addr_param(address);
827                 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
828                 g_strfreev(paramv);
829
830                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
831                                 param, addr);
832
833                 g_free(param);
834                 g_free(addr);
835         }
836 }
837
838 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
839                                                 contacts_record_h contact)
840 {
841         guint count = 0;
842
843         gint status;
844         gint i;
845
846         status = contacts_record_get_child_record_count(contact,
847                         _contacts_contact.email,
848                         &count);
849
850         if (status != CONTACTS_ERROR_NONE)
851                 return;
852
853         for (i = 0; i < count; i++) {
854                 contacts_record_h email = NULL;
855
856                 gchar *tmp = NULL;
857                 gchar *escaped;
858
859                 status = contacts_record_get_child_record_at_p(contact,
860                                 _contacts_contact.email, i, &email);
861
862                 if (status != CONTACTS_ERROR_NONE)
863                         continue;
864
865                 status = contacts_record_get_str_p(email,
866                                 _contacts_email.email,
867                                 &tmp);
868
869                 if (status != CONTACTS_ERROR_NONE)
870                         continue;
871
872                 escaped = __bluetooth_pb_vcard_escape(tmp);
873                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL, escaped);
874
875                 g_free(escaped);
876         }
877 }
878
879 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
880                                                 contacts_record_h contact)
881 {
882         guint count = 0;
883
884         gint status;
885         gint i;
886
887         status = contacts_record_get_child_record_count(contact,
888                         _contacts_contact.company,
889                         &count);
890
891         if (status != CONTACTS_ERROR_NONE)
892                 return;
893
894         for (i = 0; i < count; i++) {
895                 contacts_record_h company = NULL;
896
897                 char *title = NULL;
898                 gchar *escaped;
899
900                 status = contacts_record_get_child_record_at_p(contact,
901                                 _contacts_contact.company,i, &company);
902
903                 if (status != CONTACTS_ERROR_NONE)
904                         continue;
905
906                 status = contacts_record_get_str_p(company,
907                                 _contacts_company.job_title,
908                                 &title);
909
910                 if (status != CONTACTS_ERROR_NONE)
911                         continue;
912
913                 escaped = __bluetooth_pb_vcard_escape(title);
914                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL, escaped);
915
916                 g_free(escaped);
917         }
918 }
919
920 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
921                                                 contacts_record_h contact)
922 {
923         guint count = 0;
924
925         gint status;
926         gint i;
927
928         status = contacts_record_get_child_record_count(contact,
929                         _contacts_contact.company,
930                         &count);
931
932         if (status != CONTACTS_ERROR_NONE)
933                 return;
934
935         for (i = 0; i < count; i++) {
936                 contacts_record_h company = NULL;
937
938                 char *role = NULL;
939                 gchar *escaped;
940
941                 status = contacts_record_get_child_record_at_p(contact,
942                                 _contacts_contact.company, i, &company);
943
944                 if (status != CONTACTS_ERROR_NONE)
945                         continue;
946
947                 status = contacts_record_get_str_p(company,
948                                 _contacts_company.role,
949                                 &role);
950
951                 if (status != CONTACTS_ERROR_NONE)
952                         continue;
953
954                 escaped = __bluetooth_pb_vcard_escape(role);
955                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL, escaped);
956
957                 g_free(escaped);
958         }
959 }
960
961 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
962                                                 contacts_record_h contact)
963 {
964         guint count = 0;
965
966         gint status;
967         gint i;
968
969         status = contacts_record_get_child_record_count(contact,
970                         _contacts_contact.company,
971                         &count);
972
973         if (status != CONTACTS_ERROR_NONE)
974                 return;
975
976         for (i = 0; i < count; i++) {
977                 contacts_record_h company = NULL;
978
979                 GString *str;
980
981                 gchar *name = NULL;
982                 gchar *department = NULL;
983
984                 gint name_status;
985                 gint department_status;
986
987                 status = contacts_record_get_child_record_at_p(contact,
988                                 _contacts_contact.company, i, &company);
989
990                 if (status != CONTACTS_ERROR_NONE)
991                         continue;
992
993
994                 name_status = contacts_record_get_str_p(company,
995                                 _contacts_company.name,
996                                 &name);
997
998                 department_status = contacts_record_get_str_p(company,
999                                 _contacts_company.department,
1000                                 &department);
1001
1002                 if ((name_status != CONTACTS_ERROR_NONE) &&
1003                                 (department_status != CONTACTS_ERROR_NONE))
1004                         continue;
1005
1006                 str = g_string_new(NULL);
1007
1008                 if (name) {
1009                         gchar *escaped;
1010
1011                         escaped = __bluetooth_pb_vcard_escape(name);
1012                         g_string_append(str, escaped);
1013                         g_free(escaped);
1014                 }
1015
1016                 g_string_append(str, ";");
1017
1018                 if (department) {
1019                         gchar *escaped;
1020
1021                         escaped = __bluetooth_pb_vcard_escape(department);
1022                         g_string_append(str, escaped);
1023                         g_free(escaped);
1024                 }
1025
1026                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL, str->str);
1027
1028                 g_string_free(str, TRUE);
1029
1030         }
1031 }
1032
1033 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
1034                                                 contacts_record_h contact)
1035 {
1036         guint count = 0;
1037
1038         gint status;
1039         gint i;
1040
1041         status = contacts_record_get_child_record_count(contact,
1042                         _contacts_contact.note,
1043                         &count);
1044
1045         if (status != CONTACTS_ERROR_NONE)
1046                 return;
1047
1048         for (i = 0; i < count; i++) {
1049                 contacts_record_h note = NULL;
1050
1051                 char *tmp = NULL;
1052                 gchar *escaped;
1053
1054                 status = contacts_record_get_child_record_at_p(contact,
1055                                 _contacts_contact.note, i, &note);
1056
1057                 if (status != CONTACTS_ERROR_NONE)
1058                         continue;
1059
1060                 status = contacts_record_get_str_p(note,
1061                                 _contacts_note.note,
1062                                 &tmp);
1063
1064                 if (status != CONTACTS_ERROR_NONE)
1065                         continue;
1066
1067                 escaped = __bluetooth_pb_vcard_escape(tmp);
1068                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL, escaped);
1069
1070                 g_free(escaped);
1071         }
1072 }
1073
1074 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
1075                                                 contacts_record_h contact)
1076 {
1077         gint time = 0;
1078         gint status;
1079
1080         gchar *rev;
1081         struct tm result;
1082
1083         status = contacts_record_get_int(contact,
1084                         _contacts_contact.changed_time,
1085                         &time);
1086
1087         if (status != CONTACTS_ERROR_NONE)
1088                 return;
1089
1090         if (time <= 0)
1091                 return;
1092
1093         gmtime_r((const time_t*)(&time), &result);
1094
1095         rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
1096                         (1900 + result.tm_year), (1 + result.tm_mon), result.tm_mday,
1097                         result.tm_hour, result.tm_min, result.tm_sec);
1098
1099         __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
1100
1101         g_free(rev);
1102 }
1103
1104 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
1105                                                 contacts_record_h contact)
1106 {
1107         guint count = 0;
1108
1109         gint i;
1110         gint status;
1111
1112         status = contacts_record_get_child_record_count(contact,
1113                         _contacts_contact.url,
1114                         &count);
1115
1116         if (status != CONTACTS_ERROR_NONE)
1117                 return;
1118
1119         for (i = 0; i < count; i++) {
1120                 contacts_record_h url = NULL;
1121
1122                 gchar *tmp = NULL;
1123                 gchar *escaped;
1124
1125                 status = contacts_record_get_child_record_at_p(contact,
1126                                 _contacts_contact.url, i, &url);
1127
1128                 if (status != CONTACTS_ERROR_NONE)
1129                         return;
1130
1131                 if (url == NULL)
1132                         continue;
1133
1134                 status = contacts_record_get_str_p(url,
1135                                 _contacts_url.url,
1136                                 &tmp);
1137
1138                 if (status != CONTACTS_ERROR_NONE)
1139                         continue;
1140
1141                 escaped = __bluetooth_pb_vcard_escape(tmp);
1142                 __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL, escaped);
1143
1144                 g_free(escaped);
1145         }
1146 }
1147
1148 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
1149                                                 contacts_record_h contact)
1150 {
1151         int status;
1152
1153         gchar *uid = NULL;
1154         gchar *escaped;
1155
1156         status = contacts_record_get_str_p(contact,
1157                         _contacts_contact.uid,
1158                         &uid);
1159
1160         if (status != CONTACTS_ERROR_NONE)
1161                 return;
1162
1163         escaped = __bluetooth_pb_vcard_escape(uid);
1164         __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
1165
1166         g_free(escaped);
1167 }
1168
1169 static void __bluetooth_pb_vcard_append_v30(GString *string,
1170                                         const gchar *name,
1171                                         const gchar *param,
1172                                         const gchar *value)
1173 {
1174         if (string == NULL)
1175                 return;
1176         if (name == NULL)
1177                 return;
1178
1179         g_string_append(string, name);
1180
1181         if (param)
1182                 g_string_append_printf(string, ";%s", param);
1183
1184         g_string_append(string, ":");
1185
1186         if (value)
1187                 g_string_append(string, value);
1188
1189         g_string_append(string, "\r\n");
1190 }
1191
1192 static void __bluetooth_pb_vcard_remove_v30(GString *string,
1193                                         const gchar *property_name)
1194 {
1195         gchar *pos = NULL;
1196         gchar *st_pos = NULL;
1197
1198         gboolean matched = FALSE;
1199
1200         if(string == NULL || property_name == NULL)
1201                 return;
1202
1203         pos = string->str;
1204
1205         while(*pos != '\0') {
1206                 if (matched == FALSE) {
1207                         if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1208                                 gint attrlen = 0;
1209
1210                                 st_pos = pos;
1211                                 pos += 2;
1212
1213                                 attrlen = strlen(property_name);
1214                                 if (g_ascii_strncasecmp(pos, property_name, attrlen) == 0) {
1215                                         pos += attrlen;
1216
1217                                         if (*pos == ':' || *pos == ';') {
1218                                                 matched = TRUE;
1219                                                 pos++;
1220                                         }
1221                                 }
1222                                 continue;
1223                         }
1224                 }
1225                 else {
1226                         if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1227                                 pos += 2;
1228
1229                                 if (*pos != ' ' && *pos != '\t') {
1230                                         /* +2 means move over \r\n */
1231                                         g_string_erase(string, (st_pos+2)-(string->str), pos-(st_pos +2));
1232                                         pos = st_pos;
1233                                         matched = FALSE;
1234                                 }
1235                                 continue;
1236                         }
1237                 }
1238
1239                 pos++;
1240         }
1241 }
1242
1243 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
1244                                         guint64 filter)
1245 {
1246         GString *string = NULL;
1247
1248         if (vcard == NULL)
1249                 return NULL;
1250
1251         string = g_string_new(vcard);
1252
1253         if ((filter & VCARD_PHOTO) == 0)
1254                 __bluetooth_pb_vcard_remove_v30(string, "PHOTO");
1255
1256         if ((filter & VCARD_BDAY) == 0)
1257                 __bluetooth_pb_vcard_remove_v30(string, "BDAY");
1258
1259         if ((filter & VCARD_ADR) == 0 )
1260                 __bluetooth_pb_vcard_remove_v30(string, "ADR");
1261
1262         if ((filter & VCARD_EMAIL) == 0 )
1263                 __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
1264
1265         if ((filter & VCARD_TITLE) == 0 )
1266                 __bluetooth_pb_vcard_remove_v30(string, "TITLE");
1267
1268         if ((filter & VCARD_ROLE) == 0 )
1269                 __bluetooth_pb_vcard_remove_v30(string, "ROLE");
1270
1271         if ((filter & VCARD_ORG) == 0 )
1272                 __bluetooth_pb_vcard_remove_v30(string, "ORG");
1273
1274         if ((filter & VCARD_NOTE) == 0 )
1275                 __bluetooth_pb_vcard_remove_v30(string, "NOTE");
1276
1277         if ((filter & VCARD_REV) == 0 )
1278                 __bluetooth_pb_vcard_remove_v30(string, "REV");
1279
1280         if ((filter & VCARD_URL) == 0 )
1281                 __bluetooth_pb_vcard_remove_v30(string, "URL");
1282
1283         if ((filter & VCARD_UID) == 0 )
1284                 __bluetooth_pb_vcard_remove_v30(string, "UID");
1285
1286         if ((filter & VCARD_NICKNAME) == 0 )
1287                 __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
1288
1289         return g_string_free(string, FALSE);
1290 }
1291
1292 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
1293                                                         gint phonelog_id,
1294                                                         guint64 filter,
1295                                                         const gchar *first_name,
1296                                                         va_list args)
1297 {
1298         contacts_record_h person = NULL;
1299         contacts_record_h contact = NULL;
1300
1301         GString *str = NULL;
1302
1303         gint contact_id = 0;
1304         gint status;
1305
1306         guint64 f = filter;
1307
1308         const gchar *name = first_name;
1309
1310         status = contacts_db_get_record(_contacts_person._uri,
1311                         person_id,
1312                         &person);
1313
1314         if (status != CONTACTS_ERROR_NONE)
1315                 return NULL;
1316
1317         status = contacts_record_get_int(person,
1318                         _contacts_person.display_contact_id,
1319                         &contact_id);
1320
1321         if (status != CONTACTS_ERROR_NONE)
1322                 return NULL;
1323
1324         status = contacts_db_get_record(_contacts_contact._uri,
1325                         contact_id,
1326                         &contact);
1327
1328         if (status != CONTACTS_ERROR_NONE) {
1329                 contacts_record_destroy(person, TRUE);
1330                 return NULL;;
1331         }
1332
1333         if (f == 0)
1334                 f = ~f;
1335
1336         str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1337
1338         /* N, TEL is default */
1339         __bluetooth_pb_vcard_append_n_v21(str, contact);
1340
1341         if (phonelog_id > 0) {
1342                 gchar *number;
1343
1344                 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1345                 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
1346                 g_free(number);
1347
1348
1349         } else {
1350                 __bluetooth_pb_vcard_append_tel_v21(str, contact);
1351         }
1352
1353         if (f & VCARD_FN)
1354                 __bluetooth_pb_vcard_append_fn_v21(str, person);
1355         if (f & VCARD_PHOTO)
1356                 __bluetooth_pb_vcard_append_photo_v21(str, person);
1357         if (f & VCARD_BDAY)
1358                 __bluetooth_pb_vcard_append_bday_v21(str, contact);
1359         if (f & VCARD_ADR)
1360                 __bluetooth_pb_vcard_append_adr_v21(str, contact);
1361         if (f & VCARD_EMAIL)
1362                 __bluetooth_pb_vcard_append_email_v21(str, contact);
1363         if (f & VCARD_TITLE)
1364                 __bluetooth_pb_vcard_append_title_v21(str, contact);
1365         if (f & VCARD_ROLE)
1366                 __bluetooth_pb_vcard_append_role_v21(str, contact);
1367         if (f & VCARD_ORG)
1368                 __bluetooth_pb_vcard_append_org_v21(str, contact);
1369         if (f & VCARD_NOTE)
1370                 __bluetooth_pb_vcard_append_note_v21(str, contact);
1371         if (f & VCARD_REV)
1372                 __bluetooth_pb_vcard_append_rev_v21(str, contact);
1373         if (f & VCARD_URL)
1374                 __bluetooth_pb_vcard_append_url_v21(str, contact);
1375         if (f & VCARD_UID)
1376                 __bluetooth_pb_vcard_append_uid_v21(str, contact);
1377
1378         while (name) {
1379                 const gchar *param = va_arg(args, const gchar *);
1380                 const gchar *value = va_arg(args, const gchar *);
1381
1382                 if (value) {
1383                         gchar *escaped = NULL;
1384
1385                         escaped = __bluetooth_pb_vcard_escape(value);
1386                         __bluetooth_pb_vcard_append_qp_encode_v21(str, name, param, escaped);
1387
1388                         g_free(escaped);
1389                 }
1390
1391                 name = va_arg(args, const gchar *);
1392         }
1393
1394         g_string_append(str, "END:VCARD\r\n");
1395
1396         contacts_record_destroy(contact, TRUE);
1397         contacts_record_destroy(person, TRUE);
1398
1399         return g_string_free(str, FALSE);
1400 }
1401
1402
1403 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
1404                                                         gint phonelog_id,
1405                                                         guint64 filter,
1406                                                         const gchar *first_name,
1407                                                         va_list args)
1408 {
1409         contacts_record_h person = NULL;
1410
1411         GString *str = NULL;
1412
1413         gint status;
1414
1415         const gchar *name = first_name;
1416         gchar *vcard = NULL;
1417
1418         status = contacts_db_get_record(_contacts_person._uri,
1419                         person_id,
1420                         &person);
1421
1422         if (status != CONTACTS_ERROR_NONE)
1423                 return NULL;
1424
1425         status = contacts_vcard_make_from_person(person, &vcard);
1426
1427         if (status != CONTACTS_ERROR_NONE)
1428                 return NULL;
1429
1430         status = contacts_record_destroy(person, TRUE);
1431
1432         if (status != CONTACTS_ERROR_NONE)
1433                 return NULL;
1434
1435         str = g_string_new(vcard);
1436         g_free(vcard);
1437
1438         /* append contents on vcard */
1439         while (name) {
1440                 const gchar *param = va_arg(args, const gchar *);
1441                 const gchar *value = va_arg(args, const gchar *);
1442
1443                 __bluetooth_pb_vcard_append_v30(str, name, param, value);
1444
1445                 name = va_arg(args, const gchar *);
1446         }
1447
1448         /* if phonelog_id exist,
1449            we shall show only the phone number, which was used for that phone log */
1450         if (phonelog_id > 0) {
1451                 gchar *number;
1452
1453                 __bluetooth_pb_vcard_remove_v30(str, "TEL");
1454
1455                 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1456                 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1457                 g_free(number);
1458         }
1459
1460         vcard = g_string_free(str, FALSE);
1461
1462         /* temporary fixed for some application crash */
1463         if (filter == 0)
1464                 filter = ~VCARD_NOTE;
1465
1466         if (filter) {
1467                 gchar *new_vcard = NULL;
1468
1469                 new_vcard = __bluetooth_pb_vcard_filter_v30(vcard, filter);
1470
1471                 if (new_vcard) {
1472                         g_free(vcard);
1473                         vcard = new_vcard;
1474                 }
1475         }
1476
1477         return vcard;
1478 }
1479
1480
1481 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
1482                                                                 gint phonelog_id,
1483                                                                 guint64 filter,
1484                                                                 guint8 format,
1485                                                                 const gchar *first_name,
1486                                                                 ...)
1487 {
1488         DBG("\n");
1489         gchar *vcard = NULL;
1490         va_list args;
1491
1492         va_start(args, first_name);
1493
1494         switch(format) {
1495         case VCARD_FORMAT_3_0:
1496                 vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
1497                                 phonelog_id, filter,
1498                                 first_name, args);
1499                 break;
1500         case VCARD_FORMAT_2_1:
1501         default:
1502                 vcard = __bluetooth_pb_vcard_real_contact_valist_v21(person_id,
1503                                 phonelog_id, filter,
1504                                 first_name, args);
1505                 break;
1506         }
1507
1508         va_end(args);
1509
1510         return vcard;
1511 }
1512
1513 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
1514                                                 guint filter,
1515                                                 const char *attr)
1516 {
1517         GString *str;
1518         gchar *number;
1519
1520         str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1521
1522         __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, NULL);
1523
1524         number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1525         __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
1526         g_free(number);
1527
1528         if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1529                         && attr) {
1530                 gchar *datetime = NULL;
1531
1532                 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1533                 __bluetooth_pb_vcard_append_qp_encode_v21(str, "X-IRMC-CALL-DATETIME",
1534                                 attr, datetime);
1535                 g_free(datetime);
1536         }
1537
1538         g_string_append(str, "END:VCARD\r\n");
1539
1540         return g_string_free(str, FALSE);
1541 }
1542
1543 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
1544                                                 guint filter,
1545                                                 const gchar *attr)
1546 {
1547         GString *str;
1548         gchar *number;
1549
1550         str = g_string_new("BEGIN:VCARD\r\nVERSION:3.0\r\n");
1551
1552         __bluetooth_pb_vcard_append_v30(str, "N", NULL, NULL);
1553         __bluetooth_pb_vcard_append_v30(str, "FN", NULL, NULL);
1554
1555         number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1556         __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1557         g_free(number);
1558
1559         if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1560                         && attr) {
1561                 gchar *datetime = NULL;
1562
1563                 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1564                 __bluetooth_pb_vcard_append_v30(str,
1565                                 "X-IRMC-CALL-DATETIME", attr, datetime);
1566                 g_free(datetime);
1567         }
1568
1569         g_string_append(str, "END:VCARD\r\n");
1570
1571         return g_string_free(str, FALSE);
1572 }
1573
1574 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
1575                                         guint filter,
1576                                         guint8 format,
1577                                         const gchar *attr)
1578 {
1579         DBG("\n");
1580         gchar *vcard = NULL;
1581
1582         switch(format) {
1583         case VCARD_FORMAT_3_0:
1584                 vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
1585                                 filter, attr);
1586                 break;
1587         case VCARD_FORMAT_2_1:
1588         default:
1589                 vcard = __bluetooth_pb_vcard_real_call_v21(phonelog_id,
1590                                 filter, attr);
1591                 break;
1592         }
1593
1594         return vcard;
1595 }
1596
1597 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
1598                                                 int *field,
1599                                                 gint field_size)
1600 {
1601         gchar **strv;
1602
1603         gint status;
1604         gint i;
1605
1606         gboolean valid = FALSE;
1607
1608         /* check empty field */
1609         for (i = 0; i < field_size; i++) {
1610                 gchar *tmp = NULL;
1611
1612                 status = contacts_record_get_str_p(record, field[i], &tmp);
1613
1614                 if (status != CONTACTS_ERROR_NONE)
1615                         continue;
1616
1617                 if (tmp) {
1618                         valid = TRUE;
1619                         break;
1620                 }
1621         }
1622
1623         if (valid == FALSE)
1624                 return NULL;
1625
1626         strv = g_new0(gchar *, field_size + 1);
1627
1628         for (i = 0; i < field_size; i++) {
1629                 gchar *tmp;
1630
1631                 status = contacts_record_get_str_p(record, field[i], &tmp);
1632
1633                 if (status != CONTACTS_ERROR_NONE)
1634                         continue;
1635
1636                 if (tmp == NULL)
1637                         strv[i] = g_strdup("");
1638                 else
1639                         strv[i] = __bluetooth_pb_vcard_escape(tmp);
1640         }
1641
1642         return strv;
1643 }
1644
1645 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
1646 {
1647         gchar **strv = NULL;
1648
1649         const gint TEL_PARAM_LEN = 13;
1650
1651         gint status;
1652         gint i = 0;
1653
1654         contacts_number_type_e type;
1655
1656         bool is_default = false;
1657
1658         strv = g_new0(char *, TEL_PARAM_LEN + 1);       /* tel param max size is 13 */
1659
1660         status = contacts_record_get_bool(number, _contacts_number.is_default,
1661                         &is_default);
1662
1663         if (status != CONTACTS_ERROR_NONE)
1664                 return NULL;
1665
1666         if (is_default) {
1667                 strv[i] = g_strdup("PREF");
1668                 i++;
1669         }
1670
1671         status = contacts_record_get_int(number,
1672                         _contacts_number.type,
1673                         (gint *)&type);
1674
1675         if (status != CONTACTS_ERROR_NONE)
1676                 return NULL;
1677
1678         if (type & CONTACTS_NUMBER_TYPE_HOME) {
1679                 strv[i] = g_strdup("HOME");
1680                 i++;
1681         }
1682
1683         if (type & CONTACTS_NUMBER_TYPE_WORK) {
1684                 strv[i] = g_strdup("WORK");
1685                 i++;
1686         }
1687
1688         if (type & CONTACTS_NUMBER_TYPE_VOICE) {
1689                 strv[i] = g_strdup("VOICE");
1690                 i++;
1691         }
1692
1693         if (type & CONTACTS_NUMBER_TYPE_FAX) {
1694                 strv[i] = g_strdup("FAX");
1695                 i++;
1696         }
1697
1698         if (type & CONTACTS_NUMBER_TYPE_MSG) {
1699                 strv[i] = g_strdup("MSG");
1700                 i++;
1701         }
1702
1703         if (type & CONTACTS_NUMBER_TYPE_CELL) {
1704                 strv[i] = g_strdup("CELL");
1705                 i++;
1706         }
1707
1708         if (type & CONTACTS_NUMBER_TYPE_PAGER) {
1709                 strv[i] = g_strdup("PAGER");
1710                 i++;
1711         }
1712
1713         if (type & CONTACTS_NUMBER_TYPE_BBS) {
1714                 strv[i] = g_strdup("BBS");
1715                 i++;
1716         }
1717
1718         if (type & CONTACTS_NUMBER_TYPE_MODEM) {
1719                 strv[i] = g_strdup("MODEM");
1720                 i++;
1721         }
1722
1723         if (type & CONTACTS_NUMBER_TYPE_CAR) {
1724                 strv[i] = g_strdup("CAR");
1725                 i++;
1726         }
1727
1728         if (type & CONTACTS_NUMBER_TYPE_ISDN) {
1729                 strv[i] = g_strdup("ISDN");
1730                 i++;
1731         }
1732
1733         if (type & CONTACTS_NUMBER_TYPE_VIDEO) {
1734                 strv[i] = g_strdup("VIDEO");
1735                 i++;
1736         }
1737
1738         /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
1739         return strv;
1740 }
1741
1742
1743 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
1744 {
1745         gchar *filetype = NULL;
1746         gchar *ext = NULL;
1747
1748         if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
1749                 ERR("file does not regular:%s\n", filename);
1750                 return NULL;
1751         }
1752
1753         ext = strrchr(filename, '.');
1754         if (ext == NULL) {
1755                 ERR("file doesn't have extension\n");
1756                 return NULL;
1757         }
1758
1759         ext++;
1760
1761         if (g_ascii_strcasecmp(ext, "gif") == 0)
1762                 filetype = "GIF";
1763         else if (g_ascii_strcasecmp(ext, "cgm") == 0)
1764                 filetype = "CGM";
1765         else if (g_ascii_strcasecmp(ext, "wmf") == 0)
1766                 filetype = "WMF";
1767         else if (g_ascii_strcasecmp(ext, "bmp") == 0)
1768                 filetype = "BMP";
1769         else if (g_ascii_strcasecmp(ext, "met") == 0)
1770                 filetype = "MET";
1771         else if (g_ascii_strcasecmp(ext, "dib") == 0)
1772                 filetype = "DIB";
1773         else if (g_ascii_strcasecmp(ext, "pict") == 0 || g_ascii_strcasecmp(ext, "pct") == 0 ||
1774                         g_ascii_strcasecmp(ext, "pic") == 0)
1775                 filetype = "PICT";
1776         else if (g_ascii_strcasecmp(ext, "tiff") == 0 || g_ascii_strcasecmp(ext, "tif") == 0)
1777                 filetype = "TIFF";
1778         else if (g_ascii_strcasecmp(ext, "ps") == 0)
1779                 filetype = "PS";
1780         else if (g_ascii_strcasecmp(ext, "pdf") == 0)
1781                 filetype = "PDF";
1782         else if (g_ascii_strcasecmp(ext, "jpeg") == 0 || g_ascii_strcasecmp(ext, "jpg") == 0 ||
1783                         g_ascii_strcasecmp(ext, "jpe") == 0)
1784                 filetype = "JPEG";
1785         else if (g_ascii_strcasecmp(ext, "mpeg") == 0 || g_ascii_strcasecmp(ext, "mpg") == 0)
1786                 filetype = "MPEG";
1787         else if (g_ascii_strcasecmp(ext, "m2v") == 0)
1788                 filetype = "MPEG2";
1789         else if (g_ascii_strcasecmp(ext, "avi") == 0)
1790                 filetype = "AVI";
1791         else if (g_ascii_strcasecmp(ext, "mov") == 0)
1792                 filetype = "QTIME";
1793         else if (g_ascii_strcasecmp(ext, "png") == 0)
1794                 filetype = "PNG";
1795
1796         return g_strdup(filetype);
1797 }
1798
1799 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
1800 {
1801         const gint ADDR_LEN = 7;
1802
1803         gchar **strv = NULL;
1804
1805         gint addr[] = { _contacts_address.postbox,
1806                         _contacts_address.extended,
1807                         _contacts_address.street,
1808                         _contacts_address.locality,
1809                         _contacts_address.region,
1810                         _contacts_address.postal_code,
1811                         _contacts_address.country };
1812
1813         strv = __bluetooth_pb_contact_add_field_str(address,
1814                         addr, ADDR_LEN);
1815         return strv;
1816 }
1817
1818 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
1819 {
1820
1821         contacts_address_type_e type;
1822
1823         gint status;
1824         gint i = 0;
1825
1826         gchar **strv = NULL;
1827
1828         strv = g_new0(gchar *, 7);      /* ADDR param max size is 6 */
1829
1830         status = contacts_record_get_int(address,
1831                         _contacts_address.type,
1832                         (gint *)&type);
1833
1834         if (status != CONTACTS_ERROR_NONE)
1835                 return NULL;
1836
1837         if (type & CONTACTS_ADDRESS_TYPE_HOME) {
1838                 strv[i] = g_strdup("HOME");
1839                 i++;
1840         }
1841         if (type & CONTACTS_ADDRESS_TYPE_WORK) {
1842                 strv[i] = g_strdup("WORK");
1843                 i++;
1844         }
1845         if (type & CONTACTS_ADDRESS_TYPE_DOM) {
1846                 strv[i] = g_strdup("DOM");
1847                 i++;
1848         }
1849         if (type & CONTACTS_ADDRESS_TYPE_INTL) {
1850                 strv[i] = g_strdup("INTL");
1851                 i++;
1852         }
1853         if (type & CONTACTS_ADDRESS_TYPE_POSTAL) {
1854                 strv[i] = g_strdup("POSTAL");
1855                 i++;
1856         }
1857         if (type & CONTACTS_ADDRESS_TYPE_PARCEL) {
1858                 strv[i] = g_strdup("PARCEL");
1859                 i++;
1860         }
1861         return strv;
1862 }
1863
1864 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
1865 {
1866         contacts_record_h phone_log;
1867
1868         char time_str[32] = {0,};
1869
1870         gint status;
1871         gint time = 0;
1872
1873         struct tm time_info;
1874
1875         status = contacts_db_get_record(_contacts_phone_log._uri,
1876                         phonelog_id,
1877                         &phone_log);
1878
1879         if (status != CONTACTS_ERROR_NONE)
1880                 return NULL;
1881
1882         status = contacts_record_get_int(phone_log,
1883                         _contacts_phone_log.log_time,
1884                         &time);
1885
1886         if (status != CONTACTS_ERROR_NONE)
1887                 return NULL;
1888
1889         if (time <= 0)
1890                 return NULL;
1891
1892         localtime_r((time_t *)&time, &time_info);
1893
1894         strftime(time_str, sizeof(time_str),
1895                         "%Y%m%dT%H%M%S", &time_info);
1896
1897         contacts_record_destroy(phone_log, TRUE);
1898
1899         return g_strdup(time_str);
1900 }
1901
1902 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
1903 {
1904         contacts_record_h name = NULL;
1905
1906         GString *str = g_string_new(NULL);
1907
1908         gint status;
1909         gint i;
1910
1911         gint name_size = 5;
1912         gint name_val[] = { _contacts_name.last,
1913                         _contacts_name.first,
1914                         _contacts_name.addition,
1915                         _contacts_name.prefix,
1916                         _contacts_name.suffix };
1917
1918
1919         status = contacts_record_get_child_record_at_p(contact,
1920                         _contacts_contact.name, 0, &name);
1921
1922         if (status != CONTACTS_ERROR_NONE)
1923                 return NULL;
1924
1925         for (i = 0; i < name_size; i++) {
1926                 gchar *tmp = NULL;
1927                 gchar *escape = NULL;
1928
1929                 if (i > 0)
1930                         g_string_append_c(str, ';');
1931
1932                 status = contacts_record_get_str_p(name, name_val[i], &tmp);
1933
1934                 if (status != CONTACTS_ERROR_NONE)
1935                         continue;
1936
1937                 escape = __bluetooth_pb_vcard_escape(tmp);
1938                 g_string_append(str, escape);
1939
1940                 g_free(escape);
1941         }
1942
1943         return g_string_free(str, FALSE);
1944 }
1945
1946 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
1947 {
1948         guint count = 0;
1949
1950         gint status;
1951         gint i;
1952
1953         gchar *str = NULL;
1954
1955         status = contacts_record_get_child_record_count(contact,
1956                         _contacts_contact.number,
1957                         &count);
1958
1959         if (status != CONTACTS_ERROR_NONE)
1960                 return NULL;
1961
1962         for (i = 0; i < count; i++) {
1963                 contacts_record_h number = NULL;
1964
1965                 gchar *tmp = NULL;
1966
1967                 bool is_default = false;
1968
1969                 status = contacts_record_get_child_record_at_p(contact,
1970                                 _contacts_contact.number, i, &number);
1971
1972                 if (status != CONTACTS_ERROR_NONE)
1973                         continue;
1974
1975                 status = contacts_record_get_bool(number,
1976                                 _contacts_number.is_default,
1977                                 &is_default);
1978
1979                 if (status != CONTACTS_ERROR_NONE)
1980                         continue;
1981
1982                 if (is_default == FALSE)
1983                         continue;
1984
1985                 status = contacts_record_get_str_p(number,
1986                                 _contacts_number.number,
1987                                 &tmp);
1988
1989                 if (status != CONTACTS_ERROR_NONE)
1990                         continue;
1991
1992                 if (tmp) {
1993                         str = g_strdup(tmp);
1994                         break;
1995                 }
1996         }
1997
1998         /* get first number */
1999         if (str == NULL) {
2000                 gchar *tmp = NULL;
2001
2002                 contacts_record_h number = NULL;
2003
2004                 status = contacts_record_get_child_record_at_p(contact,
2005                                 _contacts_contact.number, 0, &number);
2006
2007                 if (status != CONTACTS_ERROR_NONE)
2008                         return NULL;
2009
2010                 status = contacts_record_get_str_p(number,
2011                                 _contacts_number.number,
2012                                 &tmp);
2013
2014                 if (status != CONTACTS_ERROR_NONE)
2015                         return NULL;
2016
2017                 str = g_strdup(tmp);
2018         }
2019
2020         return str;
2021 }
2022
2023 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
2024 {
2025         contacts_query_h query = NULL;
2026         contacts_filter_h filter = NULL;
2027         contacts_list_h record_list = NULL;
2028
2029         contacts_record_h phone_log = NULL;
2030         contacts_record_h record = NULL;
2031
2032         gint status;
2033         gint person_id = 0;
2034
2035         status = contacts_db_get_record(_contacts_phone_log._uri,
2036                         phonelog_id,
2037                         &phone_log);
2038
2039         if (status != CONTACTS_ERROR_NONE)
2040                 return 0;
2041
2042         status = contacts_record_get_int(phone_log,
2043                         _contacts_phone_log.person_id,
2044                         &person_id);
2045
2046         if (status != CONTACTS_ERROR_NONE) {
2047                 contacts_record_destroy(phone_log, TRUE);
2048                 return 0;
2049         }
2050
2051         contacts_record_destroy(phone_log, TRUE);
2052
2053         if (person_id)
2054                 return person_id;
2055
2056         status = contacts_filter_create(_contacts_person_phone_log._uri,
2057                         &filter);
2058
2059         if (status != CONTACTS_ERROR_NONE)
2060                 return 0;
2061
2062
2063         status = contacts_filter_add_int(filter,
2064                         _contacts_person_phone_log.log_id,
2065                         CONTACTS_MATCH_EQUAL,
2066                         phonelog_id);
2067
2068         if (status != CONTACTS_ERROR_NONE)
2069                 goto done;
2070
2071         status = contacts_query_create(_contacts_person_phone_log._uri, &query);
2072
2073         if (status != CONTACTS_ERROR_NONE)
2074                 goto done;
2075
2076         status = contacts_query_set_filter(query, filter);
2077
2078         if (status != CONTACTS_ERROR_NONE)
2079                 goto done;
2080
2081         status = contacts_db_get_records_with_query(query, -1, -1, &record_list);
2082
2083         if (status != CONTACTS_ERROR_NONE)
2084                 goto done;
2085
2086         status = contacts_list_first(record_list);
2087
2088         if (status != CONTACTS_ERROR_NONE)
2089                 goto done;
2090
2091         status = contacts_list_get_current_record_p(record_list, &record);
2092
2093         if (status != CONTACTS_ERROR_NONE)
2094                 goto done;
2095
2096         status = contacts_record_get_int(record,
2097                         _contacts_person_phone_log.person_id,
2098                         &person_id);
2099
2100         if (status != CONTACTS_ERROR_NONE)
2101                 goto done;
2102
2103 done:
2104         if (record_list != NULL)
2105                 contacts_list_destroy(record_list, TRUE);
2106
2107         contacts_filter_destroy(filter);
2108
2109         if (query != NULL)
2110                 contacts_query_destroy(query);
2111
2112         return person_id;
2113 }
2114
2115 /* API for vcard */
2116 gchar *_bluetooth_pb_vcard_contact(gint person_id,
2117                                 guint64 filter,
2118                                 guint8 format)
2119 {
2120         gchar *str = NULL;
2121
2122         if (person_id <= 0)
2123                 return NULL;
2124
2125         str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
2126                         filter, format,
2127                         NULL);
2128         return str;
2129 }
2130
2131 gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
2132                                         guint64 filter,
2133                                         guint8 format)
2134 {
2135         GString *str = g_string_new("BEGIN:VCARD\r\n");
2136         gchar *fn;
2137         gchar *name;
2138
2139         fn = _bluetooth_pb_owner_name();
2140         name = g_strdup_printf("%s;;;;", fn);
2141
2142         switch (format) {
2143         case VCARD_FORMAT_3_0:
2144                 g_string_append(str, "VERSION:3.0\r\n");
2145
2146                 __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
2147                 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
2148                 __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL", number);
2149                 break;
2150         case VCARD_FORMAT_2_1:
2151         default :
2152                 g_string_append(str, "VERSION:2.1\r\n");
2153
2154                 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
2155
2156                 if (filter == 0 || (filter & VCARD_FN))
2157                         __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN", NULL, fn);
2158
2159                 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL", number);
2160                 break;
2161
2162         }
2163
2164         g_string_append(str, "END:VCARD\r\n");
2165
2166         g_free(fn);
2167         g_free(name);
2168
2169         return g_string_free(str, FALSE);
2170 }
2171
2172 gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
2173                                 guint64 filter,
2174                                 guint8 format,
2175                                 const gchar *attr)
2176 {
2177         gint person_id = 0;
2178
2179         gchar *str = NULL;
2180
2181         if (attr == NULL) {
2182                 DBG("Unknown attribute type ignored\n");
2183                 return NULL;
2184         }
2185
2186         person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2187
2188         DBG("person_id %d\n", person_id);
2189
2190         if (person_id) {
2191                 if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
2192                         gchar *datetime = NULL;
2193
2194                         datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
2195
2196                         str = __bluetooth_pb_vcard_real_contact_with_properties(person_id,
2197                                         phonelog_id,
2198                                         filter, format,
2199                                         "X-IRMC-CALL-DATETIME", attr, datetime,
2200                                         NULL);
2201
2202                         if(datetime)
2203                                 g_free(datetime);
2204                 }
2205                 else {
2206                         str = __bluetooth_pb_vcard_real_contact_with_properties(person_id,
2207                                         phonelog_id,
2208                                         filter, format,
2209                                         NULL);
2210                 }
2211         }
2212         else
2213                 str = __bluetooth_pb_vcard_real_call(phonelog_id, filter, format, attr);
2214
2215         return str;
2216 }
2217
2218 gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
2219 {
2220         contacts_record_h person = NULL;
2221
2222         gint status;
2223
2224         gchar *str = NULL;
2225
2226         status = contacts_db_get_record(_contacts_person._uri,
2227                         person_id,
2228                         &person);
2229
2230         if (status != CONTACTS_ERROR_NONE)
2231                 return NULL;
2232
2233         status = contacts_record_get_str(person,
2234                         _contacts_person.display_name,
2235                         &str);
2236
2237         if (status != CONTACTS_ERROR_NONE)
2238                 return NULL;
2239
2240         contacts_record_destroy(person, TRUE);
2241
2242         return str;
2243 }
2244
2245 gchar *_bluetooth_pb_name_from_person_id(gint person_id)
2246 {
2247         contacts_record_h person = NULL;
2248         contacts_record_h contact = NULL;
2249
2250         gint status;
2251         gint contact_id = 0;
2252
2253         gchar *str;
2254
2255         status = contacts_db_get_record(_contacts_person._uri,
2256                         person_id,
2257                         &person);
2258
2259         if (status != CONTACTS_ERROR_NONE)
2260                 return NULL;
2261
2262         status = contacts_record_get_int(person,
2263                         _contacts_person.display_contact_id,
2264                         &contact_id);
2265
2266         if (status != CONTACTS_ERROR_NONE) {
2267                 contacts_record_destroy(person, TRUE);
2268                 return NULL;
2269         }
2270
2271         contacts_db_get_record(_contacts_contact._uri,
2272                         contact_id,
2273                         &contact);
2274
2275         if (status != CONTACTS_ERROR_NONE) {
2276                 contacts_record_destroy(person, TRUE);
2277                 return NULL;
2278         }
2279
2280         str = __bluetooth_pb_name_from_contact(contact);
2281
2282         contacts_record_destroy(contact, TRUE);
2283         contacts_record_destroy(person, TRUE);
2284
2285         return str;
2286 }
2287
2288 gchar *_bluetooth_pb_number_from_person_id(gint person_id)
2289 {
2290         contacts_record_h person = NULL;
2291         contacts_record_h contact = NULL;
2292
2293         gint status;
2294         gint contact_id = 0;
2295
2296         gchar *str;
2297
2298         status = contacts_db_get_record(_contacts_person._uri,
2299                         person_id,
2300                         &person);
2301
2302         if (status != CONTACTS_ERROR_NONE)
2303                 return NULL;
2304
2305
2306         status = contacts_record_get_int(person,
2307                         _contacts_person.display_contact_id,
2308                         &contact_id);
2309
2310         if (status != CONTACTS_ERROR_NONE) {
2311                 contacts_record_destroy(person, TRUE);
2312                 return NULL;
2313         }
2314
2315         status = contacts_db_get_record(_contacts_contact._uri,
2316                         contact_id,
2317                         &contact);
2318
2319         if (status != CONTACTS_ERROR_NONE) {
2320                 contacts_record_destroy(person, TRUE);
2321                 return NULL;
2322         }
2323
2324         str = __bluetooth_pb_number_from_contact(contact);
2325
2326         contacts_record_destroy(contact, TRUE);
2327         contacts_record_destroy(person, TRUE);
2328
2329         return str;
2330 }
2331
2332 gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
2333 {
2334         gint person_id = 0;
2335         gchar *str = NULL;
2336
2337         person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2338
2339         if (person_id > 0)
2340                 str = _bluetooth_pb_fn_from_person_id(person_id);
2341         else
2342                 str = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
2343
2344         return str;
2345 }
2346
2347 gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
2348 {
2349         gint person_id = 0;
2350         gchar *str = NULL;
2351
2352         person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2353
2354         if (person_id > 0)
2355                 str = _bluetooth_pb_name_from_person_id(person_id);
2356         else {
2357                 gchar *tmp;
2358
2359                 tmp = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
2360                 str = g_strdup_printf("%s;;;;", tmp);
2361
2362                 g_free(tmp);
2363         }
2364
2365         return str;
2366 }
2367
2368 gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
2369 {
2370         contacts_record_h phone_log;
2371
2372         gint status;
2373
2374         gchar *str;
2375         gchar *tmp = NULL;
2376
2377         status = contacts_db_get_record(_contacts_phone_log._uri,
2378                         phonelog_id, &phone_log);
2379
2380         if (status != CONTACTS_ERROR_NONE)
2381                 return NULL;
2382
2383         contacts_record_get_str_p(phone_log,
2384                         _contacts_phone_log.address,
2385                         &tmp);
2386
2387         if (status != CONTACTS_ERROR_NONE) {
2388                 contacts_record_destroy(phone_log, TRUE);
2389                 return NULL;
2390         }
2391
2392         str = g_strdup(tmp);
2393
2394         contacts_record_destroy(phone_log, TRUE);
2395
2396         return str;
2397 }
2398
2399 gchar *_bluetooth_pb_owner_name(void)
2400 {
2401         gchar *name;
2402
2403         name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
2404
2405         if (name == NULL)
2406                 name = g_strdup("My Name");
2407
2408         return name;
2409 }