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.
36 #include <image_util.h>
37 #include <image_util_internal.h>
38 #include <libexif/exif-data.h>
41 #include "bluetooth_pb_vcard.h"
42 #include "bluetooth_pb_agent.h"
45 #define LINEBREAK_LEN 75
51 contacts_record_h person;
55 gchar dest_thumb_path[255];
56 #define PBAP_IMAGE_THUMB_SIZE 48
57 #define PBAP_THMB_PATH "_thumb"
58 #define PBAP_THUMB_FILE_SIZE 4096
59 #define PBAP_IMAGE_ENCODE_QUALITY 90
60 #define PBAP_SECURITY_FILE_GROUP 6005
61 #define PBAP_SECURITY_DEFAULT_PERMISSION 0660
62 #define PBAP_SECURITY_DIR_DEFAULT_PERMISSION 0770
63 #define PBAP_SECURITY_IMAGE_PERMISSION 0440
65 static gchar *__bluetooth_pb_vcard_escape(const gchar *str);
67 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
68 const gchar *delimeter);
70 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str);
72 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
75 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
80 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
84 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
89 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str);
91 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
94 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
99 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
106 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
107 contacts_record_h contact);
109 static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
110 contacts_record_h contact);
112 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
113 contacts_record_h conatct);
115 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
116 contacts_record_h person);
118 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
119 contacts_record_h person);
121 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
122 contacts_record_h contact);
124 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
125 contacts_record_h contact);
127 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
128 contacts_record_h contact);
130 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
131 contacts_record_h contact);
133 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
134 contacts_record_h contact);
136 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
137 contacts_record_h contact);
139 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
140 contacts_record_h contact);
142 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
143 contacts_record_h contact);
145 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
146 contacts_record_h contact);
148 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
149 contacts_record_h contact);
151 static void __bluetooth_pb_vcard_append_v30(GString *string,
156 static void __bluetooth_pb_vcard_remove_v30(GString *string,
157 const gchar *property_name);
159 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
162 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
165 const gchar *first_name,
168 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
171 const gchar *first_name,
174 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
178 const gchar *first_name,
181 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
185 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
189 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
194 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
198 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number);
200 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename);
202 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address);
204 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address);
206 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id);
208 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
210 static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact);
212 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
214 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
216 /* LCOV_EXCL_START */
217 static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
228 escaped = g_string_new(NULL);
233 while (*pos != '\0') {
235 g_string_append_len(escaped, st, (pos - st));
236 g_string_append(escaped, "\\;");
245 g_string_append_len(escaped, st, (pos - st));
247 return g_string_free(escaped, FALSE);
250 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
251 const gchar *separator)
254 GString *string = g_string_new(NULL);
257 for (i = 0; strv[i] != NULL; i++) {
259 g_string_append(string, ";");
261 g_string_append(string, strv[i]);
265 return g_string_free(string, FALSE);
269 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
278 while (*pos != '\0') {
279 /* ascii code ' ' : 32, '~' : 126 */
280 if ((guchar)*pos < ' ' || (guchar)*pos > '~')
289 /* LCOV_EXCL_START */
290 /* get string length, which convert to quoted-printable encoding */
291 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
303 if (strlen(str) < len)
308 while (*pos != '\0' && (((pos - str) < length) || length < 0)) {
309 if ((guchar)*pos == '\t') {
315 if ((guchar)*pos < ' ' || (guchar)*pos == '=') {
321 /* check no-ascii utf-8 character */
322 if ((guchar)*pos > '~') {
326 next = g_utf8_next_char(pos);
328 count += QP_ENC_LEN * (next - pos);
341 /* convert to quoted printable code */
342 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
350 if (str == NULL || len == 0)
353 /* add soft linebreak when it exceed */
354 if ((*line_pos + (QP_ENC_LEN * len) > LINEBREAK_LEN)) {
355 g_string_append(string, "=\r\n");
359 for (i = 0; i < len; i++) {
360 g_string_append_printf(string, "=%02X", (guchar)*(str+i));
361 *line_pos += QP_ENC_LEN;
366 /* append plain visiable ascii character */
367 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
372 /* add soft linebreak when it exceed */
373 if (*line_pos + 1 > LINEBREAK_LEN) {
374 g_string_append(string, "=\r\n");
377 g_string_append_c(string, ch);
382 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
395 encode_len = __bluetooth_pb_vcard_qp_encode_strlen(str, len);
397 /* add soft linebreak when it exceed */
398 if (((*line_pos + encode_len) > LINEBREAK_LEN) && (*line_pos > 1)) {
399 g_string_append(string, "=\r\n");
406 pos = ((gchar *)str) + i;
408 /* converts invisiable character and escape character '='
409 to quoted-printable */
410 if ((guchar)*pos != '\t' &&
411 ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
412 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
419 /* converts non-ascii utf-8 character to quoted-printable */
420 if ((guchar)*pos > '~') {
424 next = g_utf8_next_char(pos);
427 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
428 pos, ch_len, line_pos);
434 __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos,
441 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str)
454 enc = g_string_new(NULL);
456 st_pos = (gchar *)str;
459 while (*pos != '\0') {
460 /* split string with given delimeter ' ' or '\t' */
461 if (*pos == ' ' || *pos == '\t') {
462 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
463 (pos - st_pos), &line_pos);
471 /* split string with given delimeter '\r', '\n' or
473 if (*pos == '\r' || *pos == '\n') {
474 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
475 (pos - st_pos), &line_pos);
477 /* converts newline to qp_encode with soft linebreak
478 for example, converts \r\n to =0D=0A=\r\n */
479 __bluetooth_pb_vcard_qp_encode_append_to_hex(enc,
480 "\r\n", 2, &line_pos);
481 g_string_append(enc, "=\r\n ");
485 if (*pos == '\r' && *(pos + 1) == '\n')
498 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
499 (pos - st_pos), &line_pos);
502 return g_string_free(enc, FALSE);
506 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
515 pos = (gchar *)param;
517 /* trim ';' on first */
518 while (*pos != '\0') {
526 g_string_append_printf(string, ";%s", pos);
530 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
536 GString *property = NULL;
541 property = g_string_new(name);
542 __bluetooth_pb_vcard_append_param_v21(property, param);
544 if (__bluetooth_pb_vcard_qp_encode_check(value)) {
545 /* LCOV_EXCL_START */
548 __bluetooth_pb_vcard_append_param_v21(property,
550 __bluetooth_pb_vcard_append_param_v21(property,
551 "ENCODING=QUOTED-PRINTABLE");
552 g_string_append(property, ":");
554 enc = __bluetooth_pb_vcard_qp_encode(value);
557 g_string_append(property, enc);
562 g_string_append(property, ":");
564 g_string_append(property , value);
567 g_string_append_printf(string, "%s\r\n", property->str);
569 g_string_free(property, TRUE);
573 /* LCOV_EXCL_START */
574 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
586 DBG("base 64 encoding\n");
588 g_string_append(string, name);
590 __bluetooth_pb_vcard_append_param_v21(string, param);
591 __bluetooth_pb_vcard_append_param_v21(string, "ENCODING=BASE64");
593 g_string_append(string, ":");
598 enc = g_base64_encode((const guchar *)value, len);
600 if (folding == FALSE) {
601 g_string_append(string, enc);
603 gint enc_len = strlen(enc);
606 /* count ' ' size for folding */
607 gint fline_len = LINEBREAK_LEN - 1;
609 for (i = 0; (i * fline_len) < enc_len; i++) {
610 g_string_append(string, "\r\n ");
611 if ((i * fline_len) + fline_len > enc_len)
612 g_string_append(string, enc + (i * fline_len));
614 g_string_append_len(string, enc +
615 (i * fline_len), fline_len);
618 /* some application requires more \r\n */
619 g_string_append(string, "\r\n");
621 g_string_append(string, "\r\n");
622 DBG("base 64 encoding\n");
628 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
629 contacts_record_h contact)
634 str = __bluetooth_pb_name_from_contact(contact);
635 __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
641 static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
642 contacts_record_h contact)
647 str = __bluetooth_pb_phonetic_name_from_contact(contact);
650 __bluetooth_pb_vcard_append_qp_encode_v21(string, "SOUND", "X-IRMC-N", str);
656 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
657 contacts_record_h contact)
665 status = contacts_record_get_child_record_count(contact,
666 _contacts_contact.number,
669 if (status != CONTACTS_ERROR_NONE)
672 for (i = 0; i < count; i++) {
673 contacts_record_h number = NULL;
675 gchar **paramv = NULL;
679 gchar *escaped = NULL;
681 status = contacts_record_get_child_record_at_p(contact,
682 _contacts_contact.number, i, &number);
684 if (status != CONTACTS_ERROR_NONE)
687 status = contacts_record_get_str_p(number,
688 _contacts_number.number,
691 if (status != CONTACTS_ERROR_NONE)
694 escaped = __bluetooth_pb_vcard_escape(tel);
696 paramv = __bluetooth_pb_contact_tel_param(number);
698 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
700 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param,
710 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
711 contacts_record_h person)
719 status = contacts_record_get_str_p(person,
720 _contacts_person.display_name,
723 if (status != CONTACTS_ERROR_NONE)
726 fn = __bluetooth_pb_vcard_escape(tmp);
728 __bluetooth_pb_vcard_append_qp_encode_v21(string, "FN", NULL, fn);
734 /* image util APIs will be deprecated in Tizen 5.0. So we should replace it to new API
735 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#decode
736 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#encode
739 static image_util_rotation_e __bt_pbap_get_rotation_info(const char *path)
744 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
747 ed = exif_data_new_from_file(path);
749 ERR("exif_data_new_from_file : ExifData is NULL");
750 return IMAGE_UTIL_ROTATION_NONE;
753 entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
755 ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
756 orientation = (int)exif_get_short(entry->data, mByteOrder);
757 if (orientation < 0 || orientation > 8)
763 switch (orientation) {
764 case 1: /* Top-left */
765 rotation = IMAGE_UTIL_ROTATION_NONE;
767 case 2: /* Top-right */
768 rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
770 case 3: /* Bottom-right */
771 rotation = IMAGE_UTIL_ROTATION_180;
773 case 4: /* Bottom-left */
774 rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
776 case 6: /* Right-top */
777 rotation = IMAGE_UTIL_ROTATION_90;
779 case 8: /* Left-bottom */
780 rotation = IMAGE_UTIL_ROTATION_270;
782 case 5: /* Left-top */
783 case 7: /* Right-bottom */
794 static bool __bt_pbap_image_util_supported_jpeg_colorspace_cb(
795 image_util_colorspace_e colorspace, void *user_data)
798 unsigned char *img_target = 0;
799 unsigned char *img_source = 0;
802 gchar *contents = NULL;
805 int resized_width = 0;
806 int resized_height = 0;
808 unsigned int size_decode = 0;
809 image_util_rotation_e rotation;
810 image_util_error_e ret = 0;
813 bt_image_info_t *info = (bt_image_info_t *)user_data;
814 rotation = __bt_pbap_get_rotation_info(info->src);
815 ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width,
816 &height, &size_decode);
817 if (ret != IMAGE_UTIL_ERROR_NONE) {
818 ERR("Can not decode");
819 memset(info, 0x00, sizeof(bt_image_info_t));
823 DBG("decoding completed width = %d, height = %d, size = %d\n", width,
824 height, size_decode);
825 if (width > PBAP_IMAGE_THUMB_SIZE || height > PBAP_IMAGE_THUMB_SIZE) {
826 if (width <= 0 || height <= 0) {
828 ERR("image size error(%d)", PBAP_IMAGE_THUMB_SIZE);
829 memset(info, 0x00, sizeof(bt_image_info_t));
833 if (width > height) {
834 resized_width = PBAP_IMAGE_THUMB_SIZE ;
835 resized_height = height * PBAP_IMAGE_THUMB_SIZE / width;
837 resized_height = PBAP_IMAGE_THUMB_SIZE;
838 resized_width = width * PBAP_IMAGE_THUMB_SIZE / height;
841 if (resized_height % 8)
842 resized_height += 8 - (resized_height % 8);
843 if (resized_width % 8)
844 resized_width += 8 - (resized_width % 8);
846 DBG("original size[%d, %d] changed to resize[%d,%d]", width,
847 height, resized_width, resized_height);
849 ret = image_util_calculate_buffer_size(resized_width,
854 img_target = g_malloc0(size_decode);
857 ret = image_util_resize(img_target, &resized_width,
858 &resized_height, img_source, width,
860 if (ret != IMAGE_UTIL_ERROR_NONE) {
861 ERR("image_util_resize failed(%d)", ret);
864 memset(info, 0x00, sizeof(bt_image_info_t));
869 resized_width = width;
870 resized_height = height;
871 img_target = img_source;
873 DBG("Resized w = %d, ht = %d, size = %d\n", width, height, size_decode);
875 if (IMAGE_UTIL_ROTATION_NONE != rotation) {
876 int rotated_width, rotated_height;
877 unsigned char *img_rotate = 0;
878 img_rotate = g_malloc0(size_decode);
879 ret = image_util_rotate(img_rotate, &rotated_width, &rotated_height,
880 rotation, img_target, resized_width,
881 resized_height, colorspace);
883 ERR("image_util_rotate failed");
884 resized_width = rotated_width;
885 resized_height = rotated_height;
887 img_target = img_rotate;
891 ret = image_util_encode_jpeg(img_target, resized_width, resized_height,
892 colorspace, PBAP_IMAGE_ENCODE_QUALITY,
895 if (ret != IMAGE_UTIL_ERROR_NONE) {
896 ERR("image_util_encode_jpeg failed(%d)", ret);
897 info->ret = CONTACTS_ERROR_INTERNAL;
900 DBG("Encoding done\n");
902 dest_fd = open(info->dest, O_RDONLY);
904 ERR("System : Open Failed(%d)", errno);
905 ERR_SECURE("Open : dest path(%s)", info->dest);
909 ret = fchown(dest_fd, getuid(), PBAP_SECURITY_FILE_GROUP);
911 ERR("fchown Failed(%d)", errno);
912 DBG_SECURE("fchown : dest path(%s)", info->dest);
917 ret = fchmod(dest_fd, PBAP_SECURITY_IMAGE_PERMISSION);
919 ERR("fchmod Failed(%d)", errno);
920 ERR_SECURE("fchmod : dest path(%s)", info->dest);
926 info->ret = CONTACTS_ERROR_NONE;
927 type = __bluetooth_pb_contact_photo_type(info->dest);
928 DBG("Cintact image thumb type is = %s\n", type);
931 param = g_strdup_printf("TYPE=%s", type);
935 if (g_file_get_contents(info->dest, &contents, &len, NULL) == FALSE) {
936 ERR("can not read file contents:%s\n", info->dest);
940 __bluetooth_pb_vcard_append_base64_encode_v21(info->string,
941 "PHOTO", param, contents, len, TRUE);
947 memset(info, 0x00, sizeof(bt_image_info_t));
948 DBG("Cintact image thumb created successfuly\n");
954 /* LCOV_EXCL_START */
955 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
956 contacts_record_h person)
960 gchar *filename = NULL;
961 struct stat stat_info;
964 gchar *contents = NULL;
968 status = contacts_record_get_str_p(person,
969 _contacts_person.image_thumbnail_path,
972 if (status != CONTACTS_ERROR_NONE || NULL == filename)
975 stat_info.st_size = 0;
977 if (0 > stat(filename, &stat_info))
978 ERR("fstat failed, file does not exist %s", filename);
980 if (PBAP_THUMB_FILE_SIZE > stat_info.st_size) {
981 DBG_SECURE("File size small, so use thubnail %s\n", filename);
983 type = __bluetooth_pb_contact_photo_type(filename);
985 param = g_strdup_printf("TYPE=%s", type);
989 if (g_file_get_contents(filename, &contents, &len, NULL) ==
991 ERR("can not read file contents:%s\n", filename);
995 DBG("Retrieved the contents of the file \n");
996 __bluetooth_pb_vcard_append_base64_encode_v21(string,
997 "PHOTO", param, contents, len, TRUE);
1004 ptr = strrchr(filename, '.');
1006 memset(dest_thumb_path, 0x00, sizeof(dest_thumb_path));
1007 g_strlcpy(dest_thumb_path, filename, ptr - filename);
1008 g_strlcat(dest_thumb_path, PBAP_THMB_PATH,
1009 sizeof(dest_thumb_path));
1010 g_strlcat(dest_thumb_path, ptr, sizeof(dest_thumb_path));
1011 DBG("Thumbnail path is = %s", dest_thumb_path);
1013 DBG_SECURE("filename = %s Thumbnail path is = %s", filename, dest_thumb_path);
1015 /* image_util_foreach_supported_jpeg_colorspace API will be deprecated in Tizen 5.0. So we should replace it to new API
1016 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#decode
1017 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#encode
1020 bt_image_info_t img_info;
1023 img_info.src = filename;
1024 img_info.dest = dest_thumb_path;
1025 img_info.ret = CONTACTS_ERROR_INTERNAL;
1026 img_info.person = person;
1027 img_info.string = string;
1029 res = image_util_foreach_supported_jpeg_colorspace(
1030 __bt_pbap_image_util_supported_jpeg_colorspace_cb, &img_info);
1032 if (res != IMAGE_UTIL_ERROR_NONE)
1033 ERR("Image resizing is failed");
1039 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
1040 contacts_record_h contact)
1048 status = contacts_record_get_child_record_count(contact,
1049 _contacts_contact.event, &count);
1051 if (status != CONTACTS_ERROR_NONE)
1054 for (i = 0; i < count; i++) {
1055 contacts_record_h event = NULL;
1061 contacts_event_type_e type;
1063 status = contacts_record_get_child_record_at_p(contact,
1064 _contacts_contact.event, i, &event);
1066 if (status != CONTACTS_ERROR_NONE)
1069 status = contacts_record_get_int(event,
1070 _contacts_event.type,
1073 if (status != CONTACTS_ERROR_NONE)
1076 if (type != CONTACTS_EVENT_TYPE_BIRTH)
1079 status = contacts_record_get_int(event,
1080 _contacts_event.date,
1083 if (status != CONTACTS_ERROR_NONE)
1089 bday = g_strdup_printf("%04d-%02d-%02d",
1090 (date/10000), (date/100)%100, date%100);
1091 __bluetooth_pb_vcard_append_qp_encode_v21(string, "BDAY",
1098 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
1099 contacts_record_h contact)
1107 status = contacts_record_get_child_record_count(contact,
1108 _contacts_contact.address,
1111 if (status != CONTACTS_ERROR_NONE)
1114 for (i = 0; i < count; i++) {
1115 contacts_record_h address = NULL;
1123 status = contacts_record_get_child_record_at_p(contact,
1124 _contacts_contact.address, i, &address);
1126 if (status != CONTACTS_ERROR_NONE)
1129 addrv = __bluetooth_pb_contact_addr(address);
1134 addr = __bluetooth_pb_vcard_strv_concat(addrv, ";");
1137 paramv = __bluetooth_pb_contact_addr_param(address);
1139 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
1142 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
1152 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
1153 contacts_record_h contact)
1161 status = contacts_record_get_child_record_count(contact,
1162 _contacts_contact.email,
1165 if (status != CONTACTS_ERROR_NONE)
1168 for (i = 0; i < count; i++) {
1169 contacts_record_h email = NULL;
1174 status = contacts_record_get_child_record_at_p(contact,
1175 _contacts_contact.email, i, &email);
1177 if (status != CONTACTS_ERROR_NONE)
1180 status = contacts_record_get_str_p(email,
1181 _contacts_email.email,
1184 if (status != CONTACTS_ERROR_NONE)
1187 escaped = __bluetooth_pb_vcard_escape(tmp);
1188 __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL,
1196 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
1197 contacts_record_h contact)
1205 status = contacts_record_get_child_record_count(contact,
1206 _contacts_contact.company,
1209 if (status != CONTACTS_ERROR_NONE)
1212 for (i = 0; i < count; i++) {
1213 contacts_record_h company = NULL;
1218 status = contacts_record_get_child_record_at_p(contact,
1219 _contacts_contact.company, i, &company);
1221 if (status != CONTACTS_ERROR_NONE)
1224 status = contacts_record_get_str_p(company,
1225 _contacts_company.job_title,
1228 if (status != CONTACTS_ERROR_NONE)
1231 escaped = __bluetooth_pb_vcard_escape(title);
1232 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL,
1240 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
1241 contacts_record_h contact)
1249 status = contacts_record_get_child_record_count(contact,
1250 _contacts_contact.company,
1253 if (status != CONTACTS_ERROR_NONE)
1256 for (i = 0; i < count; i++) {
1257 contacts_record_h company = NULL;
1262 status = contacts_record_get_child_record_at_p(contact,
1263 _contacts_contact.company, i, &company);
1265 if (status != CONTACTS_ERROR_NONE)
1268 status = contacts_record_get_str_p(company,
1269 _contacts_company.role,
1272 if (status != CONTACTS_ERROR_NONE)
1275 escaped = __bluetooth_pb_vcard_escape(role);
1276 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL,
1284 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
1285 contacts_record_h contact)
1293 status = contacts_record_get_child_record_count(contact,
1294 _contacts_contact.company,
1297 if (status != CONTACTS_ERROR_NONE)
1300 for (i = 0; i < count; i++) {
1301 contacts_record_h company = NULL;
1306 gchar *department = NULL;
1309 gint department_status;
1311 status = contacts_record_get_child_record_at_p(contact,
1312 _contacts_contact.company, i, &company);
1314 if (status != CONTACTS_ERROR_NONE)
1318 name_status = contacts_record_get_str_p(company,
1319 _contacts_company.name,
1322 department_status = contacts_record_get_str_p(company,
1323 _contacts_company.department,
1326 if ((name_status != CONTACTS_ERROR_NONE) &&
1327 (department_status != CONTACTS_ERROR_NONE))
1330 str = g_string_new(NULL);
1335 escaped = __bluetooth_pb_vcard_escape(name);
1336 g_string_append(str, escaped);
1340 g_string_append(str, ";");
1345 escaped = __bluetooth_pb_vcard_escape(department);
1346 g_string_append(str, escaped);
1350 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL,
1353 g_string_free(str, TRUE);
1359 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
1360 contacts_record_h contact)
1368 status = contacts_record_get_child_record_count(contact,
1369 _contacts_contact.note,
1372 if (status != CONTACTS_ERROR_NONE)
1375 for (i = 0; i < count; i++) {
1376 contacts_record_h note = NULL;
1381 status = contacts_record_get_child_record_at_p(contact,
1382 _contacts_contact.note, i, ¬e);
1384 if (status != CONTACTS_ERROR_NONE)
1387 status = contacts_record_get_str_p(note,
1388 _contacts_note.note,
1391 if (status != CONTACTS_ERROR_NONE)
1394 escaped = __bluetooth_pb_vcard_escape(tmp);
1395 __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL,
1403 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
1404 contacts_record_h contact)
1413 status = contacts_record_get_int(contact,
1414 _contacts_contact.changed_time,
1417 if (status != CONTACTS_ERROR_NONE)
1423 gmtime_r((const time_t *)(&time), &result);
1425 rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
1426 (1900 + result.tm_year), (1 + result.tm_mon),
1427 result.tm_mday, result.tm_hour, result.tm_min,
1430 __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
1436 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
1437 contacts_record_h contact)
1445 status = contacts_record_get_child_record_count(contact,
1446 _contacts_contact.url,
1449 if (status != CONTACTS_ERROR_NONE)
1452 for (i = 0; i < count; i++) {
1453 contacts_record_h url = NULL;
1458 status = contacts_record_get_child_record_at_p(contact,
1459 _contacts_contact.url, i, &url);
1461 if (status != CONTACTS_ERROR_NONE)
1467 status = contacts_record_get_str_p(url,
1471 if (status != CONTACTS_ERROR_NONE)
1474 escaped = __bluetooth_pb_vcard_escape(tmp);
1475 __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL,
1483 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
1484 contacts_record_h contact)
1492 status = contacts_record_get_str_p(contact,
1493 _contacts_contact.uid,
1496 if (status != CONTACTS_ERROR_NONE)
1499 escaped = __bluetooth_pb_vcard_escape(uid);
1500 __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
1505 /* LCOV_EXCL_STOP */
1507 static void __bluetooth_pb_vcard_append_v30(GString *string,
1518 g_string_append(string, name);
1521 g_string_append_printf(string, ";%s", param);
1523 g_string_append(string, ":");
1526 g_string_append(string, value);
1528 g_string_append(string, "\r\n");
1532 /* LCOV_EXCL_START */
1533 static void __bluetooth_pb_vcard_remove_v30(GString *string,
1534 const gchar *property_name)
1538 gchar *st_pos = NULL;
1540 gboolean matched = FALSE;
1542 if (string == NULL || property_name == NULL)
1547 while (*pos != '\0') {
1548 if (matched == FALSE) {
1549 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1555 attrlen = strlen(property_name);
1556 if (g_ascii_strncasecmp(pos, property_name,
1560 if (*pos == ':' || *pos == ';') {
1568 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1571 if (*pos != ' ' && *pos != '\t') {
1572 /* +2 means move over \r\n */
1573 g_string_erase(string,
1574 (st_pos+2)-(string->str),
1589 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
1593 GString *string = NULL;
1598 string = g_string_new(vcard);
1600 if ((filter & VCARD_BDAY) == 0)
1601 __bluetooth_pb_vcard_remove_v30(string, "BDAY");
1603 if ((filter & VCARD_ADR) == 0)
1604 __bluetooth_pb_vcard_remove_v30(string, "ADR");
1606 if ((filter & VCARD_EMAIL) == 0)
1607 __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
1609 if ((filter & VCARD_TITLE) == 0)
1610 __bluetooth_pb_vcard_remove_v30(string, "TITLE");
1612 if ((filter & VCARD_ROLE) == 0)
1613 __bluetooth_pb_vcard_remove_v30(string, "ROLE");
1615 if ((filter & VCARD_ORG) == 0)
1616 __bluetooth_pb_vcard_remove_v30(string, "ORG");
1618 if ((filter & VCARD_NOTE) == 0)
1619 __bluetooth_pb_vcard_remove_v30(string, "NOTE");
1621 if ((filter & VCARD_REV) == 0)
1622 __bluetooth_pb_vcard_remove_v30(string, "REV");
1624 if ((filter & VCARD_URL) == 0)
1625 __bluetooth_pb_vcard_remove_v30(string, "URL");
1627 if ((filter & VCARD_UID) == 0)
1628 __bluetooth_pb_vcard_remove_v30(string, "UID");
1630 if ((filter & VCARD_NICKNAME) == 0)
1631 __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
1634 return g_string_free(string, FALSE);
1637 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
1640 const gchar *first_name,
1644 contacts_record_h person = NULL;
1645 contacts_record_h contact = NULL;
1647 GString *str = NULL;
1649 gint contact_id = 0;
1654 const gchar *name = first_name;
1656 status = contacts_db_get_record(_contacts_person._uri,
1660 if (status != CONTACTS_ERROR_NONE)
1663 status = contacts_record_get_int(person,
1664 _contacts_person.display_contact_id,
1667 if (status != CONTACTS_ERROR_NONE)
1670 status = contacts_db_get_record(_contacts_contact._uri,
1674 if (status != CONTACTS_ERROR_NONE) {
1675 contacts_record_destroy(person, TRUE);
1682 DBG("filter[%x]\n", filter);
1684 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1686 /* N, TEL is default */
1687 __bluetooth_pb_vcard_append_n_v21(str, contact);
1689 if (phonelog_id > 0) {
1692 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1693 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0",
1699 __bluetooth_pb_vcard_append_tel_v21(str, contact);
1703 __bluetooth_pb_vcard_append_fn_v21(str, person);
1704 /* Need to check filter
1705 if (f & VCARD_SOUND)*/
1706 __bluetooth_pb_vcard_append_phonetic_first_v21(str, contact);
1707 if (f & VCARD_PHOTO)
1708 __bluetooth_pb_vcard_append_photo_v21(str, person);
1710 __bluetooth_pb_vcard_append_bday_v21(str, contact);
1712 __bluetooth_pb_vcard_append_adr_v21(str, contact);
1713 if (f & VCARD_EMAIL)
1714 __bluetooth_pb_vcard_append_email_v21(str, contact);
1715 if (f & VCARD_TITLE)
1716 __bluetooth_pb_vcard_append_title_v21(str, contact);
1718 __bluetooth_pb_vcard_append_role_v21(str, contact);
1720 __bluetooth_pb_vcard_append_org_v21(str, contact);
1722 __bluetooth_pb_vcard_append_note_v21(str, contact);
1724 __bluetooth_pb_vcard_append_rev_v21(str, contact);
1726 __bluetooth_pb_vcard_append_url_v21(str, contact);
1728 __bluetooth_pb_vcard_append_uid_v21(str, contact);
1731 const gchar *param = va_arg(args, const gchar *);
1732 const gchar *value = va_arg(args, const gchar *);
1735 gchar *escaped = NULL;
1737 escaped = __bluetooth_pb_vcard_escape(value);
1738 __bluetooth_pb_vcard_append_qp_encode_v21(str, name,
1744 name = va_arg(args, const gchar *);
1747 g_string_append(str, "END:VCARD\r\n");
1749 contacts_record_destroy(contact, TRUE);
1750 contacts_record_destroy(person, TRUE);
1753 return g_string_free(str, FALSE);
1755 /* LCOV_EXCL_STOP */
1757 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
1760 const gchar *first_name,
1764 contacts_record_h person = NULL;
1766 GString *str = NULL;
1770 const gchar *name = first_name;
1771 gchar *vcard = NULL;
1773 status = contacts_db_get_record(_contacts_person._uri,
1777 if (status != CONTACTS_ERROR_NONE)
1780 /* LCOV_EXCL_START */
1781 status = contacts_vcard_make_from_person(person, &vcard);
1783 if (status != CONTACTS_ERROR_NONE)
1786 /* removing the END:VCARD\r\n" to append extra data */
1787 str = g_string_new_len(vcard, (strlen(vcard)-11));
1790 /* append contents on vcard */
1792 const gchar *param = va_arg(args, const gchar *);
1793 const gchar *value = va_arg(args, const gchar *);
1795 __bluetooth_pb_vcard_append_v30(str, name, param, value);
1797 name = va_arg(args, const gchar *);
1800 /* if phonelog_id exist, we shall show only the phone number, which was
1801 used for that phone log */
1802 if (phonelog_id > 0) {
1805 __bluetooth_pb_vcard_remove_v30(str, "TEL");
1807 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1808 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1812 /* Remove Full contact image and add thumbnail image */
1813 __bluetooth_pb_vcard_remove_v30(str, "PHOTO");
1814 if (filter & VCARD_PHOTO)
1815 __bluetooth_pb_vcard_append_photo_v21(str, person); /* Photo is same as vCard 2.1 */
1817 /* Destroy contact record */
1818 status = contacts_record_destroy(person, TRUE);
1819 if (status != CONTACTS_ERROR_NONE)
1820 ERR("Failed to destroy person");
1822 g_string_append(str, "END:VCARD\r\n");
1824 vcard = g_string_free(str, FALSE);
1826 /* temporary fixed for some application crash */
1828 filter = ~VCARD_NOTE;
1831 gchar *new_vcard = NULL;
1833 new_vcard = __bluetooth_pb_vcard_filter_v30(vcard, filter);
1843 /* LCOV_EXCL_STOP */
1847 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
1851 const gchar *first_name,
1855 DBG(" format [%d]\n", format);
1856 gchar *vcard = NULL;
1859 va_start(args, first_name);
1862 case VCARD_FORMAT_3_0:
1863 vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
1864 phonelog_id, filter,
1867 case VCARD_FORMAT_2_1:
1869 vcard = __bluetooth_pb_vcard_real_contact_valist_v21(person_id,
1870 phonelog_id, filter,
1881 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
1889 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1891 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, NULL);
1893 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1894 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
1897 /* LCOV_EXCL_START */
1898 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1900 gchar *datetime = NULL;
1902 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1903 __bluetooth_pb_vcard_append_qp_encode_v21(str,
1904 "X-IRMC-CALL-DATETIME",
1908 /* LCOV_EXCL_STOP */
1910 g_string_append(str, "END:VCARD\r\n");
1913 return g_string_free(str, FALSE);
1916 /* LCOV_EXCL_START */
1917 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
1925 str = g_string_new("BEGIN:VCARD\r\nVERSION:3.0\r\n");
1927 __bluetooth_pb_vcard_append_v30(str, "N", NULL, NULL);
1928 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, NULL);
1930 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1931 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1934 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1936 gchar *datetime = NULL;
1938 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1939 __bluetooth_pb_vcard_append_v30(str,
1940 "X-IRMC-CALL-DATETIME", attr, datetime);
1944 g_string_append(str, "END:VCARD\r\n");
1947 return g_string_free(str, FALSE);
1949 /* LCOV_EXCL_STOP */
1951 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
1957 gchar *vcard = NULL;
1960 case VCARD_FORMAT_3_0:
1961 vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
1964 case VCARD_FORMAT_2_1:
1966 vcard = __bluetooth_pb_vcard_real_call_v21(phonelog_id,
1975 /* LCOV_EXCL_START */
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 status = contacts_record_get_int(number,
2047 _contacts_number.type,
2050 if (status != CONTACTS_ERROR_NONE)
2053 strv = g_new0(char *, TEL_PARAM_LEN + 1);/* tel param max size is 13 */
2056 strv[i] = g_strdup("PREF");
2060 if (type & CONTACTS_NUMBER_TYPE_HOME) {
2061 strv[i] = g_strdup("HOME");
2065 if (type & CONTACTS_NUMBER_TYPE_WORK) {
2066 strv[i] = g_strdup("WORK");
2070 if (type & CONTACTS_NUMBER_TYPE_VOICE) {
2071 strv[i] = g_strdup("VOICE");
2075 if (type & CONTACTS_NUMBER_TYPE_FAX) {
2076 strv[i] = g_strdup("FAX");
2080 if (type & CONTACTS_NUMBER_TYPE_MSG) {
2081 strv[i] = g_strdup("MSG");
2085 if (type & CONTACTS_NUMBER_TYPE_CELL) {
2086 strv[i] = g_strdup("CELL");
2090 if (type & CONTACTS_NUMBER_TYPE_PAGER) {
2091 strv[i] = g_strdup("PAGER");
2095 if (type & CONTACTS_NUMBER_TYPE_BBS) {
2096 strv[i] = g_strdup("BBS");
2100 if (type & CONTACTS_NUMBER_TYPE_MODEM) {
2101 strv[i] = g_strdup("MODEM");
2105 if (type & CONTACTS_NUMBER_TYPE_CAR) {
2106 strv[i] = g_strdup("CAR");
2110 if (type & CONTACTS_NUMBER_TYPE_ISDN) {
2111 strv[i] = g_strdup("ISDN");
2115 if (type & CONTACTS_NUMBER_TYPE_VIDEO) {
2116 strv[i] = g_strdup("VIDEO");
2120 /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
2126 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
2129 gchar *filetype = NULL;
2132 if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
2133 ERR_SECURE("file does not regular:%s\n", filename);
2137 ext = strrchr(filename, '.');
2139 ERR("file doesn't have extension\n");
2145 if (g_ascii_strcasecmp(ext, "gif") == 0)
2147 else if (g_ascii_strcasecmp(ext, "cgm") == 0)
2149 else if (g_ascii_strcasecmp(ext, "wmf") == 0)
2151 else if (g_ascii_strcasecmp(ext, "bmp") == 0)
2153 else if (g_ascii_strcasecmp(ext, "met") == 0)
2155 else if (g_ascii_strcasecmp(ext, "dib") == 0)
2157 else if (g_ascii_strcasecmp(ext, "pict") == 0 ||
2158 g_ascii_strcasecmp(ext, "pct") == 0 ||
2159 g_ascii_strcasecmp(ext, "pic") == 0)
2161 else if (g_ascii_strcasecmp(ext, "tiff") == 0 ||
2162 g_ascii_strcasecmp(ext, "tif") == 0)
2164 else if (g_ascii_strcasecmp(ext, "ps") == 0)
2166 else if (g_ascii_strcasecmp(ext, "pdf") == 0)
2168 else if (g_ascii_strcasecmp(ext, "jpeg") == 0 ||
2169 g_ascii_strcasecmp(ext, "jpg") == 0 ||
2170 g_ascii_strcasecmp(ext, "jpe") == 0)
2172 else if (g_ascii_strcasecmp(ext, "mpeg") == 0 ||
2173 g_ascii_strcasecmp(ext, "mpg") == 0)
2175 else if (g_ascii_strcasecmp(ext, "m2v") == 0)
2177 else if (g_ascii_strcasecmp(ext, "avi") == 0)
2179 else if (g_ascii_strcasecmp(ext, "mov") == 0)
2181 else if (g_ascii_strcasecmp(ext, "png") == 0)
2185 return g_strdup(filetype);
2188 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
2191 const gint ADDR_LEN = 7;
2193 gchar **strv = NULL;
2195 gint addr[] = { _contacts_address.postbox,
2196 _contacts_address.extended,
2197 _contacts_address.street,
2198 _contacts_address.locality,
2199 _contacts_address.region,
2200 _contacts_address.postal_code,
2201 _contacts_address.country };
2203 strv = __bluetooth_pb_contact_add_field_str(address,
2209 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
2212 contacts_address_type_e type;
2217 gchar **strv = NULL;
2219 status = contacts_record_get_int(address,
2220 _contacts_address.type,
2223 if (status != CONTACTS_ERROR_NONE)
2226 strv = g_new0(gchar *, 7); /* ADDR param max size is 6 */
2228 if (type & CONTACTS_ADDRESS_TYPE_HOME) {
2229 strv[i] = g_strdup("HOME");
2232 if (type & CONTACTS_ADDRESS_TYPE_WORK) {
2233 strv[i] = g_strdup("WORK");
2236 if (type & CONTACTS_ADDRESS_TYPE_DOM) {
2237 strv[i] = g_strdup("DOM");
2240 if (type & CONTACTS_ADDRESS_TYPE_INTL) {
2241 strv[i] = g_strdup("INTL");
2244 if (type & CONTACTS_ADDRESS_TYPE_POSTAL) {
2245 strv[i] = g_strdup("POSTAL");
2248 if (type & CONTACTS_ADDRESS_TYPE_PARCEL) {
2249 strv[i] = g_strdup("PARCEL");
2256 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
2259 contacts_record_h phone_log;
2261 char time_str[32] = {0,};
2266 struct tm time_info;
2268 status = contacts_db_get_record(_contacts_phone_log._uri,
2272 if (status != CONTACTS_ERROR_NONE)
2275 status = contacts_record_get_int(phone_log,
2276 _contacts_phone_log.log_time,
2279 if (status != CONTACTS_ERROR_NONE)
2285 localtime_r((time_t *)&time, &time_info);
2287 strftime(time_str, sizeof(time_str),
2288 "%Y%m%dT%H%M%S", &time_info);
2290 contacts_record_destroy(phone_log, TRUE);
2293 return g_strdup(time_str);
2296 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
2299 contacts_record_h name = NULL;
2306 gint name_val[] = { _contacts_name.last,
2307 _contacts_name.first,
2308 _contacts_name.addition,
2309 _contacts_name.prefix,
2310 _contacts_name.suffix };
2313 status = contacts_record_get_child_record_at_p(contact,
2314 _contacts_contact.name, 0, &name);
2316 if (status != CONTACTS_ERROR_NONE)
2319 str = g_string_new(NULL);
2321 for (i = 0; i < name_size; i++) {
2323 gchar *escape = NULL;
2326 g_string_append_c(str, ';');
2328 status = contacts_record_get_str_p(name, name_val[i], &tmp);
2330 if (status != CONTACTS_ERROR_NONE)
2333 escape = __bluetooth_pb_vcard_escape(tmp);
2334 g_string_append(str, escape);
2340 return g_string_free(str, FALSE);
2343 static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact)
2346 contacts_record_h name = NULL;
2352 gchar *phonetic_first = NULL;
2353 gchar *phonetic_last = NULL;
2354 gchar *escape = NULL;
2356 status = contacts_record_get_child_record_at_p(contact,
2357 _contacts_contact.name, 0, &name);
2359 if (status != CONTACTS_ERROR_NONE)
2362 status = contacts_record_get_str_p(name, _contacts_name.phonetic_first, &phonetic_first);
2364 if (status != CONTACTS_ERROR_NONE)
2367 if (phonetic_first == NULL)
2370 str = g_string_new(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);
2473 /* LCOV_EXCL_STOP */
2475 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
2478 contacts_query_h query = NULL;
2479 contacts_filter_h filter = NULL;
2480 contacts_list_h record_list = NULL;
2482 contacts_record_h phone_log = NULL;
2483 contacts_record_h record = NULL;
2488 status = contacts_db_get_record(_contacts_phone_log._uri,
2492 if (status != CONTACTS_ERROR_NONE)
2495 /* LCOV_EXCL_START */
2496 status = contacts_record_get_int(phone_log,
2497 _contacts_phone_log.person_id,
2500 if (status != CONTACTS_ERROR_NONE) {
2501 contacts_record_destroy(phone_log, TRUE);
2505 contacts_record_destroy(phone_log, TRUE);
2510 status = contacts_filter_create(_contacts_person_phone_log._uri,
2513 if (status != CONTACTS_ERROR_NONE)
2517 status = contacts_filter_add_int(filter,
2518 _contacts_person_phone_log.log_id,
2519 CONTACTS_MATCH_EQUAL,
2522 if (status != CONTACTS_ERROR_NONE)
2525 status = contacts_query_create(_contacts_person_phone_log._uri, &query);
2527 if (status != CONTACTS_ERROR_NONE)
2530 status = contacts_query_set_filter(query, filter);
2532 if (status != CONTACTS_ERROR_NONE)
2535 status = contacts_db_get_records_with_query(query, -1, -1,
2538 if (status != CONTACTS_ERROR_NONE)
2541 status = contacts_list_first(record_list);
2543 if (status != CONTACTS_ERROR_NONE)
2546 status = contacts_list_get_current_record_p(record_list, &record);
2548 if (status != CONTACTS_ERROR_NONE)
2551 status = contacts_record_get_int(record,
2552 _contacts_person_phone_log.person_id,
2555 if (status != CONTACTS_ERROR_NONE)
2559 if (record_list != NULL)
2560 contacts_list_destroy(record_list, TRUE);
2562 contacts_filter_destroy(filter);
2565 contacts_query_destroy(query);
2569 /* LCOV_EXCL_STOP */
2572 int _bluetooth_get_contact_addressbook(gint person_id)
2574 contacts_record_h person = NULL;
2575 contacts_record_h contact = NULL;
2576 contacts_record_h addressbook = NULL;
2578 char* addressbook_name = NULL;
2579 gint contact_id = 0;
2580 gint address_book_id = 0;
2583 status = contacts_db_get_record(_contacts_person._uri,
2586 if (status != CONTACTS_ERROR_NONE)
2587 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2589 /* LCOV_EXCL_START */
2590 status = contacts_record_get_int(person,
2591 _contacts_person.display_contact_id,
2593 contacts_record_destroy(person, TRUE);
2595 if (status != CONTACTS_ERROR_NONE)
2596 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2598 status = contacts_db_get_record(_contacts_contact._uri,
2601 if (status != CONTACTS_ERROR_NONE)
2602 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2604 status = contacts_record_get_int(contact,
2605 _contacts_contact.address_book_id,
2607 contacts_record_destroy(contact, TRUE);
2609 if (status != CONTACTS_ERROR_NONE)
2610 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2612 status = contacts_db_get_record(_contacts_address_book._uri,
2615 if (status != CONTACTS_ERROR_NONE)
2616 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2618 status = contacts_record_get_str_p(addressbook, _contacts_address_book.name,
2620 contacts_record_destroy(addressbook, TRUE);
2622 if (status != CONTACTS_ERROR_NONE)
2623 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2625 if (address_book_id == 0 || _bt_is_sim_addressbook(addressbook_name) == false)
2626 return PBAP_ADDRESSBOOK_PHONE;
2628 return PBAP_ADDRESSBOOK_SIM;
2629 /* LCOV_EXCL_STOP */
2632 gchar *_bluetooth_pb_vcard_contact(gint person_id,
2642 str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
2649 gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
2654 GString *str = g_string_new("BEGIN:VCARD\r\n");
2658 fn = _bluetooth_pb_owner_name();
2659 name = g_strdup_printf("%s;;;;", fn);
2662 case VCARD_FORMAT_3_0:
2663 g_string_append(str, "VERSION:3.0\r\n");
2665 __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
2666 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
2667 __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL",
2670 case VCARD_FORMAT_2_1:
2672 g_string_append(str, "VERSION:2.1\r\n");
2674 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
2676 if (filter == 0 || (filter & VCARD_FN))
2677 __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN",
2680 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL",
2686 g_string_append(str, "END:VCARD\r\n");
2692 return g_string_free(str, FALSE);
2695 gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
2706 ERR("Unknown attribute type ignored\n");
2710 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2712 DBG("person_id %d\n", person_id);
2715 /* LCOV_EXCL_START */
2716 if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
2717 gchar *datetime = NULL;
2719 datetime = __bluetooth_pb_phonelog_datetime(
2722 str = __bluetooth_pb_vcard_real_contact_with_properties(
2726 "X-IRMC-CALL-DATETIME", attr, datetime,
2732 str = __bluetooth_pb_vcard_real_contact_with_properties(
2738 /* LCOV_EXCL_STOP */
2740 str = __bluetooth_pb_vcard_real_call(phonelog_id, filter,
2747 gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
2750 contacts_record_h person = NULL;
2756 status = contacts_db_get_record(_contacts_person._uri,
2760 if (status != CONTACTS_ERROR_NONE)
2763 /* LCOV_EXCL_START */
2764 status = contacts_record_get_str(person,
2765 _contacts_person.display_name,
2768 if (status != CONTACTS_ERROR_NONE)
2771 contacts_record_destroy(person, TRUE);
2775 /* LCOV_EXCL_STOP */
2778 gchar *_bluetooth_pb_name_from_person_id(gint person_id)
2781 contacts_record_h person = NULL;
2782 contacts_record_h contact = NULL;
2785 gint contact_id = 0;
2789 status = contacts_db_get_record(_contacts_person._uri,
2793 if (status != CONTACTS_ERROR_NONE)
2796 /* LCOV_EXCL_START */
2797 status = contacts_record_get_int(person,
2798 _contacts_person.display_contact_id,
2801 if (status != CONTACTS_ERROR_NONE) {
2802 contacts_record_destroy(person, TRUE);
2806 status = contacts_db_get_record(_contacts_contact._uri,
2810 if (status != CONTACTS_ERROR_NONE) {
2811 contacts_record_destroy(person, TRUE);
2815 str = __bluetooth_pb_name_from_contact(contact);
2817 contacts_record_destroy(contact, TRUE);
2818 contacts_record_destroy(person, TRUE);
2819 /* LCOV_EXCL_STOP */
2825 gchar *_bluetooth_pb_number_from_person_id(gint person_id)
2828 contacts_record_h person = NULL;
2829 contacts_record_h contact = NULL;
2832 gint contact_id = 0;
2836 status = contacts_db_get_record(_contacts_person._uri,
2840 if (status != CONTACTS_ERROR_NONE)
2843 /* LCOV_EXCL_START */
2844 status = contacts_record_get_int(person,
2845 _contacts_person.display_contact_id,
2848 if (status != CONTACTS_ERROR_NONE) {
2849 contacts_record_destroy(person, TRUE);
2853 status = contacts_db_get_record(_contacts_contact._uri,
2857 if (status != CONTACTS_ERROR_NONE) {
2858 contacts_record_destroy(person, TRUE);
2862 str = __bluetooth_pb_number_from_contact(contact);
2864 contacts_record_destroy(contact, TRUE);
2865 contacts_record_destroy(person, TRUE);
2866 /* LCOV_EXCL_STOP */
2872 gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
2878 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2881 str = _bluetooth_pb_fn_from_person_id(person_id);
2889 gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
2895 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2898 str = _bluetooth_pb_name_from_person_id(person_id);
2902 tmp = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
2903 str = g_strdup_printf("%s;;;;", tmp);
2912 gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
2915 contacts_record_h phone_log;
2922 status = contacts_db_get_record(_contacts_phone_log._uri,
2923 phonelog_id, &phone_log);
2925 if (status != CONTACTS_ERROR_NONE)
2928 /* LCOV_EXCL_START */
2929 status = contacts_record_get_str_p(phone_log,
2930 _contacts_phone_log.address,
2933 if (status != CONTACTS_ERROR_NONE) {
2934 contacts_record_destroy(phone_log, TRUE);
2938 str = g_strdup(tmp);
2940 contacts_record_destroy(phone_log, TRUE);
2941 /* LCOV_EXCL_STOP */
2947 gchar *_bluetooth_pb_owner_name(void)
2952 name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
2955 name = g_strdup("My Name"); /* LCOV_EXCL_LINE */
2961 bool _bt_is_sim_addressbook(const char *addressbook)
2963 return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX);