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 <libexif/exif-data.h>
40 #include "bluetooth_pb_vcard.h"
41 #include "bluetooth_pb_agent.h"
44 #define LINEBREAK_LEN 75
50 contacts_record_h person;
54 gchar dest_thumb_path[255];
55 #define PBAP_IMAGE_THUMB_SIZE 48
56 #define PBAP_THMB_PATH "_thumb"
57 #define PBAP_THUMB_FILE_SIZE 4096
58 #define PBAP_IMAGE_ENCODE_QUALITY 90
59 #define PBAP_SECURITY_FILE_GROUP 6005
60 #define PBAP_SECURITY_DEFAULT_PERMISSION 0660
61 #define PBAP_SECURITY_DIR_DEFAULT_PERMISSION 0770
62 #define PBAP_SECURITY_IMAGE_PERMISSION 0440
64 static gchar *__bluetooth_pb_vcard_escape(const gchar *str);
66 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
67 const gchar *delimeter);
69 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str);
71 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
74 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
79 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
83 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
88 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str);
90 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
93 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
98 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
105 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
106 contacts_record_h contact);
108 static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
109 contacts_record_h contact);
111 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
112 contacts_record_h conatct);
114 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
115 contacts_record_h person);
117 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
118 contacts_record_h person);
120 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
121 contacts_record_h contact);
123 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
124 contacts_record_h contact);
126 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
127 contacts_record_h contact);
129 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
130 contacts_record_h contact);
132 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
133 contacts_record_h contact);
135 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
136 contacts_record_h contact);
138 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
139 contacts_record_h contact);
141 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
142 contacts_record_h contact);
144 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
145 contacts_record_h contact);
147 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
148 contacts_record_h contact);
150 static void __bluetooth_pb_vcard_append_v30(GString *string,
155 static void __bluetooth_pb_vcard_remove_v30(GString *string,
156 const gchar *property_name);
158 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
161 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
164 const gchar *first_name,
167 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
170 const gchar *first_name,
173 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
177 const gchar *first_name,
180 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
184 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
188 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
193 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
197 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number);
199 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename);
201 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address);
203 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address);
205 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id);
207 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
209 static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact);
211 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
213 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
215 /* LCOV_EXCL_START */
216 static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
227 escaped = g_string_new(NULL);
232 while (*pos != '\0') {
234 g_string_append_len(escaped, st, (pos - st));
235 g_string_append(escaped, "\\;");
244 g_string_append_len(escaped, st, (pos - st));
246 return g_string_free(escaped, FALSE);
249 static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
250 const gchar *separator)
253 GString *string = g_string_new(NULL);
256 for (i = 0; strv[i] != NULL; i++) {
258 g_string_append(string, ";");
260 g_string_append(string, strv[i]);
264 return g_string_free(string, FALSE);
268 static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
277 while (*pos != '\0') {
278 /* ascii code ' ' : 32, '~' : 126 */
279 if ((guchar)*pos < ' ' || (guchar)*pos > '~')
288 /* LCOV_EXCL_START */
289 /* get string length, which convert to quoted-printable encoding */
290 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
302 if (strlen(str) < len)
307 while (*pos != '\0' && (((pos - str) < length) || length < 0)) {
308 if ((guchar)*pos == '\t') {
314 if ((guchar)*pos < ' ' || (guchar)*pos == '=') {
320 /* check no-ascii utf-8 character */
321 if ((guchar)*pos > '~') {
325 next = g_utf8_next_char(pos);
327 count += QP_ENC_LEN * (next - pos);
340 /* convert to quoted printable code */
341 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
349 if (str == NULL || len == 0)
352 /* add soft linebreak when it exceed */
353 if ((*line_pos + (QP_ENC_LEN * len) > LINEBREAK_LEN)) {
354 g_string_append(string, "=\r\n");
358 for (i = 0; i < len; i++) {
359 g_string_append_printf(string, "=%02X", (guchar)*(str+i));
360 *line_pos += QP_ENC_LEN;
365 /* append plain visiable ascii character */
366 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
371 /* add soft linebreak when it exceed */
372 if (*line_pos + 1 > LINEBREAK_LEN) {
373 g_string_append(string, "=\r\n");
376 g_string_append_c(string, ch);
381 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
394 encode_len = __bluetooth_pb_vcard_qp_encode_strlen(str, len);
396 /* add soft linebreak when it exceed */
397 if (((*line_pos + encode_len) > LINEBREAK_LEN) && (*line_pos > 1)) {
398 g_string_append(string, "=\r\n");
405 pos = ((gchar *)str) + i;
407 /* converts invisiable character and escape character '='
408 to quoted-printable */
409 if ((guchar)*pos != '\t' &&
410 ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
411 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
418 /* converts non-ascii utf-8 character to quoted-printable */
419 if ((guchar)*pos > '~') {
423 next = g_utf8_next_char(pos);
426 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
427 pos, ch_len, line_pos);
433 __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos,
440 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str)
453 enc = g_string_new(NULL);
455 st_pos = (gchar *)str;
458 while (*pos != '\0') {
459 /* split string with given delimeter ' ' or '\t' */
460 if (*pos == ' ' || *pos == '\t') {
461 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
462 (pos - st_pos), &line_pos);
470 /* split string with given delimeter '\r', '\n' or
472 if (*pos == '\r' || *pos == '\n') {
473 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
474 (pos - st_pos), &line_pos);
476 /* converts newline to qp_encode with soft linebreak
477 for example, converts \r\n to =0D=0A=\r\n */
478 __bluetooth_pb_vcard_qp_encode_append_to_hex(enc,
479 "\r\n", 2, &line_pos);
480 g_string_append(enc, "=\r\n ");
484 if (*pos == '\r' && *(pos + 1) == '\n')
497 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
498 (pos - st_pos), &line_pos);
501 return g_string_free(enc, FALSE);
505 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
514 pos = (gchar *)param;
516 /* trim ';' on first */
517 while (*pos != '\0') {
525 g_string_append_printf(string, ";%s", pos);
529 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
535 GString *property = NULL;
540 property = g_string_new(name);
541 __bluetooth_pb_vcard_append_param_v21(property, param);
543 if (__bluetooth_pb_vcard_qp_encode_check(value)) {
544 /* LCOV_EXCL_START */
547 __bluetooth_pb_vcard_append_param_v21(property,
549 __bluetooth_pb_vcard_append_param_v21(property,
550 "ENCODING=QUOTED-PRINTABLE");
551 g_string_append(property, ":");
553 enc = __bluetooth_pb_vcard_qp_encode(value);
556 g_string_append(property, enc);
561 g_string_append(property, ":");
563 g_string_append(property , value);
566 g_string_append_printf(string, "%s\r\n", property->str);
568 g_string_free(property, TRUE);
572 /* LCOV_EXCL_START */
573 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
585 DBG("base 64 encoding\n");
587 g_string_append(string, name);
589 __bluetooth_pb_vcard_append_param_v21(string, param);
590 __bluetooth_pb_vcard_append_param_v21(string, "ENCODING=BASE64");
592 g_string_append(string, ":");
597 enc = g_base64_encode((const guchar *)value, len);
599 if (folding == FALSE) {
600 g_string_append(string, enc);
602 gint enc_len = strlen(enc);
605 /* count ' ' size for folding */
606 gint fline_len = LINEBREAK_LEN - 1;
608 for (i = 0; (i * fline_len) < enc_len; i++) {
609 g_string_append(string, "\r\n ");
610 if ((i * fline_len) + fline_len > enc_len)
611 g_string_append(string, enc + (i * fline_len));
613 g_string_append_len(string, enc +
614 (i * fline_len), fline_len);
617 /* some application requires more \r\n */
618 g_string_append(string, "\r\n");
620 g_string_append(string, "\r\n");
621 DBG("base 64 encoding\n");
627 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
628 contacts_record_h contact)
633 str = __bluetooth_pb_name_from_contact(contact);
634 __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
640 static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
641 contacts_record_h contact)
646 str = __bluetooth_pb_phonetic_name_from_contact(contact);
649 __bluetooth_pb_vcard_append_qp_encode_v21(string, "SOUND", "X-IRMC-N", str);
655 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
656 contacts_record_h contact)
664 status = contacts_record_get_child_record_count(contact,
665 _contacts_contact.number,
668 if (status != CONTACTS_ERROR_NONE)
671 for (i = 0; i < count; i++) {
672 contacts_record_h number = NULL;
674 gchar **paramv = NULL;
678 gchar *escaped = NULL;
680 status = contacts_record_get_child_record_at_p(contact,
681 _contacts_contact.number, i, &number);
683 if (status != CONTACTS_ERROR_NONE)
686 status = contacts_record_get_str_p(number,
687 _contacts_number.number,
690 if (status != CONTACTS_ERROR_NONE)
693 escaped = __bluetooth_pb_vcard_escape(tel);
695 paramv = __bluetooth_pb_contact_tel_param(number);
697 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
699 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param,
709 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
710 contacts_record_h person)
718 status = contacts_record_get_str_p(person,
719 _contacts_person.display_name,
722 if (status != CONTACTS_ERROR_NONE)
725 fn = __bluetooth_pb_vcard_escape(tmp);
727 __bluetooth_pb_vcard_append_qp_encode_v21(string, "FN", NULL, fn);
733 /* image util APIs will be deprecated in Tizen 5.0. So we should replace it to new API
734 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#decode
735 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#encode
738 static image_util_rotation_e __bt_pbap_get_rotation_info(const char *path)
743 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
746 ed = exif_data_new_from_file(path);
748 ERR("exif_data_new_from_file : ExifData is NULL");
749 return IMAGE_UTIL_ROTATION_NONE;
752 entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
754 ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
755 orientation = (int)exif_get_short(entry->data, mByteOrder);
756 if (orientation < 0 || orientation > 8)
762 switch (orientation) {
763 case 1: /* Top-left */
764 rotation = IMAGE_UTIL_ROTATION_NONE;
766 case 2: /* Top-right */
767 rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
769 case 3: /* Bottom-right */
770 rotation = IMAGE_UTIL_ROTATION_180;
772 case 4: /* Bottom-left */
773 rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
775 case 6: /* Right-top */
776 rotation = IMAGE_UTIL_ROTATION_90;
778 case 8: /* Left-bottom */
779 rotation = IMAGE_UTIL_ROTATION_270;
781 case 5: /* Left-top */
782 case 7: /* Right-bottom */
793 static bool __bt_pbap_image_util_supported_jpeg_colorspace_cb(
794 image_util_colorspace_e colorspace, void *user_data)
797 unsigned char *img_target = 0;
798 unsigned char *img_source = 0;
801 gchar *contents = NULL;
804 int resized_width = 0;
805 int resized_height = 0;
807 unsigned int size_decode = 0;
808 image_util_rotation_e rotation;
809 image_util_error_e ret = 0;
812 bt_image_info_t *info = (bt_image_info_t *)user_data;
813 rotation = __bt_pbap_get_rotation_info(info->src);
814 ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width,
815 &height, &size_decode);
816 if (ret != IMAGE_UTIL_ERROR_NONE) {
817 ERR("Can not decode");
818 memset(info, 0x00, sizeof(bt_image_info_t));
822 DBG("decoding completed width = %d, height = %d, size = %d\n", width,
823 height, size_decode);
824 if (width > PBAP_IMAGE_THUMB_SIZE || height > PBAP_IMAGE_THUMB_SIZE) {
825 if (width <= 0 || height <= 0) {
827 ERR("image size error(%d)", PBAP_IMAGE_THUMB_SIZE);
828 memset(info, 0x00, sizeof(bt_image_info_t));
832 if (width > height) {
833 resized_width = PBAP_IMAGE_THUMB_SIZE ;
834 resized_height = height * PBAP_IMAGE_THUMB_SIZE / width;
836 resized_height = PBAP_IMAGE_THUMB_SIZE;
837 resized_width = width * PBAP_IMAGE_THUMB_SIZE / height;
840 if (resized_height % 8)
841 resized_height += 8 - (resized_height % 8);
842 if (resized_width % 8)
843 resized_width += 8 - (resized_width % 8);
845 DBG("original size[%d, %d] changed to resize[%d,%d]", width,
846 height, resized_width, resized_height);
848 ret = image_util_calculate_buffer_size(resized_width,
853 img_target = g_malloc0(size_decode);
856 ret = image_util_resize(img_target, &resized_width,
857 &resized_height, img_source, width,
859 if (ret != IMAGE_UTIL_ERROR_NONE) {
860 ERR("image_util_resize failed(%d)", ret);
863 memset(info, 0x00, sizeof(bt_image_info_t));
868 resized_width = width;
869 resized_height = height;
870 img_target = img_source;
872 DBG("Resized w = %d, ht = %d, size = %d\n", width, height, size_decode);
874 if (IMAGE_UTIL_ROTATION_NONE != rotation) {
875 int rotated_width, rotated_height;
876 unsigned char *img_rotate = 0;
877 img_rotate = g_malloc0(size_decode);
878 ret = image_util_rotate(img_rotate, &rotated_width, &rotated_height,
879 rotation, img_target, resized_width,
880 resized_height, colorspace);
882 ERR("image_util_rotate failed");
883 resized_width = rotated_width;
884 resized_height = rotated_height;
886 img_target = img_rotate;
890 ret = image_util_encode_jpeg(img_target, resized_width, resized_height,
891 colorspace, PBAP_IMAGE_ENCODE_QUALITY,
894 if (ret != IMAGE_UTIL_ERROR_NONE) {
895 ERR("image_util_encode_jpeg failed(%d)", ret);
896 info->ret = CONTACTS_ERROR_INTERNAL;
899 DBG("Encoding done\n");
901 dest_fd = open(info->dest, O_RDONLY);
903 ERR("System : Open Failed(%d)", errno);
904 ERR_SECURE("Open : dest path(%s)", info->dest);
908 ret = fchown(dest_fd, getuid(), PBAP_SECURITY_FILE_GROUP);
910 ERR("fchown Failed(%d)", errno);
911 DBG_SECURE("fchown : dest path(%s)", info->dest);
916 ret = fchmod(dest_fd, PBAP_SECURITY_IMAGE_PERMISSION);
918 ERR("fchmod Failed(%d)", errno);
919 ERR_SECURE("fchmod : dest path(%s)", info->dest);
925 info->ret = CONTACTS_ERROR_NONE;
926 type = __bluetooth_pb_contact_photo_type(info->dest);
927 DBG("Cintact image thumb type is = %s\n", type);
930 param = g_strdup_printf("TYPE=%s", type);
934 if (g_file_get_contents(info->dest, &contents, &len, NULL) == FALSE) {
935 ERR("can not read file contents:%s\n", info->dest);
939 __bluetooth_pb_vcard_append_base64_encode_v21(info->string,
940 "PHOTO", param, contents, len, TRUE);
946 memset(info, 0x00, sizeof(bt_image_info_t));
947 DBG("Cintact image thumb created successfuly\n");
953 /* LCOV_EXCL_START */
954 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
955 contacts_record_h person)
959 gchar *filename = NULL;
960 struct stat stat_info;
963 gchar *contents = NULL;
967 status = contacts_record_get_str_p(person,
968 _contacts_person.image_thumbnail_path,
971 if (status != CONTACTS_ERROR_NONE || NULL == filename)
974 stat_info.st_size = 0;
976 if (0 > stat(filename, &stat_info))
977 ERR("fstat failed, file does not exist %s", filename);
979 if (PBAP_THUMB_FILE_SIZE > stat_info.st_size) {
980 DBG_SECURE("File size small, so use thubnail %s\n", filename);
982 type = __bluetooth_pb_contact_photo_type(filename);
984 param = g_strdup_printf("TYPE=%s", type);
988 if (g_file_get_contents(filename, &contents, &len, NULL) ==
990 ERR("can not read file contents:%s\n", filename);
994 DBG("Retrieved the contents of the file \n");
995 __bluetooth_pb_vcard_append_base64_encode_v21(string,
996 "PHOTO", param, contents, len, TRUE);
1003 ptr = strrchr(filename, '.');
1005 memset(dest_thumb_path, 0x00, sizeof(dest_thumb_path));
1006 g_strlcpy(dest_thumb_path, filename, ptr - filename);
1007 g_strlcat(dest_thumb_path, PBAP_THMB_PATH,
1008 sizeof(dest_thumb_path));
1009 g_strlcat(dest_thumb_path, ptr, sizeof(dest_thumb_path));
1010 DBG("Thumbnail path is = %s", dest_thumb_path);
1012 DBG_SECURE("filename = %s Thumbnail path is = %s", filename, dest_thumb_path);
1014 /* image_util_foreach_supported_jpeg_colorspace API will be deprecated in Tizen 5.0. So we should replace it to new API
1015 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#decode
1016 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#encode
1019 bt_image_info_t img_info;
1022 img_info.src = filename;
1023 img_info.dest = dest_thumb_path;
1024 img_info.ret = CONTACTS_ERROR_INTERNAL;
1025 img_info.person = person;
1026 img_info.string = string;
1028 res = image_util_foreach_supported_jpeg_colorspace(
1029 __bt_pbap_image_util_supported_jpeg_colorspace_cb, &img_info);
1031 if (res != IMAGE_UTIL_ERROR_NONE)
1032 ERR("Image resizing is failed");
1038 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
1039 contacts_record_h contact)
1047 status = contacts_record_get_child_record_count(contact,
1048 _contacts_contact.event, &count);
1050 if (status != CONTACTS_ERROR_NONE)
1053 for (i = 0; i < count; i++) {
1054 contacts_record_h event = NULL;
1060 contacts_event_type_e type;
1062 status = contacts_record_get_child_record_at_p(contact,
1063 _contacts_contact.event, i, &event);
1065 if (status != CONTACTS_ERROR_NONE)
1068 status = contacts_record_get_int(event,
1069 _contacts_event.type,
1072 if (status != CONTACTS_ERROR_NONE)
1075 if (type != CONTACTS_EVENT_TYPE_BIRTH)
1078 status = contacts_record_get_int(event,
1079 _contacts_event.date,
1082 if (status != CONTACTS_ERROR_NONE)
1088 bday = g_strdup_printf("%04d-%02d-%02d",
1089 (date/10000), (date/100)%100, date%100);
1090 __bluetooth_pb_vcard_append_qp_encode_v21(string, "BDAY",
1097 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
1098 contacts_record_h contact)
1106 status = contacts_record_get_child_record_count(contact,
1107 _contacts_contact.address,
1110 if (status != CONTACTS_ERROR_NONE)
1113 for (i = 0; i < count; i++) {
1114 contacts_record_h address = NULL;
1122 status = contacts_record_get_child_record_at_p(contact,
1123 _contacts_contact.address, i, &address);
1125 if (status != CONTACTS_ERROR_NONE)
1128 addrv = __bluetooth_pb_contact_addr(address);
1133 addr = __bluetooth_pb_vcard_strv_concat(addrv, ";");
1136 paramv = __bluetooth_pb_contact_addr_param(address);
1138 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
1141 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
1151 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
1152 contacts_record_h contact)
1160 status = contacts_record_get_child_record_count(contact,
1161 _contacts_contact.email,
1164 if (status != CONTACTS_ERROR_NONE)
1167 for (i = 0; i < count; i++) {
1168 contacts_record_h email = NULL;
1173 status = contacts_record_get_child_record_at_p(contact,
1174 _contacts_contact.email, i, &email);
1176 if (status != CONTACTS_ERROR_NONE)
1179 status = contacts_record_get_str_p(email,
1180 _contacts_email.email,
1183 if (status != CONTACTS_ERROR_NONE)
1186 escaped = __bluetooth_pb_vcard_escape(tmp);
1187 __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL,
1195 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
1196 contacts_record_h contact)
1204 status = contacts_record_get_child_record_count(contact,
1205 _contacts_contact.company,
1208 if (status != CONTACTS_ERROR_NONE)
1211 for (i = 0; i < count; i++) {
1212 contacts_record_h company = NULL;
1217 status = contacts_record_get_child_record_at_p(contact,
1218 _contacts_contact.company, i, &company);
1220 if (status != CONTACTS_ERROR_NONE)
1223 status = contacts_record_get_str_p(company,
1224 _contacts_company.job_title,
1227 if (status != CONTACTS_ERROR_NONE)
1230 escaped = __bluetooth_pb_vcard_escape(title);
1231 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL,
1239 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
1240 contacts_record_h contact)
1248 status = contacts_record_get_child_record_count(contact,
1249 _contacts_contact.company,
1252 if (status != CONTACTS_ERROR_NONE)
1255 for (i = 0; i < count; i++) {
1256 contacts_record_h company = NULL;
1261 status = contacts_record_get_child_record_at_p(contact,
1262 _contacts_contact.company, i, &company);
1264 if (status != CONTACTS_ERROR_NONE)
1267 status = contacts_record_get_str_p(company,
1268 _contacts_company.role,
1271 if (status != CONTACTS_ERROR_NONE)
1274 escaped = __bluetooth_pb_vcard_escape(role);
1275 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL,
1283 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
1284 contacts_record_h contact)
1292 status = contacts_record_get_child_record_count(contact,
1293 _contacts_contact.company,
1296 if (status != CONTACTS_ERROR_NONE)
1299 for (i = 0; i < count; i++) {
1300 contacts_record_h company = NULL;
1305 gchar *department = NULL;
1308 gint department_status;
1310 status = contacts_record_get_child_record_at_p(contact,
1311 _contacts_contact.company, i, &company);
1313 if (status != CONTACTS_ERROR_NONE)
1317 name_status = contacts_record_get_str_p(company,
1318 _contacts_company.name,
1321 department_status = contacts_record_get_str_p(company,
1322 _contacts_company.department,
1325 if ((name_status != CONTACTS_ERROR_NONE) &&
1326 (department_status != CONTACTS_ERROR_NONE))
1329 str = g_string_new(NULL);
1334 escaped = __bluetooth_pb_vcard_escape(name);
1335 g_string_append(str, escaped);
1339 g_string_append(str, ";");
1344 escaped = __bluetooth_pb_vcard_escape(department);
1345 g_string_append(str, escaped);
1349 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL,
1352 g_string_free(str, TRUE);
1358 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
1359 contacts_record_h contact)
1367 status = contacts_record_get_child_record_count(contact,
1368 _contacts_contact.note,
1371 if (status != CONTACTS_ERROR_NONE)
1374 for (i = 0; i < count; i++) {
1375 contacts_record_h note = NULL;
1380 status = contacts_record_get_child_record_at_p(contact,
1381 _contacts_contact.note, i, ¬e);
1383 if (status != CONTACTS_ERROR_NONE)
1386 status = contacts_record_get_str_p(note,
1387 _contacts_note.note,
1390 if (status != CONTACTS_ERROR_NONE)
1393 escaped = __bluetooth_pb_vcard_escape(tmp);
1394 __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL,
1402 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
1403 contacts_record_h contact)
1412 status = contacts_record_get_int(contact,
1413 _contacts_contact.changed_time,
1416 if (status != CONTACTS_ERROR_NONE)
1422 gmtime_r((const time_t *)(&time), &result);
1424 rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
1425 (1900 + result.tm_year), (1 + result.tm_mon),
1426 result.tm_mday, result.tm_hour, result.tm_min,
1429 __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
1435 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
1436 contacts_record_h contact)
1444 status = contacts_record_get_child_record_count(contact,
1445 _contacts_contact.url,
1448 if (status != CONTACTS_ERROR_NONE)
1451 for (i = 0; i < count; i++) {
1452 contacts_record_h url = NULL;
1457 status = contacts_record_get_child_record_at_p(contact,
1458 _contacts_contact.url, i, &url);
1460 if (status != CONTACTS_ERROR_NONE)
1466 status = contacts_record_get_str_p(url,
1470 if (status != CONTACTS_ERROR_NONE)
1473 escaped = __bluetooth_pb_vcard_escape(tmp);
1474 __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL,
1482 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
1483 contacts_record_h contact)
1491 status = contacts_record_get_str_p(contact,
1492 _contacts_contact.uid,
1495 if (status != CONTACTS_ERROR_NONE)
1498 escaped = __bluetooth_pb_vcard_escape(uid);
1499 __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
1504 /* LCOV_EXCL_STOP */
1506 static void __bluetooth_pb_vcard_append_v30(GString *string,
1517 g_string_append(string, name);
1520 g_string_append_printf(string, ";%s", param);
1522 g_string_append(string, ":");
1525 g_string_append(string, value);
1527 g_string_append(string, "\r\n");
1531 /* LCOV_EXCL_START */
1532 static void __bluetooth_pb_vcard_remove_v30(GString *string,
1533 const gchar *property_name)
1537 gchar *st_pos = NULL;
1539 gboolean matched = FALSE;
1541 if (string == NULL || property_name == NULL)
1546 while (*pos != '\0') {
1547 if (matched == FALSE) {
1548 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1554 attrlen = strlen(property_name);
1555 if (g_ascii_strncasecmp(pos, property_name,
1559 if (*pos == ':' || *pos == ';') {
1567 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1570 if (*pos != ' ' && *pos != '\t') {
1571 /* +2 means move over \r\n */
1572 g_string_erase(string,
1573 (st_pos+2)-(string->str),
1588 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
1592 GString *string = NULL;
1597 string = g_string_new(vcard);
1599 if ((filter & VCARD_BDAY) == 0)
1600 __bluetooth_pb_vcard_remove_v30(string, "BDAY");
1602 if ((filter & VCARD_ADR) == 0)
1603 __bluetooth_pb_vcard_remove_v30(string, "ADR");
1605 if ((filter & VCARD_EMAIL) == 0)
1606 __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
1608 if ((filter & VCARD_TITLE) == 0)
1609 __bluetooth_pb_vcard_remove_v30(string, "TITLE");
1611 if ((filter & VCARD_ROLE) == 0)
1612 __bluetooth_pb_vcard_remove_v30(string, "ROLE");
1614 if ((filter & VCARD_ORG) == 0)
1615 __bluetooth_pb_vcard_remove_v30(string, "ORG");
1617 if ((filter & VCARD_NOTE) == 0)
1618 __bluetooth_pb_vcard_remove_v30(string, "NOTE");
1620 if ((filter & VCARD_REV) == 0)
1621 __bluetooth_pb_vcard_remove_v30(string, "REV");
1623 if ((filter & VCARD_URL) == 0)
1624 __bluetooth_pb_vcard_remove_v30(string, "URL");
1626 if ((filter & VCARD_UID) == 0)
1627 __bluetooth_pb_vcard_remove_v30(string, "UID");
1629 if ((filter & VCARD_NICKNAME) == 0)
1630 __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
1633 return g_string_free(string, FALSE);
1636 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
1639 const gchar *first_name,
1643 contacts_record_h person = NULL;
1644 contacts_record_h contact = NULL;
1646 GString *str = NULL;
1648 gint contact_id = 0;
1653 const gchar *name = first_name;
1655 status = contacts_db_get_record(_contacts_person._uri,
1659 if (status != CONTACTS_ERROR_NONE)
1662 status = contacts_record_get_int(person,
1663 _contacts_person.display_contact_id,
1666 if (status != CONTACTS_ERROR_NONE)
1669 status = contacts_db_get_record(_contacts_contact._uri,
1673 if (status != CONTACTS_ERROR_NONE) {
1674 contacts_record_destroy(person, TRUE);
1681 DBG("filter[%llu]\n", (unsigned long long int)filter);
1683 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1685 /* N, TEL is default */
1686 __bluetooth_pb_vcard_append_n_v21(str, contact);
1688 if (phonelog_id > 0) {
1691 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1692 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0",
1698 __bluetooth_pb_vcard_append_tel_v21(str, contact);
1702 __bluetooth_pb_vcard_append_fn_v21(str, person);
1703 /* Need to check filter
1704 if (f & VCARD_SOUND)*/
1705 __bluetooth_pb_vcard_append_phonetic_first_v21(str, contact);
1706 if (f & VCARD_PHOTO)
1707 __bluetooth_pb_vcard_append_photo_v21(str, person);
1709 __bluetooth_pb_vcard_append_bday_v21(str, contact);
1711 __bluetooth_pb_vcard_append_adr_v21(str, contact);
1712 if (f & VCARD_EMAIL)
1713 __bluetooth_pb_vcard_append_email_v21(str, contact);
1714 if (f & VCARD_TITLE)
1715 __bluetooth_pb_vcard_append_title_v21(str, contact);
1717 __bluetooth_pb_vcard_append_role_v21(str, contact);
1719 __bluetooth_pb_vcard_append_org_v21(str, contact);
1721 __bluetooth_pb_vcard_append_note_v21(str, contact);
1723 __bluetooth_pb_vcard_append_rev_v21(str, contact);
1725 __bluetooth_pb_vcard_append_url_v21(str, contact);
1727 __bluetooth_pb_vcard_append_uid_v21(str, contact);
1730 const gchar *param = va_arg(args, const gchar *);
1731 const gchar *value = va_arg(args, const gchar *);
1734 gchar *escaped = NULL;
1736 escaped = __bluetooth_pb_vcard_escape(value);
1737 __bluetooth_pb_vcard_append_qp_encode_v21(str, name,
1743 name = va_arg(args, const gchar *);
1746 g_string_append(str, "END:VCARD\r\n");
1748 contacts_record_destroy(contact, TRUE);
1749 contacts_record_destroy(person, TRUE);
1752 return g_string_free(str, FALSE);
1754 /* LCOV_EXCL_STOP */
1756 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
1759 const gchar *first_name,
1763 contacts_record_h person = NULL;
1765 GString *str = NULL;
1769 const gchar *name = first_name;
1770 gchar *vcard = NULL;
1772 status = contacts_db_get_record(_contacts_person._uri,
1776 if (status != CONTACTS_ERROR_NONE)
1779 /* LCOV_EXCL_START */
1780 status = contacts_vcard_make_from_person(person, &vcard);
1782 if (status != CONTACTS_ERROR_NONE)
1785 /* removing the END:VCARD\r\n" to append extra data */
1786 str = g_string_new_len(vcard, (strlen(vcard)-11));
1789 /* append contents on vcard */
1791 const gchar *param = va_arg(args, const gchar *);
1792 const gchar *value = va_arg(args, const gchar *);
1794 __bluetooth_pb_vcard_append_v30(str, name, param, value);
1796 name = va_arg(args, const gchar *);
1799 /* if phonelog_id exist, we shall show only the phone number, which was
1800 used for that phone log */
1801 if (phonelog_id > 0) {
1804 __bluetooth_pb_vcard_remove_v30(str, "TEL");
1806 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1807 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1811 /* Remove Full contact image and add thumbnail image */
1812 __bluetooth_pb_vcard_remove_v30(str, "PHOTO");
1813 if (filter & VCARD_PHOTO)
1814 __bluetooth_pb_vcard_append_photo_v21(str, person); /* Photo is same as vCard 2.1 */
1816 /* Destroy contact record */
1817 status = contacts_record_destroy(person, TRUE);
1818 if (status != CONTACTS_ERROR_NONE)
1819 ERR("Failed to destroy person");
1821 g_string_append(str, "END:VCARD\r\n");
1823 vcard = g_string_free(str, FALSE);
1825 /* temporary fixed for some application crash */
1827 filter = ~VCARD_NOTE;
1830 gchar *new_vcard = NULL;
1832 new_vcard = __bluetooth_pb_vcard_filter_v30(vcard, filter);
1842 /* LCOV_EXCL_STOP */
1846 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
1850 const gchar *first_name,
1854 DBG(" format [%d]\n", format);
1855 gchar *vcard = NULL;
1858 va_start(args, first_name);
1861 case VCARD_FORMAT_3_0:
1862 vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
1863 phonelog_id, filter,
1866 case VCARD_FORMAT_2_1:
1868 vcard = __bluetooth_pb_vcard_real_contact_valist_v21(person_id,
1869 phonelog_id, filter,
1880 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
1888 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1890 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, NULL);
1892 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1893 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
1896 /* LCOV_EXCL_START */
1897 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1899 gchar *datetime = NULL;
1901 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1902 __bluetooth_pb_vcard_append_qp_encode_v21(str,
1903 "X-IRMC-CALL-DATETIME",
1907 /* LCOV_EXCL_STOP */
1909 g_string_append(str, "END:VCARD\r\n");
1912 return g_string_free(str, FALSE);
1915 /* LCOV_EXCL_START */
1916 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
1924 str = g_string_new("BEGIN:VCARD\r\nVERSION:3.0\r\n");
1926 __bluetooth_pb_vcard_append_v30(str, "N", NULL, NULL);
1927 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, NULL);
1929 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1930 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1933 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1935 gchar *datetime = NULL;
1937 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1938 __bluetooth_pb_vcard_append_v30(str,
1939 "X-IRMC-CALL-DATETIME", attr, datetime);
1943 g_string_append(str, "END:VCARD\r\n");
1946 return g_string_free(str, FALSE);
1948 /* LCOV_EXCL_STOP */
1950 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
1956 gchar *vcard = NULL;
1959 case VCARD_FORMAT_3_0:
1960 vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
1963 case VCARD_FORMAT_2_1:
1965 vcard = __bluetooth_pb_vcard_real_call_v21(phonelog_id,
1974 /* LCOV_EXCL_START */
1975 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
1985 gboolean valid = FALSE;
1987 /* check empty field */
1988 for (i = 0; i < field_size; i++) {
1991 status = contacts_record_get_str_p(record, field[i], &tmp);
1993 if (status != CONTACTS_ERROR_NONE)
2005 strv = g_new0(gchar *, field_size + 1);
2007 for (i = 0; i < field_size; i++) {
2010 status = contacts_record_get_str_p(record, field[i], &tmp);
2012 if (status != CONTACTS_ERROR_NONE)
2016 strv[i] = g_strdup("");
2018 strv[i] = __bluetooth_pb_vcard_escape(tmp);
2025 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
2028 gchar **strv = NULL;
2030 const gint TEL_PARAM_LEN = 13;
2035 contacts_number_type_e type;
2037 bool is_default = false;
2039 status = contacts_record_get_bool(number, _contacts_number.is_default,
2042 if (status != CONTACTS_ERROR_NONE)
2045 status = contacts_record_get_int(number,
2046 _contacts_number.type,
2049 if (status != CONTACTS_ERROR_NONE)
2052 strv = g_new0(char *, TEL_PARAM_LEN + 1);/* tel param max size is 13 */
2055 strv[i] = g_strdup("PREF");
2059 if (type & CONTACTS_NUMBER_TYPE_HOME) {
2060 strv[i] = g_strdup("HOME");
2064 if (type & CONTACTS_NUMBER_TYPE_WORK) {
2065 strv[i] = g_strdup("WORK");
2069 if (type & CONTACTS_NUMBER_TYPE_VOICE) {
2070 strv[i] = g_strdup("VOICE");
2074 if (type & CONTACTS_NUMBER_TYPE_FAX) {
2075 strv[i] = g_strdup("FAX");
2079 if (type & CONTACTS_NUMBER_TYPE_MSG) {
2080 strv[i] = g_strdup("MSG");
2084 if (type & CONTACTS_NUMBER_TYPE_CELL) {
2085 strv[i] = g_strdup("CELL");
2089 if (type & CONTACTS_NUMBER_TYPE_PAGER) {
2090 strv[i] = g_strdup("PAGER");
2094 if (type & CONTACTS_NUMBER_TYPE_BBS) {
2095 strv[i] = g_strdup("BBS");
2099 if (type & CONTACTS_NUMBER_TYPE_MODEM) {
2100 strv[i] = g_strdup("MODEM");
2104 if (type & CONTACTS_NUMBER_TYPE_CAR) {
2105 strv[i] = g_strdup("CAR");
2109 if (type & CONTACTS_NUMBER_TYPE_ISDN) {
2110 strv[i] = g_strdup("ISDN");
2114 if (type & CONTACTS_NUMBER_TYPE_VIDEO) {
2115 strv[i] = g_strdup("VIDEO");
2119 /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
2125 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
2128 gchar *filetype = NULL;
2131 if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
2132 ERR_SECURE("file does not regular:%s\n", filename);
2136 ext = strrchr(filename, '.');
2138 ERR("file doesn't have extension\n");
2144 if (g_ascii_strcasecmp(ext, "gif") == 0)
2146 else if (g_ascii_strcasecmp(ext, "cgm") == 0)
2148 else if (g_ascii_strcasecmp(ext, "wmf") == 0)
2150 else if (g_ascii_strcasecmp(ext, "bmp") == 0)
2152 else if (g_ascii_strcasecmp(ext, "met") == 0)
2154 else if (g_ascii_strcasecmp(ext, "dib") == 0)
2156 else if (g_ascii_strcasecmp(ext, "pict") == 0 ||
2157 g_ascii_strcasecmp(ext, "pct") == 0 ||
2158 g_ascii_strcasecmp(ext, "pic") == 0)
2160 else if (g_ascii_strcasecmp(ext, "tiff") == 0 ||
2161 g_ascii_strcasecmp(ext, "tif") == 0)
2163 else if (g_ascii_strcasecmp(ext, "ps") == 0)
2165 else if (g_ascii_strcasecmp(ext, "pdf") == 0)
2167 else if (g_ascii_strcasecmp(ext, "jpeg") == 0 ||
2168 g_ascii_strcasecmp(ext, "jpg") == 0 ||
2169 g_ascii_strcasecmp(ext, "jpe") == 0)
2171 else if (g_ascii_strcasecmp(ext, "mpeg") == 0 ||
2172 g_ascii_strcasecmp(ext, "mpg") == 0)
2174 else if (g_ascii_strcasecmp(ext, "m2v") == 0)
2176 else if (g_ascii_strcasecmp(ext, "avi") == 0)
2178 else if (g_ascii_strcasecmp(ext, "mov") == 0)
2180 else if (g_ascii_strcasecmp(ext, "png") == 0)
2184 return g_strdup(filetype);
2187 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
2190 const gint ADDR_LEN = 7;
2192 gchar **strv = NULL;
2194 gint addr[] = { _contacts_address.postbox,
2195 _contacts_address.extended,
2196 _contacts_address.street,
2197 _contacts_address.locality,
2198 _contacts_address.region,
2199 _contacts_address.postal_code,
2200 _contacts_address.country };
2202 strv = __bluetooth_pb_contact_add_field_str(address,
2208 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
2211 contacts_address_type_e type;
2216 gchar **strv = NULL;
2218 status = contacts_record_get_int(address,
2219 _contacts_address.type,
2222 if (status != CONTACTS_ERROR_NONE)
2225 strv = g_new0(gchar *, 7); /* ADDR param max size is 6 */
2227 if (type & CONTACTS_ADDRESS_TYPE_HOME) {
2228 strv[i] = g_strdup("HOME");
2231 if (type & CONTACTS_ADDRESS_TYPE_WORK) {
2232 strv[i] = g_strdup("WORK");
2235 if (type & CONTACTS_ADDRESS_TYPE_DOM) {
2236 strv[i] = g_strdup("DOM");
2239 if (type & CONTACTS_ADDRESS_TYPE_INTL) {
2240 strv[i] = g_strdup("INTL");
2243 if (type & CONTACTS_ADDRESS_TYPE_POSTAL) {
2244 strv[i] = g_strdup("POSTAL");
2247 if (type & CONTACTS_ADDRESS_TYPE_PARCEL) {
2248 strv[i] = g_strdup("PARCEL");
2255 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
2258 contacts_record_h phone_log;
2260 char time_str[32] = {0,};
2265 struct tm time_info;
2267 status = contacts_db_get_record(_contacts_phone_log._uri,
2271 if (status != CONTACTS_ERROR_NONE)
2274 status = contacts_record_get_int(phone_log,
2275 _contacts_phone_log.log_time,
2278 if (status != CONTACTS_ERROR_NONE)
2284 localtime_r((time_t *)&time, &time_info);
2286 strftime(time_str, sizeof(time_str),
2287 "%Y%m%dT%H%M%S", &time_info);
2289 contacts_record_destroy(phone_log, TRUE);
2292 return g_strdup(time_str);
2295 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
2298 contacts_record_h name = NULL;
2305 gint name_val[] = { _contacts_name.last,
2306 _contacts_name.first,
2307 _contacts_name.addition,
2308 _contacts_name.prefix,
2309 _contacts_name.suffix };
2312 status = contacts_record_get_child_record_at_p(contact,
2313 _contacts_contact.name, 0, &name);
2315 if (status != CONTACTS_ERROR_NONE)
2318 str = g_string_new(NULL);
2320 for (i = 0; i < name_size; i++) {
2322 gchar *escape = NULL;
2325 g_string_append_c(str, ';');
2327 status = contacts_record_get_str_p(name, name_val[i], &tmp);
2329 if (status != CONTACTS_ERROR_NONE)
2332 escape = __bluetooth_pb_vcard_escape(tmp);
2333 g_string_append(str, escape);
2339 return g_string_free(str, FALSE);
2342 static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact)
2345 contacts_record_h name = NULL;
2351 gchar *phonetic_first = NULL;
2352 gchar *phonetic_last = NULL;
2353 gchar *escape = NULL;
2355 status = contacts_record_get_child_record_at_p(contact,
2356 _contacts_contact.name, 0, &name);
2358 if (status != CONTACTS_ERROR_NONE)
2361 status = contacts_record_get_str_p(name, _contacts_name.phonetic_first, &phonetic_first);
2363 if (status != CONTACTS_ERROR_NONE)
2366 if (phonetic_first == NULL)
2369 str = g_string_new(NULL);
2371 status = contacts_record_get_str_p(name, _contacts_name.phonetic_last, &phonetic_last);
2373 if ((status == CONTACTS_ERROR_NONE) && (phonetic_last != NULL)) {
2374 escape = __bluetooth_pb_vcard_escape(phonetic_last);
2375 g_string_append(str, escape);
2377 g_string_append_c(str, ' ');
2380 escape = __bluetooth_pb_vcard_escape(phonetic_first);
2381 g_string_append(str, escape);
2384 g_string_append_c(str, ';');
2385 g_string_append_c(str, ';');
2386 g_string_append_c(str, ';');
2387 g_string_append_c(str, ';');
2390 return g_string_free(str, FALSE);
2394 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
2404 status = contacts_record_get_child_record_count(contact,
2405 _contacts_contact.number,
2408 if (status != CONTACTS_ERROR_NONE)
2411 for (i = 0; i < count; i++) {
2412 contacts_record_h number = NULL;
2416 bool is_default = false;
2418 status = contacts_record_get_child_record_at_p(contact,
2419 _contacts_contact.number, i, &number);
2421 if (status != CONTACTS_ERROR_NONE)
2424 status = contacts_record_get_bool(number,
2425 _contacts_number.is_default,
2428 if (status != CONTACTS_ERROR_NONE)
2431 if (is_default == FALSE)
2434 status = contacts_record_get_str_p(number,
2435 _contacts_number.number,
2438 if (status != CONTACTS_ERROR_NONE)
2442 str = g_strdup(tmp);
2447 /* get first number */
2451 contacts_record_h number = NULL;
2453 status = contacts_record_get_child_record_at_p(contact,
2454 _contacts_contact.number, 0, &number);
2456 if (status != CONTACTS_ERROR_NONE)
2459 status = contacts_record_get_str_p(number,
2460 _contacts_number.number,
2463 if (status != CONTACTS_ERROR_NONE)
2466 str = g_strdup(tmp);
2472 /* LCOV_EXCL_STOP */
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 /* LCOV_EXCL_START */
2495 status = contacts_record_get_int(phone_log,
2496 _contacts_phone_log.person_id,
2499 if (status != CONTACTS_ERROR_NONE) {
2500 contacts_record_destroy(phone_log, TRUE);
2504 contacts_record_destroy(phone_log, TRUE);
2509 status = contacts_filter_create(_contacts_person_phone_log._uri,
2512 if (status != CONTACTS_ERROR_NONE)
2516 status = contacts_filter_add_int(filter,
2517 _contacts_person_phone_log.log_id,
2518 CONTACTS_MATCH_EQUAL,
2521 if (status != CONTACTS_ERROR_NONE)
2524 status = contacts_query_create(_contacts_person_phone_log._uri, &query);
2526 if (status != CONTACTS_ERROR_NONE)
2529 status = contacts_query_set_filter(query, filter);
2531 if (status != CONTACTS_ERROR_NONE)
2534 status = contacts_db_get_records_with_query(query, -1, -1,
2537 if (status != CONTACTS_ERROR_NONE)
2540 status = contacts_list_first(record_list);
2542 if (status != CONTACTS_ERROR_NONE)
2545 status = contacts_list_get_current_record_p(record_list, &record);
2547 if (status != CONTACTS_ERROR_NONE)
2550 status = contacts_record_get_int(record,
2551 _contacts_person_phone_log.person_id,
2554 if (status != CONTACTS_ERROR_NONE)
2558 if (record_list != NULL)
2559 contacts_list_destroy(record_list, TRUE);
2561 contacts_filter_destroy(filter);
2564 contacts_query_destroy(query);
2568 /* LCOV_EXCL_STOP */
2571 int _bluetooth_get_contact_addressbook(gint person_id)
2573 contacts_record_h person = NULL;
2574 contacts_record_h contact = NULL;
2575 contacts_record_h addressbook = NULL;
2577 char* addressbook_name = NULL;
2578 gint contact_id = 0;
2579 gint address_book_id = 0;
2582 status = contacts_db_get_record(_contacts_person._uri,
2585 if (status != CONTACTS_ERROR_NONE)
2586 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2588 /* LCOV_EXCL_START */
2589 status = contacts_record_get_int(person,
2590 _contacts_person.display_contact_id,
2592 contacts_record_destroy(person, TRUE);
2594 if (status != CONTACTS_ERROR_NONE)
2595 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2597 status = contacts_db_get_record(_contacts_contact._uri,
2600 if (status != CONTACTS_ERROR_NONE)
2601 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2603 status = contacts_record_get_int(contact,
2604 _contacts_contact.address_book_id,
2606 contacts_record_destroy(contact, TRUE);
2608 if (status != CONTACTS_ERROR_NONE)
2609 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2611 status = contacts_db_get_record(_contacts_address_book._uri,
2614 if (status != CONTACTS_ERROR_NONE)
2615 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2617 status = contacts_record_get_str_p(addressbook, _contacts_address_book.name,
2619 contacts_record_destroy(addressbook, TRUE);
2621 if (status != CONTACTS_ERROR_NONE)
2622 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2624 if (address_book_id == 0 || _bt_is_sim_addressbook(addressbook_name) == false)
2625 return PBAP_ADDRESSBOOK_PHONE;
2627 return PBAP_ADDRESSBOOK_SIM;
2628 /* LCOV_EXCL_STOP */
2631 gchar *_bluetooth_pb_vcard_contact(gint person_id,
2641 str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
2648 gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
2653 GString *str = g_string_new("BEGIN:VCARD\r\n");
2657 fn = _bluetooth_pb_owner_name();
2658 name = g_strdup_printf("%s;;;;", fn);
2661 case VCARD_FORMAT_3_0:
2662 g_string_append(str, "VERSION:3.0\r\n");
2664 __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
2665 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
2666 __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL",
2669 case VCARD_FORMAT_2_1:
2671 g_string_append(str, "VERSION:2.1\r\n");
2673 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
2675 if (filter == 0 || (filter & VCARD_FN))
2676 __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN",
2679 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL",
2685 g_string_append(str, "END:VCARD\r\n");
2691 return g_string_free(str, FALSE);
2694 gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
2705 ERR("Unknown attribute type ignored\n");
2709 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2711 DBG("person_id %d\n", person_id);
2714 /* LCOV_EXCL_START */
2715 if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
2716 gchar *datetime = NULL;
2718 datetime = __bluetooth_pb_phonelog_datetime(
2721 str = __bluetooth_pb_vcard_real_contact_with_properties(
2725 "X-IRMC-CALL-DATETIME", attr, datetime,
2731 str = __bluetooth_pb_vcard_real_contact_with_properties(
2737 /* LCOV_EXCL_STOP */
2739 str = __bluetooth_pb_vcard_real_call(phonelog_id, filter,
2746 gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
2749 contacts_record_h person = NULL;
2755 status = contacts_db_get_record(_contacts_person._uri,
2759 if (status != CONTACTS_ERROR_NONE)
2762 /* LCOV_EXCL_START */
2763 status = contacts_record_get_str(person,
2764 _contacts_person.display_name,
2767 if (status != CONTACTS_ERROR_NONE)
2770 contacts_record_destroy(person, TRUE);
2774 /* LCOV_EXCL_STOP */
2777 gchar *_bluetooth_pb_name_from_person_id(gint person_id)
2780 contacts_record_h person = NULL;
2781 contacts_record_h contact = NULL;
2784 gint contact_id = 0;
2788 status = contacts_db_get_record(_contacts_person._uri,
2792 if (status != CONTACTS_ERROR_NONE)
2795 /* LCOV_EXCL_START */
2796 status = contacts_record_get_int(person,
2797 _contacts_person.display_contact_id,
2800 if (status != CONTACTS_ERROR_NONE) {
2801 contacts_record_destroy(person, TRUE);
2805 status = contacts_db_get_record(_contacts_contact._uri,
2809 if (status != CONTACTS_ERROR_NONE) {
2810 contacts_record_destroy(person, TRUE);
2814 str = __bluetooth_pb_name_from_contact(contact);
2816 contacts_record_destroy(contact, TRUE);
2817 contacts_record_destroy(person, TRUE);
2818 /* LCOV_EXCL_STOP */
2824 gchar *_bluetooth_pb_number_from_person_id(gint person_id)
2827 contacts_record_h person = NULL;
2828 contacts_record_h contact = NULL;
2831 gint contact_id = 0;
2835 status = contacts_db_get_record(_contacts_person._uri,
2839 if (status != CONTACTS_ERROR_NONE)
2842 /* LCOV_EXCL_START */
2843 status = contacts_record_get_int(person,
2844 _contacts_person.display_contact_id,
2847 if (status != CONTACTS_ERROR_NONE) {
2848 contacts_record_destroy(person, TRUE);
2852 status = contacts_db_get_record(_contacts_contact._uri,
2856 if (status != CONTACTS_ERROR_NONE) {
2857 contacts_record_destroy(person, TRUE);
2861 str = __bluetooth_pb_number_from_contact(contact);
2863 contacts_record_destroy(contact, TRUE);
2864 contacts_record_destroy(person, TRUE);
2865 /* LCOV_EXCL_STOP */
2871 gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
2877 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2880 str = _bluetooth_pb_fn_from_person_id(person_id);
2888 gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
2894 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2897 str = _bluetooth_pb_name_from_person_id(person_id);
2901 tmp = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
2902 str = g_strdup_printf("%s;;;;", tmp);
2911 gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
2914 contacts_record_h phone_log;
2921 status = contacts_db_get_record(_contacts_phone_log._uri,
2922 phonelog_id, &phone_log);
2924 if (status != CONTACTS_ERROR_NONE)
2927 /* LCOV_EXCL_START */
2928 status = contacts_record_get_str_p(phone_log,
2929 _contacts_phone_log.address,
2932 if (status != CONTACTS_ERROR_NONE) {
2933 contacts_record_destroy(phone_log, TRUE);
2937 str = g_strdup(tmp);
2939 contacts_record_destroy(phone_log, TRUE);
2940 /* LCOV_EXCL_STOP */
2946 gchar *_bluetooth_pb_owner_name(void)
2951 name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
2954 name = g_strdup("My Name"); /* LCOV_EXCL_LINE */
2960 bool _bt_is_sim_addressbook(const char *addressbook)
2962 return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX);