4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
9 * Jaekyun Lee <jkyun.lee@samsung.com>
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
30 #include <dbus/dbus-glib.h>
37 #include <image_util.h>
38 //#include <image_util_product.h>
39 #include <libexif/exif-data.h>
42 #include "bluetooth_pb_vcard.h"
43 #include "bluetooth_pb_agent.h"
45 #define VCARD_FORMAT_2_1 0x0
46 #define VCARD_FORMAT_3_0 0x1
48 #define VCARD_VERSION (0x1)
49 #define VCARD_FN (0x1 << 1)
50 #define VCARD_N (0x1 << 2)
51 #define VCARD_PHOTO (0x1 << 3)
52 #define VCARD_BDAY (0x1 << 4)
53 #define VCARD_ADR (0x1 << 5)
54 #define VCARD_LABEL (0x1 << 6) /* not supported */
55 #define VCARD_TEL (0x1 << 7)
56 #define VCARD_EMAIL (0x1 << 8)
57 #define VCARD_MAILER (0x1 << 9) /* not supported */
58 #define VCARD_TZ (0x1 << 10) /* not supported */
59 #define VCARD_GEO (0x1 << 11) /* not supported */
60 #define VCARD_TITLE (0x1 << 12)
61 #define VCARD_ROLE (0x1 << 13)
62 #define VCARD_LOGO (0x1 << 14) /* not supported */
63 #define VCARD_AGENT (0x1 << 15) /* not supported */
64 #define VCARD_ORG (0x1 << 16)
65 #define VCARD_NOTE (0x1 << 17)
66 #define VCARD_REV (0x1 << 18)
67 #define VCARD_SOUND (0x1 << 19) /* not supported */
68 #define VCARD_URL (0x1 << 20)
69 #define VCARD_UID (0x1 << 21)
70 #define VCARD_KEY (0x1 << 22) /* not supported */
71 #define VCARD_NICKNAME (0x1 << 23)
72 #define VCARD_CATEGORIES (0x1 << 24) /* not supported */
73 #define VCARD_PROID (0x1 << 25) /* not supported */
74 #define VCARD_CLASS (0x1 << 26) /* not supported */
75 #define VCARD_SORT_STRING (0x1 << 27) /* not supported */
76 #define VCARD_X_IRMC_CALL_DATETIME (0x1 << 28)
79 #define LINEBREAK_LEN 75
85 contacts_record_h person;
89 gchar dest_thumb_path[255];
90 #define PBAP_IMAGE_THUMB_SIZE 48
91 #define PBAP_THMB_PATH "_thumb"
92 #define PBAP_THUMB_FILE_SIZE 4096
93 #define PBAP_IMAGE_ENCODE_QUALITY 90
94 #define PBAP_SECURITY_FILE_GROUP 6005
95 #define PBAP_SECURITY_DEFAULT_PERMISSION 0660
96 #define PBAP_SECURITY_DIR_DEFAULT_PERMISSION 0770
97 #define PBAP_SECURITY_IMAGE_PERMISSION 0440
99 static gchar *__bluetooth_pb_vcard_escape(const gchar *str);
101 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
102 const gchar *delimeter);
104 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str);
106 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
109 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
114 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
118 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
123 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str);
125 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
128 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
133 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
140 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
141 contacts_record_h contact);
143 static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
144 contacts_record_h contact);
146 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
147 contacts_record_h conatct);
149 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
150 contacts_record_h person);
152 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
153 contacts_record_h person);
155 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
156 contacts_record_h contact);
158 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
159 contacts_record_h contact);
161 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
162 contacts_record_h contact);
164 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
165 contacts_record_h contact);
167 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
168 contacts_record_h contact);
170 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
171 contacts_record_h contact);
173 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
174 contacts_record_h contact);
176 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
177 contacts_record_h contact);
179 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
180 contacts_record_h contact);
182 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
183 contacts_record_h contact);
185 static void __bluetooth_pb_vcard_append_v30(GString *string,
190 static void __bluetooth_pb_vcard_remove_v30(GString *string,
191 const gchar *property_name);
193 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
196 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
199 const gchar *first_name,
202 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
205 const gchar *first_name,
208 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
212 const gchar *first_name,
215 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
219 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
223 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
228 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
232 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number);
234 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename);
236 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address);
238 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address);
240 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id);
242 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
244 static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact);
246 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
248 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
251 static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
262 escaped = g_string_new(NULL);
267 while (*pos != '\0') {
269 g_string_append_len(escaped, st, (pos - st));
270 g_string_append(escaped, "\\;");
279 g_string_append_len(escaped, st, (pos - st));
281 return g_string_free(escaped, FALSE);
284 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
285 const gchar *separator)
288 GString *string = g_string_new(NULL);
291 for (i = 0; strv[i] != NULL; i++) {
293 g_string_append(string, ";");
295 g_string_append(string, strv[i]);
299 return g_string_free(string, FALSE);
302 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
311 while (*pos != '\0') {
312 /* ascii code ' ' : 32, '~' : 126 */
313 if ((guchar)*pos < ' ' || (guchar)*pos > '~')
322 /* get string length, which convert to quoted-printable encoding */
323 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
335 if (strlen(str) < len)
340 while (*pos != '\0' && (((pos - str) < length) || length < 0)) {
341 if ((guchar)*pos == '\t') {
347 if ((guchar)*pos < ' ' || (guchar)*pos == '=') {
353 /* check no-ascii utf-8 character */
354 if ((guchar)*pos > '~') {
358 next = g_utf8_next_char(pos);
360 count += QP_ENC_LEN * (next - pos);
373 /* convert to quoted printable code */
374 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
382 if (str == NULL || len == 0)
385 /* add soft linebreak when it exceed */
386 if ((*line_pos + (QP_ENC_LEN * len) > LINEBREAK_LEN)) {
387 g_string_append(string, "=\r\n");
391 for (i = 0; i < len; i++) {
392 g_string_append_printf(string, "=%02X", (guchar)*(str+i));
393 *line_pos += QP_ENC_LEN;
398 /* append plain visiable ascii character */
399 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
404 /* add soft linebreak when it exceed */
405 if (*line_pos + 1 > LINEBREAK_LEN) {
406 g_string_append(string, "=\r\n");
409 g_string_append_c(string, ch);
414 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
427 encode_len = __bluetooth_pb_vcard_qp_encode_strlen(str, len);
429 /* add soft linebreak when it exceed */
430 if (((*line_pos + encode_len) > LINEBREAK_LEN) && (*line_pos > 1)) {
431 g_string_append(string, "=\r\n");
438 pos = ((gchar *)str) + i;
440 /* converts invisiable character and escape character '='
441 to quoted-printable */
442 if ((guchar)*pos != '\t' &&
443 ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
444 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
451 /* converts non-ascii utf-8 character to quoted-printable */
452 if ((guchar)*pos > '~') {
456 next = g_utf8_next_char(pos);
459 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
460 pos, ch_len, line_pos);
466 __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos,
473 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str)
486 enc = g_string_new(NULL);
488 st_pos = (gchar *)str;
491 while (*pos != '\0') {
492 /* split string with given delimeter ' ' or '\t' */
493 if (*pos == ' ' || *pos == '\t') {
494 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
495 (pos - st_pos), &line_pos);
503 /* split string with given delimeter '\r', '\n' or
505 if (*pos == '\r' || *pos == '\n') {
506 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
507 (pos - st_pos), &line_pos);
509 /* converts newline to qp_encode with soft linebreak
510 for example, converts \r\n to =0D=0A=\r\n */
511 __bluetooth_pb_vcard_qp_encode_append_to_hex(enc,
512 "\r\n", 2, &line_pos);
513 g_string_append(enc, "=\r\n ");
517 if (*pos == '\r' && *(pos + 1) == '\n')
530 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
531 (pos - st_pos), &line_pos);
534 return g_string_free(enc, FALSE);
537 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
546 pos = (gchar *)param;
548 /* trim ';' on first */
549 while (*pos != '\0') {
557 g_string_append_printf(string, ";%s", pos);
561 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
567 GString *property = NULL;
572 property = g_string_new(name);
573 __bluetooth_pb_vcard_append_param_v21(property, param);
575 if (__bluetooth_pb_vcard_qp_encode_check(value)) {
578 __bluetooth_pb_vcard_append_param_v21(property,
580 __bluetooth_pb_vcard_append_param_v21(property,
581 "ENCODING=QUOTED-PRINTABLE");
582 g_string_append(property, ":");
584 enc = __bluetooth_pb_vcard_qp_encode(value);
587 g_string_append(property, enc);
591 g_string_append(property, ":");
593 g_string_append(property , value);
596 g_string_append_printf(string, "%s\r\n", property->str);
598 g_string_free(property, TRUE);
603 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
615 DBG("base 64 encoding\n");
617 g_string_append(string, name);
619 __bluetooth_pb_vcard_append_param_v21(string, param);
620 __bluetooth_pb_vcard_append_param_v21(string, "ENCODING=BASE64");
622 g_string_append(string, ":");
627 enc = g_base64_encode((const guchar *)value, len);
629 if (folding == FALSE) {
630 g_string_append(string, enc);
632 gint enc_len = strlen(enc);
635 /* count ' ' size for folding */
636 gint fline_len = LINEBREAK_LEN - 1;
638 for (i = 0; (i * fline_len) < enc_len; i++) {
639 g_string_append(string, "\r\n ");
640 if ((i * fline_len) + fline_len > enc_len)
641 g_string_append(string, enc + (i * fline_len));
643 g_string_append_len(string, enc +
644 (i * fline_len), fline_len);
647 /* some application requires more \r\n */
648 g_string_append(string, "\r\n");
650 g_string_append(string, "\r\n");
651 DBG("base 64 encoding\n");
657 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
658 contacts_record_h contact)
663 str = __bluetooth_pb_name_from_contact(contact);
664 __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
670 static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
671 contacts_record_h contact)
676 str = __bluetooth_pb_phonetic_name_from_contact(contact);
679 __bluetooth_pb_vcard_append_qp_encode_v21(string, "SOUND", "X-IRMC-N", str);
685 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
686 contacts_record_h contact)
694 status = contacts_record_get_child_record_count(contact,
695 _contacts_contact.number,
698 if (status != CONTACTS_ERROR_NONE)
701 for (i = 0; i < count; i++) {
702 contacts_record_h number = NULL;
704 gchar **paramv = NULL;
708 gchar *escaped = NULL;
710 status = contacts_record_get_child_record_at_p(contact,
711 _contacts_contact.number, i, &number);
713 if (status != CONTACTS_ERROR_NONE)
716 status = contacts_record_get_str_p(number,
717 _contacts_number.number,
720 if (status != CONTACTS_ERROR_NONE)
723 escaped = __bluetooth_pb_vcard_escape(tel);
725 paramv = __bluetooth_pb_contact_tel_param(number);
727 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
729 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param,
739 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
740 contacts_record_h person)
748 status = contacts_record_get_str_p(person,
749 _contacts_person.display_name,
752 if (status != CONTACTS_ERROR_NONE)
755 fn = __bluetooth_pb_vcard_escape(tmp);
757 __bluetooth_pb_vcard_append_qp_encode_v21(string, "FN", NULL, fn);
762 static image_util_rotation_e __bt_pbap_get_rotation_info(const char *path)
767 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
770 ed = exif_data_new_from_file(path);
772 ERR("exif_data_new_from_file : ExifData is NULL");
773 return IMAGE_UTIL_ROTATION_NONE;
776 entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
778 ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
779 orientation = (int)exif_get_short(entry->data, mByteOrder);
780 if (orientation < 0 || orientation > 8)
786 switch (orientation) {
787 case 1: /* Top-left */
788 rotation = IMAGE_UTIL_ROTATION_NONE;
790 case 2: /* Top-right */
791 rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
793 case 3: /* Bottom-right */
794 rotation = IMAGE_UTIL_ROTATION_180;
796 case 4: /* Bottom-left */
797 rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
799 case 6: /* Right-top */
800 rotation = IMAGE_UTIL_ROTATION_90;
802 case 8: /* Left-bottom */
803 rotation = IMAGE_UTIL_ROTATION_270;
805 case 5: /* Left-top */
806 case 7: /* Right-bottom */
817 static bool __bt_pbap_image_util_supported_jpeg_colorspace_cb(
818 image_util_colorspace_e colorspace, void *user_data)
821 unsigned char *img_target = 0;
822 unsigned char *img_source = 0;
825 gchar *contents = NULL;
828 int resized_width = 0;
829 int resized_height = 0;
831 unsigned int size_decode = 0;
832 image_util_rotation_e rotation;
833 image_util_error_e ret = 0;
836 bt_image_info_t *info = (bt_image_info_t *)user_data;
837 rotation = __bt_pbap_get_rotation_info(info->src);
838 ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width,
839 &height, &size_decode);
840 if (ret != IMAGE_UTIL_ERROR_NONE) {
841 ERR("Can not decode");
842 memset(info, 0x00, sizeof(bt_image_info_t));
846 DBG("decoding completed width = %d, height = %d, size = %d\n", width,
847 height, size_decode);
848 if (width > PBAP_IMAGE_THUMB_SIZE || height > PBAP_IMAGE_THUMB_SIZE) {
849 if (width <= 0 || height <= 0) {
851 ERR("image size error(%d)", PBAP_IMAGE_THUMB_SIZE);
852 memset(info, 0x00, sizeof(bt_image_info_t));
856 if (width > height) {
857 resized_width = PBAP_IMAGE_THUMB_SIZE ;
858 resized_height = height * PBAP_IMAGE_THUMB_SIZE / width;
860 resized_height = PBAP_IMAGE_THUMB_SIZE;
861 resized_width = width * PBAP_IMAGE_THUMB_SIZE / height;
864 if (resized_height % 8)
865 resized_height += 8 - (resized_height % 8);
866 if (resized_width % 8)
867 resized_width += 8 - (resized_width % 8);
869 DBG("original size[%d, %d] changed to resize[%d,%d]", width,
870 height, resized_width, resized_height);
872 ret = image_util_calculate_buffer_size(resized_width,
877 img_target = g_malloc0(size_decode);
880 ret = image_util_resize(img_target, &resized_width,
881 &resized_height, img_source, width,
883 if (ret != IMAGE_UTIL_ERROR_NONE) {
884 ERR("image_util_resize failed(%d)", ret);
887 memset(info, 0x00, sizeof(bt_image_info_t));
892 resized_width = width;
893 resized_height = height;
894 img_target = img_source;
896 DBG("Resized w = %d, ht = %d, size = %d\n", width, height, size_decode);
898 if (IMAGE_UTIL_ROTATION_NONE != rotation) {
899 int rotated_width, rotated_height;
900 unsigned char *img_rotate = 0;
901 img_rotate = g_malloc0(size_decode);
902 image_util_rotate(img_rotate, &rotated_width, &rotated_height,
903 rotation, img_target, resized_width,
904 resized_height, colorspace);
905 resized_width = rotated_width;
906 resized_height = rotated_height;
908 img_target = img_rotate;
912 ret = image_util_encode_jpeg(img_target, resized_width, resized_height,
913 colorspace, PBAP_IMAGE_ENCODE_QUALITY,
916 if (ret != IMAGE_UTIL_ERROR_NONE) {
917 ERR("image_util_encode_jpeg failed(%d)", ret);
918 info->ret = CONTACTS_ERROR_INTERNAL;
921 DBG("Encoding done\n");
923 dest_fd = open(info->dest, O_RDONLY);
925 ERR("System : Open Failed(%d)", errno);
926 ERR_SECURE("Open : dest path(%s)", info->dest);
930 ret = fchown(dest_fd, getuid(), PBAP_SECURITY_FILE_GROUP);
932 ERR("fchown Failed(%d)", errno);
933 DBG_SECURE("fchown : dest path(%s)", info->dest);
938 ret = fchmod(dest_fd, PBAP_SECURITY_IMAGE_PERMISSION);
940 ERR("fchmod Failed(%d)", errno);
941 ERR_SECURE("fchmod : dest path(%s)", info->dest);
947 info->ret = CONTACTS_ERROR_NONE;
948 type = __bluetooth_pb_contact_photo_type(info->dest);
949 DBG("Cintact image thumb type is = %s\n", type);
952 param = g_strdup_printf("TYPE=%s", type);
956 if (g_file_get_contents(info->dest, &contents, &len, NULL) == FALSE) {
957 ERR("can not read file contents:%s\n", info->dest);
961 __bluetooth_pb_vcard_append_base64_encode_v21(info->string,
962 "PHOTO", param, contents, len, TRUE);
968 memset(info, 0x00, sizeof(bt_image_info_t));
969 DBG("Cintact image thumb created successfuly\n");
974 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
975 contacts_record_h person)
979 gchar *filename = NULL;
981 bt_image_info_t img_info;
982 struct stat stat_info;
985 gchar *contents = NULL;
989 status = contacts_record_get_str_p(person,
990 _contacts_person.image_thumbnail_path,
993 if (status != CONTACTS_ERROR_NONE || NULL == filename)
996 stat_info.st_size = 0;
998 if (0 > stat(filename, &stat_info)) {
999 ERR("fstat failed, file does not exist %s", filename);
1002 if (PBAP_THUMB_FILE_SIZE > stat_info.st_size) {
1003 DBG_SECURE("File size small, so use thubnail %s\n", filename);
1005 type = __bluetooth_pb_contact_photo_type(filename);
1007 param = g_strdup_printf("TYPE=%s", type);
1011 if (g_file_get_contents(filename, &contents, &len, NULL) ==
1013 ERR("can not read file contents:%s\n", filename);
1017 DBG("Retrieved the contents of the file \n");
1018 __bluetooth_pb_vcard_append_base64_encode_v21(string,
1019 "PHOTO", param, contents, len, TRUE);
1026 ptr = strrchr(filename, '.');
1028 memset(dest_thumb_path, 0x00, sizeof(dest_thumb_path));
1029 g_strlcpy(dest_thumb_path, filename, ptr - filename);
1030 g_strlcat(dest_thumb_path, PBAP_THMB_PATH,
1031 sizeof(dest_thumb_path));
1032 g_strlcat(dest_thumb_path, ptr, sizeof(dest_thumb_path));
1033 DBG("Thumbnail path is = %s", dest_thumb_path);
1035 DBG_SECURE("filename = %s Thumbnail path is = %s", filename, dest_thumb_path);
1036 img_info.src = filename;
1037 img_info.dest = dest_thumb_path;
1038 img_info.ret = CONTACTS_ERROR_INTERNAL;
1039 img_info.person = person;
1040 img_info.string = string;
1042 res = image_util_foreach_supported_jpeg_colorspace(
1043 __bt_pbap_image_util_supported_jpeg_colorspace_cb, &img_info);
1044 if (res != IMAGE_UTIL_ERROR_NONE) {
1045 ERR("Image resizing is failed");
1050 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
1051 contacts_record_h contact)
1059 status = contacts_record_get_child_record_count(contact,
1060 _contacts_contact.event, &count);
1062 if (status != CONTACTS_ERROR_NONE)
1065 for (i = 0; i < count; i++) {
1066 contacts_record_h event = NULL;
1072 contacts_event_type_e type;
1074 status = contacts_record_get_child_record_at_p(contact,
1075 _contacts_contact.event, i, &event);
1077 if (status != CONTACTS_ERROR_NONE)
1080 status = contacts_record_get_int(event,
1081 _contacts_event.type,
1084 if (status != CONTACTS_ERROR_NONE)
1087 if (type != CONTACTS_EVENT_TYPE_BIRTH)
1090 status = contacts_record_get_int(event,
1091 _contacts_event.date,
1094 if (status != CONTACTS_ERROR_NONE)
1100 bday = g_strdup_printf("%04d-%02d-%02d",
1101 (date/10000), (date/100)%100, date%100);
1102 __bluetooth_pb_vcard_append_qp_encode_v21(string, "BDAY",
1109 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
1110 contacts_record_h contact)
1118 status = contacts_record_get_child_record_count(contact,
1119 _contacts_contact.address,
1122 if (status != CONTACTS_ERROR_NONE)
1125 for (i = 0; i < count; i++) {
1126 contacts_record_h address = NULL;
1134 status = contacts_record_get_child_record_at_p(contact,
1135 _contacts_contact.address, i, &address);
1137 if (status != CONTACTS_ERROR_NONE)
1140 addrv = __bluetooth_pb_contact_addr(address);
1145 addr = __bluetooth_pb_vcard_strv_concat(addrv, ";");
1148 paramv = __bluetooth_pb_contact_addr_param(address);
1150 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
1153 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
1163 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
1164 contacts_record_h contact)
1172 status = contacts_record_get_child_record_count(contact,
1173 _contacts_contact.email,
1176 if (status != CONTACTS_ERROR_NONE)
1179 for (i = 0; i < count; i++) {
1180 contacts_record_h email = NULL;
1185 status = contacts_record_get_child_record_at_p(contact,
1186 _contacts_contact.email, i, &email);
1188 if (status != CONTACTS_ERROR_NONE)
1191 status = contacts_record_get_str_p(email,
1192 _contacts_email.email,
1195 if (status != CONTACTS_ERROR_NONE)
1198 escaped = __bluetooth_pb_vcard_escape(tmp);
1199 __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL,
1207 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
1208 contacts_record_h contact)
1216 status = contacts_record_get_child_record_count(contact,
1217 _contacts_contact.company,
1220 if (status != CONTACTS_ERROR_NONE)
1223 for (i = 0; i < count; i++) {
1224 contacts_record_h company = NULL;
1229 status = contacts_record_get_child_record_at_p(contact,
1230 _contacts_contact.company, i, &company);
1232 if (status != CONTACTS_ERROR_NONE)
1235 status = contacts_record_get_str_p(company,
1236 _contacts_company.job_title,
1239 if (status != CONTACTS_ERROR_NONE)
1242 escaped = __bluetooth_pb_vcard_escape(title);
1243 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL,
1251 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
1252 contacts_record_h contact)
1260 status = contacts_record_get_child_record_count(contact,
1261 _contacts_contact.company,
1264 if (status != CONTACTS_ERROR_NONE)
1267 for (i = 0; i < count; i++) {
1268 contacts_record_h company = NULL;
1273 status = contacts_record_get_child_record_at_p(contact,
1274 _contacts_contact.company, i, &company);
1276 if (status != CONTACTS_ERROR_NONE)
1279 status = contacts_record_get_str_p(company,
1280 _contacts_company.role,
1283 if (status != CONTACTS_ERROR_NONE)
1286 escaped = __bluetooth_pb_vcard_escape(role);
1287 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL,
1295 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
1296 contacts_record_h contact)
1304 status = contacts_record_get_child_record_count(contact,
1305 _contacts_contact.company,
1308 if (status != CONTACTS_ERROR_NONE)
1311 for (i = 0; i < count; i++) {
1312 contacts_record_h company = NULL;
1317 gchar *department = NULL;
1320 gint department_status;
1322 status = contacts_record_get_child_record_at_p(contact,
1323 _contacts_contact.company, i, &company);
1325 if (status != CONTACTS_ERROR_NONE)
1329 name_status = contacts_record_get_str_p(company,
1330 _contacts_company.name,
1333 department_status = contacts_record_get_str_p(company,
1334 _contacts_company.department,
1337 if ((name_status != CONTACTS_ERROR_NONE) &&
1338 (department_status != CONTACTS_ERROR_NONE))
1341 str = g_string_new(NULL);
1346 escaped = __bluetooth_pb_vcard_escape(name);
1347 g_string_append(str, escaped);
1351 g_string_append(str, ";");
1356 escaped = __bluetooth_pb_vcard_escape(department);
1357 g_string_append(str, escaped);
1361 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL,
1364 g_string_free(str, TRUE);
1370 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
1371 contacts_record_h contact)
1379 status = contacts_record_get_child_record_count(contact,
1380 _contacts_contact.note,
1383 if (status != CONTACTS_ERROR_NONE)
1386 for (i = 0; i < count; i++) {
1387 contacts_record_h note = NULL;
1392 status = contacts_record_get_child_record_at_p(contact,
1393 _contacts_contact.note, i, ¬e);
1395 if (status != CONTACTS_ERROR_NONE)
1398 status = contacts_record_get_str_p(note,
1399 _contacts_note.note,
1402 if (status != CONTACTS_ERROR_NONE)
1405 escaped = __bluetooth_pb_vcard_escape(tmp);
1406 __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL,
1414 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
1415 contacts_record_h contact)
1424 status = contacts_record_get_int(contact,
1425 _contacts_contact.changed_time,
1428 if (status != CONTACTS_ERROR_NONE)
1434 gmtime_r((const time_t *)(&time), &result);
1436 rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
1437 (1900 + result.tm_year), (1 + result.tm_mon),
1438 result.tm_mday, result.tm_hour, result.tm_min,
1441 __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
1447 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
1448 contacts_record_h contact)
1456 status = contacts_record_get_child_record_count(contact,
1457 _contacts_contact.url,
1460 if (status != CONTACTS_ERROR_NONE)
1463 for (i = 0; i < count; i++) {
1464 contacts_record_h url = NULL;
1469 status = contacts_record_get_child_record_at_p(contact,
1470 _contacts_contact.url, i, &url);
1472 if (status != CONTACTS_ERROR_NONE)
1478 status = contacts_record_get_str_p(url,
1482 if (status != CONTACTS_ERROR_NONE)
1485 escaped = __bluetooth_pb_vcard_escape(tmp);
1486 __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL,
1494 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
1495 contacts_record_h contact)
1503 status = contacts_record_get_str_p(contact,
1504 _contacts_contact.uid,
1507 if (status != CONTACTS_ERROR_NONE)
1510 escaped = __bluetooth_pb_vcard_escape(uid);
1511 __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
1517 static void __bluetooth_pb_vcard_append_v30(GString *string,
1528 g_string_append(string, name);
1531 g_string_append_printf(string, ";%s", param);
1533 g_string_append(string, ":");
1536 g_string_append(string, value);
1538 g_string_append(string, "\r\n");
1542 static void __bluetooth_pb_vcard_remove_v30(GString *string,
1543 const gchar *property_name)
1547 gchar *st_pos = NULL;
1549 gboolean matched = FALSE;
1551 if (string == NULL || property_name == NULL)
1556 while (*pos != '\0') {
1557 if (matched == FALSE) {
1558 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1564 attrlen = strlen(property_name);
1565 if (g_ascii_strncasecmp(pos, property_name,
1569 if (*pos == ':' || *pos == ';') {
1577 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1580 if (*pos != ' ' && *pos != '\t') {
1581 /* +2 means move over \r\n */
1582 g_string_erase(string,
1583 (st_pos+2)-(string->str),
1598 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
1602 GString *string = NULL;
1607 string = g_string_new(vcard);
1609 if ((filter & VCARD_PHOTO) == 0)
1610 __bluetooth_pb_vcard_remove_v30(string, "PHOTO");
1612 if ((filter & VCARD_BDAY) == 0)
1613 __bluetooth_pb_vcard_remove_v30(string, "BDAY");
1615 if ((filter & VCARD_ADR) == 0)
1616 __bluetooth_pb_vcard_remove_v30(string, "ADR");
1618 if ((filter & VCARD_EMAIL) == 0)
1619 __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
1621 if ((filter & VCARD_TITLE) == 0)
1622 __bluetooth_pb_vcard_remove_v30(string, "TITLE");
1624 if ((filter & VCARD_ROLE) == 0)
1625 __bluetooth_pb_vcard_remove_v30(string, "ROLE");
1627 if ((filter & VCARD_ORG) == 0)
1628 __bluetooth_pb_vcard_remove_v30(string, "ORG");
1630 if ((filter & VCARD_NOTE) == 0)
1631 __bluetooth_pb_vcard_remove_v30(string, "NOTE");
1633 if ((filter & VCARD_REV) == 0)
1634 __bluetooth_pb_vcard_remove_v30(string, "REV");
1636 if ((filter & VCARD_URL) == 0)
1637 __bluetooth_pb_vcard_remove_v30(string, "URL");
1639 if ((filter & VCARD_UID) == 0)
1640 __bluetooth_pb_vcard_remove_v30(string, "UID");
1642 if ((filter & VCARD_NICKNAME) == 0)
1643 __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
1646 return g_string_free(string, FALSE);
1649 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
1652 const gchar *first_name,
1656 contacts_record_h person = NULL;
1657 contacts_record_h contact = NULL;
1659 GString *str = NULL;
1661 gint contact_id = 0;
1666 const gchar *name = first_name;
1668 status = contacts_db_get_record(_contacts_person._uri,
1672 if (status != CONTACTS_ERROR_NONE)
1675 status = contacts_record_get_int(person,
1676 _contacts_person.display_contact_id,
1679 if (status != CONTACTS_ERROR_NONE)
1682 status = contacts_db_get_record(_contacts_contact._uri,
1686 if (status != CONTACTS_ERROR_NONE) {
1687 contacts_record_destroy(person, TRUE);
1694 DBG("filter[%x]\n", filter);
1696 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1698 /* N, TEL is default */
1699 __bluetooth_pb_vcard_append_n_v21(str, contact);
1701 if (phonelog_id > 0) {
1704 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1705 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0",
1711 __bluetooth_pb_vcard_append_tel_v21(str, contact);
1715 __bluetooth_pb_vcard_append_fn_v21(str, person);
1716 /* Need to check filter
1717 if (f & VCARD_SOUND)*/
1718 __bluetooth_pb_vcard_append_phonetic_first_v21(str, contact);
1719 if (f & VCARD_PHOTO)
1720 __bluetooth_pb_vcard_append_photo_v21(str, person);
1722 __bluetooth_pb_vcard_append_bday_v21(str, contact);
1724 __bluetooth_pb_vcard_append_adr_v21(str, contact);
1725 if (f & VCARD_EMAIL)
1726 __bluetooth_pb_vcard_append_email_v21(str, contact);
1727 if (f & VCARD_TITLE)
1728 __bluetooth_pb_vcard_append_title_v21(str, contact);
1730 __bluetooth_pb_vcard_append_role_v21(str, contact);
1732 __bluetooth_pb_vcard_append_org_v21(str, contact);
1734 __bluetooth_pb_vcard_append_note_v21(str, contact);
1736 __bluetooth_pb_vcard_append_rev_v21(str, contact);
1738 __bluetooth_pb_vcard_append_url_v21(str, contact);
1740 __bluetooth_pb_vcard_append_uid_v21(str, contact);
1743 const gchar *param = va_arg(args, const gchar *);
1744 const gchar *value = va_arg(args, const gchar *);
1747 gchar *escaped = NULL;
1749 escaped = __bluetooth_pb_vcard_escape(value);
1750 __bluetooth_pb_vcard_append_qp_encode_v21(str, name,
1756 name = va_arg(args, const gchar *);
1759 g_string_append(str, "END:VCARD\r\n");
1761 contacts_record_destroy(contact, TRUE);
1762 contacts_record_destroy(person, TRUE);
1765 return g_string_free(str, FALSE);
1769 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
1772 const gchar *first_name,
1776 contacts_record_h person = NULL;
1778 GString *str = NULL;
1782 const gchar *name = first_name;
1783 gchar *vcard = NULL;
1785 status = contacts_db_get_record(_contacts_person._uri,
1789 if (status != CONTACTS_ERROR_NONE)
1792 status = contacts_vcard_make_from_person(person, &vcard);
1794 if (status != CONTACTS_ERROR_NONE)
1797 status = contacts_record_destroy(person, TRUE);
1799 if (status != CONTACTS_ERROR_NONE)
1802 /* removing the END:VCARD\r\n" to append extra data */
1803 str = g_string_new_len(vcard, (strlen(vcard)-11));
1806 /* append contents on vcard */
1808 const gchar *param = va_arg(args, const gchar *);
1809 const gchar *value = va_arg(args, const gchar *);
1811 __bluetooth_pb_vcard_append_v30(str, name, param, value);
1813 name = va_arg(args, const gchar *);
1816 /* if phonelog_id exist, we shall show only the phone number, which was
1817 used for that phone log */
1818 if (phonelog_id > 0) {
1821 __bluetooth_pb_vcard_remove_v30(str, "TEL");
1823 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1824 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1828 g_string_append(str, "END:VCARD\r\n");
1830 vcard = g_string_free(str, FALSE);
1832 /* temporary fixed for some application crash */
1834 filter = ~VCARD_NOTE;
1837 gchar *new_vcard = NULL;
1839 new_vcard = __bluetooth_pb_vcard_filter_v30(vcard, filter);
1852 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
1856 const gchar *first_name,
1860 DBG(" format [%d]\n", format);
1861 gchar *vcard = NULL;
1864 va_start(args, first_name);
1867 case VCARD_FORMAT_3_0:
1868 vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
1869 phonelog_id, filter,
1872 case VCARD_FORMAT_2_1:
1874 vcard = __bluetooth_pb_vcard_real_contact_valist_v21(person_id,
1875 phonelog_id, filter,
1886 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
1894 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1896 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, NULL);
1898 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1899 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
1902 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1904 gchar *datetime = NULL;
1906 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1907 __bluetooth_pb_vcard_append_qp_encode_v21(str,
1908 "X-IRMC-CALL-DATETIME",
1913 g_string_append(str, "END:VCARD\r\n");
1916 return g_string_free(str, FALSE);
1919 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
1927 str = g_string_new("BEGIN:VCARD\r\nVERSION:3.0\r\n");
1929 __bluetooth_pb_vcard_append_v30(str, "N", NULL, NULL);
1930 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, NULL);
1932 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1933 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1936 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1938 gchar *datetime = NULL;
1940 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1941 __bluetooth_pb_vcard_append_v30(str,
1942 "X-IRMC-CALL-DATETIME", attr, datetime);
1946 g_string_append(str, "END:VCARD\r\n");
1949 return g_string_free(str, FALSE);
1952 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
1958 gchar *vcard = NULL;
1961 case VCARD_FORMAT_3_0:
1962 vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
1965 case VCARD_FORMAT_2_1:
1967 vcard = __bluetooth_pb_vcard_real_call_v21(phonelog_id,
1976 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
1986 gboolean valid = FALSE;
1988 /* check empty field */
1989 for (i = 0; i < field_size; i++) {
1992 status = contacts_record_get_str_p(record, field[i], &tmp);
1994 if (status != CONTACTS_ERROR_NONE)
2006 strv = g_new0(gchar *, field_size + 1);
2008 for (i = 0; i < field_size; i++) {
2011 status = contacts_record_get_str_p(record, field[i], &tmp);
2013 if (status != CONTACTS_ERROR_NONE)
2017 strv[i] = g_strdup("");
2019 strv[i] = __bluetooth_pb_vcard_escape(tmp);
2026 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
2029 gchar **strv = NULL;
2031 const gint TEL_PARAM_LEN = 13;
2036 contacts_number_type_e type;
2038 bool is_default = false;
2040 status = contacts_record_get_bool(number, _contacts_number.is_default,
2043 if (status != CONTACTS_ERROR_NONE)
2046 strv = g_new0(char *, TEL_PARAM_LEN + 1);/* tel param max size is 13 */
2049 strv[i] = g_strdup("PREF");
2053 status = contacts_record_get_int(number,
2054 _contacts_number.type,
2057 if (status != CONTACTS_ERROR_NONE)
2063 if (type & CONTACTS_NUMBER_TYPE_HOME) {
2064 strv[i] = g_strdup("HOME");
2068 if (type & CONTACTS_NUMBER_TYPE_WORK) {
2069 strv[i] = g_strdup("WORK");
2073 if (type & CONTACTS_NUMBER_TYPE_VOICE) {
2074 strv[i] = g_strdup("VOICE");
2078 if (type & CONTACTS_NUMBER_TYPE_FAX) {
2079 strv[i] = g_strdup("FAX");
2083 if (type & CONTACTS_NUMBER_TYPE_MSG) {
2084 strv[i] = g_strdup("MSG");
2088 if (type & CONTACTS_NUMBER_TYPE_CELL) {
2089 strv[i] = g_strdup("CELL");
2093 if (type & CONTACTS_NUMBER_TYPE_PAGER) {
2094 strv[i] = g_strdup("PAGER");
2098 if (type & CONTACTS_NUMBER_TYPE_BBS) {
2099 strv[i] = g_strdup("BBS");
2103 if (type & CONTACTS_NUMBER_TYPE_MODEM) {
2104 strv[i] = g_strdup("MODEM");
2108 if (type & CONTACTS_NUMBER_TYPE_CAR) {
2109 strv[i] = g_strdup("CAR");
2113 if (type & CONTACTS_NUMBER_TYPE_ISDN) {
2114 strv[i] = g_strdup("ISDN");
2118 if (type & CONTACTS_NUMBER_TYPE_VIDEO) {
2119 strv[i] = g_strdup("VIDEO");
2123 /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
2129 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
2132 gchar *filetype = NULL;
2135 if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
2136 ERR_SECURE("file does not regular:%s\n", filename);
2140 ext = strrchr(filename, '.');
2142 ERR("file doesn't have extension\n");
2148 if (g_ascii_strcasecmp(ext, "gif") == 0)
2150 else if (g_ascii_strcasecmp(ext, "cgm") == 0)
2152 else if (g_ascii_strcasecmp(ext, "wmf") == 0)
2154 else if (g_ascii_strcasecmp(ext, "bmp") == 0)
2156 else if (g_ascii_strcasecmp(ext, "met") == 0)
2158 else if (g_ascii_strcasecmp(ext, "dib") == 0)
2160 else if (g_ascii_strcasecmp(ext, "pict") == 0 ||
2161 g_ascii_strcasecmp(ext, "pct") == 0 ||
2162 g_ascii_strcasecmp(ext, "pic") == 0)
2164 else if (g_ascii_strcasecmp(ext, "tiff") == 0 ||
2165 g_ascii_strcasecmp(ext, "tif") == 0)
2167 else if (g_ascii_strcasecmp(ext, "ps") == 0)
2169 else if (g_ascii_strcasecmp(ext, "pdf") == 0)
2171 else if (g_ascii_strcasecmp(ext, "jpeg") == 0 ||
2172 g_ascii_strcasecmp(ext, "jpg") == 0 ||
2173 g_ascii_strcasecmp(ext, "jpe") == 0)
2175 else if (g_ascii_strcasecmp(ext, "mpeg") == 0 ||
2176 g_ascii_strcasecmp(ext, "mpg") == 0)
2178 else if (g_ascii_strcasecmp(ext, "m2v") == 0)
2180 else if (g_ascii_strcasecmp(ext, "avi") == 0)
2182 else if (g_ascii_strcasecmp(ext, "mov") == 0)
2184 else if (g_ascii_strcasecmp(ext, "png") == 0)
2188 return g_strdup(filetype);
2191 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
2194 const gint ADDR_LEN = 7;
2196 gchar **strv = NULL;
2198 gint addr[] = { _contacts_address.postbox,
2199 _contacts_address.extended,
2200 _contacts_address.street,
2201 _contacts_address.locality,
2202 _contacts_address.region,
2203 _contacts_address.postal_code,
2204 _contacts_address.country };
2206 strv = __bluetooth_pb_contact_add_field_str(address,
2212 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
2215 contacts_address_type_e type;
2220 gchar **strv = NULL;
2222 status = contacts_record_get_int(address,
2223 _contacts_address.type,
2226 if (status != CONTACTS_ERROR_NONE)
2229 strv = g_new0(gchar *, 7); /* ADDR param max size is 6 */
2231 if (type & CONTACTS_ADDRESS_TYPE_HOME) {
2232 strv[i] = g_strdup("HOME");
2235 if (type & CONTACTS_ADDRESS_TYPE_WORK) {
2236 strv[i] = g_strdup("WORK");
2239 if (type & CONTACTS_ADDRESS_TYPE_DOM) {
2240 strv[i] = g_strdup("DOM");
2243 if (type & CONTACTS_ADDRESS_TYPE_INTL) {
2244 strv[i] = g_strdup("INTL");
2247 if (type & CONTACTS_ADDRESS_TYPE_POSTAL) {
2248 strv[i] = g_strdup("POSTAL");
2251 if (type & CONTACTS_ADDRESS_TYPE_PARCEL) {
2252 strv[i] = g_strdup("PARCEL");
2259 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
2262 contacts_record_h phone_log;
2264 char time_str[32] = {0,};
2269 struct tm time_info;
2271 status = contacts_db_get_record(_contacts_phone_log._uri,
2275 if (status != CONTACTS_ERROR_NONE)
2278 status = contacts_record_get_int(phone_log,
2279 _contacts_phone_log.log_time,
2282 if (status != CONTACTS_ERROR_NONE)
2288 localtime_r((time_t *)&time, &time_info);
2290 strftime(time_str, sizeof(time_str),
2291 "%Y%m%dT%H%M%S", &time_info);
2293 contacts_record_destroy(phone_log, TRUE);
2296 return g_strdup(time_str);
2299 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
2302 contacts_record_h name = NULL;
2304 GString *str = g_string_new(NULL);
2310 gint name_val[] = { _contacts_name.last,
2311 _contacts_name.first,
2312 _contacts_name.addition,
2313 _contacts_name.prefix,
2314 _contacts_name.suffix };
2317 status = contacts_record_get_child_record_at_p(contact,
2318 _contacts_contact.name, 0, &name);
2320 if (status != CONTACTS_ERROR_NONE)
2323 for (i = 0; i < name_size; i++) {
2325 gchar *escape = NULL;
2328 g_string_append_c(str, ';');
2330 status = contacts_record_get_str_p(name, name_val[i], &tmp);
2332 if (status != CONTACTS_ERROR_NONE)
2335 escape = __bluetooth_pb_vcard_escape(tmp);
2336 g_string_append(str, escape);
2342 return g_string_free(str, FALSE);
2345 static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact)
2348 contacts_record_h name = NULL;
2350 GString *str = g_string_new(NULL);
2354 gchar *phonetic_first = NULL;
2355 gchar *phonetic_last = NULL;
2356 gchar *escape = NULL;
2358 status = contacts_record_get_child_record_at_p(contact,
2359 _contacts_contact.name, 0, &name);
2361 if (status != CONTACTS_ERROR_NONE)
2364 status = contacts_record_get_str_p(name, _contacts_name.phonetic_first, &phonetic_first);
2366 if (status != CONTACTS_ERROR_NONE)
2369 if (phonetic_first == NULL)
2372 status = contacts_record_get_str_p(name, _contacts_name.phonetic_last, &phonetic_last);
2374 if ((status == CONTACTS_ERROR_NONE) && (phonetic_last != NULL)) {
2375 escape = __bluetooth_pb_vcard_escape(phonetic_last);
2376 g_string_append(str, escape);
2378 g_string_append_c(str, ' ');
2381 escape = __bluetooth_pb_vcard_escape(phonetic_first);
2382 g_string_append(str, escape);
2385 g_string_append_c(str, ';');
2386 g_string_append_c(str, ';');
2387 g_string_append_c(str, ';');
2388 g_string_append_c(str, ';');
2391 return g_string_free(str, FALSE);
2395 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
2405 status = contacts_record_get_child_record_count(contact,
2406 _contacts_contact.number,
2409 if (status != CONTACTS_ERROR_NONE)
2412 for (i = 0; i < count; i++) {
2413 contacts_record_h number = NULL;
2417 bool is_default = false;
2419 status = contacts_record_get_child_record_at_p(contact,
2420 _contacts_contact.number, i, &number);
2422 if (status != CONTACTS_ERROR_NONE)
2425 status = contacts_record_get_bool(number,
2426 _contacts_number.is_default,
2429 if (status != CONTACTS_ERROR_NONE)
2432 if (is_default == FALSE)
2435 status = contacts_record_get_str_p(number,
2436 _contacts_number.number,
2439 if (status != CONTACTS_ERROR_NONE)
2443 str = g_strdup(tmp);
2448 /* get first number */
2452 contacts_record_h number = NULL;
2454 status = contacts_record_get_child_record_at_p(contact,
2455 _contacts_contact.number, 0, &number);
2457 if (status != CONTACTS_ERROR_NONE)
2460 status = contacts_record_get_str_p(number,
2461 _contacts_number.number,
2464 if (status != CONTACTS_ERROR_NONE)
2467 str = g_strdup(tmp);
2474 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
2477 contacts_query_h query = NULL;
2478 contacts_filter_h filter = NULL;
2479 contacts_list_h record_list = NULL;
2481 contacts_record_h phone_log = NULL;
2482 contacts_record_h record = NULL;
2487 status = contacts_db_get_record(_contacts_phone_log._uri,
2491 if (status != CONTACTS_ERROR_NONE)
2494 status = contacts_record_get_int(phone_log,
2495 _contacts_phone_log.person_id,
2498 if (status != CONTACTS_ERROR_NONE) {
2499 contacts_record_destroy(phone_log, TRUE);
2503 contacts_record_destroy(phone_log, TRUE);
2508 status = contacts_filter_create(_contacts_person_phone_log._uri,
2511 if (status != CONTACTS_ERROR_NONE)
2515 status = contacts_filter_add_int(filter,
2516 _contacts_person_phone_log.log_id,
2517 CONTACTS_MATCH_EQUAL,
2520 if (status != CONTACTS_ERROR_NONE)
2523 status = contacts_query_create(_contacts_person_phone_log._uri, &query);
2525 if (status != CONTACTS_ERROR_NONE)
2528 status = contacts_query_set_filter(query, filter);
2530 if (status != CONTACTS_ERROR_NONE)
2533 status = contacts_db_get_records_with_query(query, -1, -1,
2536 if (status != CONTACTS_ERROR_NONE)
2539 status = contacts_list_first(record_list);
2541 if (status != CONTACTS_ERROR_NONE)
2544 status = contacts_list_get_current_record_p(record_list, &record);
2546 if (status != CONTACTS_ERROR_NONE)
2549 status = contacts_record_get_int(record,
2550 _contacts_person_phone_log.person_id,
2553 if (status != CONTACTS_ERROR_NONE)
2557 if (record_list != NULL)
2558 contacts_list_destroy(record_list, TRUE);
2560 contacts_filter_destroy(filter);
2563 contacts_query_destroy(query);
2569 int _bluetooth_get_contact_addressbook(gint person_id)
2571 contacts_record_h person = NULL;
2572 contacts_record_h contact = NULL;
2573 contacts_record_h addressbook = NULL;
2575 char* addressbook_name = NULL;
2576 gint contact_id = 0;
2577 gint address_book_id = 0;
2580 status = contacts_db_get_record(_contacts_person._uri,
2583 if (status != CONTACTS_ERROR_NONE)
2584 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2586 status = contacts_record_get_int(person,
2587 _contacts_person.display_contact_id,
2589 contacts_record_destroy(person, TRUE);
2591 if (status != CONTACTS_ERROR_NONE)
2592 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2594 status = contacts_db_get_record(_contacts_contact._uri,
2597 if (status != CONTACTS_ERROR_NONE)
2598 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2600 status = contacts_record_get_int(contact,
2601 _contacts_contact.address_book_id,
2603 contacts_record_destroy(contact, TRUE);
2605 if (status != CONTACTS_ERROR_NONE)
2606 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2608 status = contacts_db_get_record(_contacts_address_book._uri,
2611 if (status != CONTACTS_ERROR_NONE)
2612 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2614 status = contacts_record_get_str_p(addressbook, _contacts_address_book.name,
2616 contacts_record_destroy(addressbook, TRUE);
2618 if (status != CONTACTS_ERROR_NONE)
2619 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2621 if (address_book_id == 0 || _bt_is_sim_addressbook(addressbook_name) == false)
2622 return PBAP_ADDRESSBOOK_PHONE;
2624 return PBAP_ADDRESSBOOK_SIM;
2627 gchar *_bluetooth_pb_vcard_contact(gint person_id,
2637 str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
2644 gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
2649 GString *str = g_string_new("BEGIN:VCARD\r\n");
2653 fn = _bluetooth_pb_owner_name();
2654 name = g_strdup_printf("%s;;;;", fn);
2657 case VCARD_FORMAT_3_0:
2658 g_string_append(str, "VERSION:3.0\r\n");
2660 __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
2661 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
2662 __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL",
2665 case VCARD_FORMAT_2_1:
2667 g_string_append(str, "VERSION:2.1\r\n");
2669 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
2671 if (filter == 0 || (filter & VCARD_FN))
2672 __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN",
2675 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL",
2681 g_string_append(str, "END:VCARD\r\n");
2687 return g_string_free(str, FALSE);
2690 gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
2701 ERR("Unknown attribute type ignored\n");
2705 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2707 DBG("person_id %d\n", person_id);
2710 if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
2711 gchar *datetime = NULL;
2713 datetime = __bluetooth_pb_phonelog_datetime(
2716 str = __bluetooth_pb_vcard_real_contact_with_properties(
2720 "X-IRMC-CALL-DATETIME", attr, datetime,
2726 str = __bluetooth_pb_vcard_real_contact_with_properties(
2733 str = __bluetooth_pb_vcard_real_call(phonelog_id, filter,
2740 gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
2743 contacts_record_h person = NULL;
2749 status = contacts_db_get_record(_contacts_person._uri,
2753 if (status != CONTACTS_ERROR_NONE)
2756 status = contacts_record_get_str(person,
2757 _contacts_person.display_name,
2760 if (status != CONTACTS_ERROR_NONE)
2763 contacts_record_destroy(person, TRUE);
2769 gchar *_bluetooth_pb_name_from_person_id(gint person_id)
2772 contacts_record_h person = NULL;
2773 contacts_record_h contact = NULL;
2776 gint contact_id = 0;
2780 status = contacts_db_get_record(_contacts_person._uri,
2784 if (status != CONTACTS_ERROR_NONE)
2787 status = contacts_record_get_int(person,
2788 _contacts_person.display_contact_id,
2791 if (status != CONTACTS_ERROR_NONE) {
2792 contacts_record_destroy(person, TRUE);
2796 status = contacts_db_get_record(_contacts_contact._uri,
2800 if (status != CONTACTS_ERROR_NONE) {
2801 contacts_record_destroy(person, TRUE);
2805 str = __bluetooth_pb_name_from_contact(contact);
2807 contacts_record_destroy(contact, TRUE);
2808 contacts_record_destroy(person, TRUE);
2814 gchar *_bluetooth_pb_number_from_person_id(gint person_id)
2817 contacts_record_h person = NULL;
2818 contacts_record_h contact = NULL;
2821 gint contact_id = 0;
2825 status = contacts_db_get_record(_contacts_person._uri,
2829 if (status != CONTACTS_ERROR_NONE)
2833 status = contacts_record_get_int(person,
2834 _contacts_person.display_contact_id,
2837 if (status != CONTACTS_ERROR_NONE) {
2838 contacts_record_destroy(person, TRUE);
2842 status = contacts_db_get_record(_contacts_contact._uri,
2846 if (status != CONTACTS_ERROR_NONE) {
2847 contacts_record_destroy(person, TRUE);
2851 str = __bluetooth_pb_number_from_contact(contact);
2853 contacts_record_destroy(contact, TRUE);
2854 contacts_record_destroy(person, TRUE);
2860 gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
2866 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2869 str = _bluetooth_pb_fn_from_person_id(person_id);
2877 gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
2883 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2886 str = _bluetooth_pb_name_from_person_id(person_id);
2890 tmp = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
2891 str = g_strdup_printf("%s;;;;", tmp);
2900 gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
2903 contacts_record_h phone_log;
2910 status = contacts_db_get_record(_contacts_phone_log._uri,
2911 phonelog_id, &phone_log);
2913 if (status != CONTACTS_ERROR_NONE)
2916 status = contacts_record_get_str_p(phone_log,
2917 _contacts_phone_log.address,
2920 if (status != CONTACTS_ERROR_NONE) {
2921 contacts_record_destroy(phone_log, TRUE);
2925 str = g_strdup(tmp);
2927 contacts_record_destroy(phone_log, TRUE);
2933 gchar *_bluetooth_pb_owner_name(void)
2938 name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
2941 name = g_strdup("My Name");
2947 bool _bt_is_sim_addressbook(const char *addressbook)
2949 return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX);