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);
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);
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 /* get string length, which convert to quoted-printable encoding */
289 static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
301 if (strlen(str) < len)
306 while (*pos != '\0' && (((pos - str) < length) || length < 0)) {
307 if ((guchar)*pos == '\t') {
313 if ((guchar)*pos < ' ' || (guchar)*pos == '=') {
319 /* check no-ascii utf-8 character */
320 if ((guchar)*pos > '~') {
324 next = g_utf8_next_char(pos);
326 count += QP_ENC_LEN * (next - pos);
339 /* convert to quoted printable code */
340 static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
348 if (str == NULL || len == 0)
351 /* add soft linebreak when it exceed */
352 if ((*line_pos + (QP_ENC_LEN * len) > LINEBREAK_LEN)) {
353 g_string_append(string, "=\r\n");
357 for (i = 0; i < len; i++) {
358 g_string_append_printf(string, "=%02X", (guchar)*(str+i));
359 *line_pos += QP_ENC_LEN;
364 /* append plain visiable ascii character */
365 static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
370 /* add soft linebreak when it exceed */
371 if (*line_pos + 1 > LINEBREAK_LEN) {
372 g_string_append(string, "=\r\n");
375 g_string_append_c(string, ch);
380 static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
393 encode_len = __bluetooth_pb_vcard_qp_encode_strlen(str, len);
395 /* add soft linebreak when it exceed */
396 if (((*line_pos + encode_len) > LINEBREAK_LEN) && (*line_pos > 1)) {
397 g_string_append(string, "=\r\n");
404 pos = ((gchar *)str) + i;
406 /* converts invisiable character and escape character '='
407 to quoted-printable */
408 if ((guchar)*pos != '\t' &&
409 ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
410 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
417 /* converts non-ascii utf-8 character to quoted-printable */
418 if ((guchar)*pos > '~') {
422 next = g_utf8_next_char(pos);
425 __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
426 pos, ch_len, line_pos);
432 __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos,
439 static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str)
452 enc = g_string_new(NULL);
454 st_pos = (gchar *)str;
457 while (*pos != '\0') {
458 /* split string with given delimeter ' ' or '\t' */
459 if (*pos == ' ' || *pos == '\t') {
460 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
461 (pos - st_pos), &line_pos);
469 /* split string with given delimeter '\r', '\n' or
471 if (*pos == '\r' || *pos == '\n') {
472 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
473 (pos - st_pos), &line_pos);
475 /* converts newline to qp_encode with soft linebreak
476 for example, converts \r\n to =0D=0A=\r\n */
477 __bluetooth_pb_vcard_qp_encode_append_to_hex(enc,
478 "\r\n", 2, &line_pos);
479 g_string_append(enc, "=\r\n ");
483 if (*pos == '\r' && *(pos + 1) == '\n')
496 __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
497 (pos - st_pos), &line_pos);
500 return g_string_free(enc, FALSE);
503 static void __bluetooth_pb_vcard_append_param_v21(GString *string,
512 pos = (gchar *)param;
514 /* trim ';' on first */
515 while (*pos != '\0') {
523 g_string_append_printf(string, ";%s", pos);
527 static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
533 GString *property = NULL;
538 property = g_string_new(name);
539 __bluetooth_pb_vcard_append_param_v21(property, param);
541 if (__bluetooth_pb_vcard_qp_encode_check(value)) {
544 __bluetooth_pb_vcard_append_param_v21(property,
546 __bluetooth_pb_vcard_append_param_v21(property,
547 "ENCODING=QUOTED-PRINTABLE");
548 g_string_append(property, ":");
550 enc = __bluetooth_pb_vcard_qp_encode(value);
553 g_string_append(property, enc);
557 g_string_append(property, ":");
559 g_string_append(property , value);
562 g_string_append_printf(string, "%s\r\n", property->str);
564 g_string_free(property, TRUE);
569 static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
581 DBG("base 64 encoding\n");
583 g_string_append(string, name);
585 __bluetooth_pb_vcard_append_param_v21(string, param);
586 __bluetooth_pb_vcard_append_param_v21(string, "ENCODING=BASE64");
588 g_string_append(string, ":");
593 enc = g_base64_encode((const guchar *)value, len);
595 if (folding == FALSE) {
596 g_string_append(string, enc);
598 gint enc_len = strlen(enc);
601 /* count ' ' size for folding */
602 gint fline_len = LINEBREAK_LEN - 1;
604 for (i = 0; (i * fline_len) < enc_len; i++) {
605 g_string_append(string, "\r\n ");
606 if ((i * fline_len) + fline_len > enc_len)
607 g_string_append(string, enc + (i * fline_len));
609 g_string_append_len(string, enc +
610 (i * fline_len), fline_len);
613 /* some application requires more \r\n */
614 g_string_append(string, "\r\n");
616 g_string_append(string, "\r\n");
617 DBG("base 64 encoding\n");
623 static void __bluetooth_pb_vcard_append_n_v21(GString *string,
624 contacts_record_h contact)
629 str = __bluetooth_pb_name_from_contact(contact);
630 __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
636 static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
637 contacts_record_h contact)
642 str = __bluetooth_pb_phonetic_name_from_contact(contact);
645 __bluetooth_pb_vcard_append_qp_encode_v21(string, "SOUND", "X-IRMC-N", str);
651 static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
652 contacts_record_h contact)
660 status = contacts_record_get_child_record_count(contact,
661 _contacts_contact.number,
664 if (status != CONTACTS_ERROR_NONE)
667 for (i = 0; i < count; i++) {
668 contacts_record_h number = NULL;
670 gchar **paramv = NULL;
674 gchar *escaped = NULL;
676 status = contacts_record_get_child_record_at_p(contact,
677 _contacts_contact.number, i, &number);
679 if (status != CONTACTS_ERROR_NONE)
682 status = contacts_record_get_str_p(number,
683 _contacts_number.number,
686 if (status != CONTACTS_ERROR_NONE)
689 escaped = __bluetooth_pb_vcard_escape(tel);
691 paramv = __bluetooth_pb_contact_tel_param(number);
693 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
695 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param,
705 static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
706 contacts_record_h person)
714 status = contacts_record_get_str_p(person,
715 _contacts_person.display_name,
718 if (status != CONTACTS_ERROR_NONE)
721 fn = __bluetooth_pb_vcard_escape(tmp);
723 __bluetooth_pb_vcard_append_qp_encode_v21(string, "FN", NULL, fn);
728 /* image util APIs will be deprecated in Tizen 5.0. So we should replace it to new API
729 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#decode
730 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#encode
733 static image_util_rotation_e __bt_pbap_get_rotation_info(const char *path)
738 image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
741 ed = exif_data_new_from_file(path);
743 ERR("exif_data_new_from_file : ExifData is NULL");
744 return IMAGE_UTIL_ROTATION_NONE;
747 entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
749 ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
750 orientation = (int)exif_get_short(entry->data, mByteOrder);
751 if (orientation < 0 || orientation > 8)
757 switch (orientation) {
758 case 1: /* Top-left */
759 rotation = IMAGE_UTIL_ROTATION_NONE;
761 case 2: /* Top-right */
762 rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
764 case 3: /* Bottom-right */
765 rotation = IMAGE_UTIL_ROTATION_180;
767 case 4: /* Bottom-left */
768 rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
770 case 6: /* Right-top */
771 rotation = IMAGE_UTIL_ROTATION_90;
773 case 8: /* Left-bottom */
774 rotation = IMAGE_UTIL_ROTATION_270;
776 case 5: /* Left-top */
777 case 7: /* Right-bottom */
788 static bool __bt_pbap_image_util_supported_jpeg_colorspace_cb(
789 image_util_colorspace_e colorspace, void *user_data)
792 unsigned char *img_target = 0;
793 unsigned char *img_source = 0;
796 gchar *contents = NULL;
799 int resized_width = 0;
800 int resized_height = 0;
802 unsigned int size_decode = 0;
803 image_util_rotation_e rotation;
804 image_util_error_e ret = 0;
807 bt_image_info_t *info = (bt_image_info_t *)user_data;
808 rotation = __bt_pbap_get_rotation_info(info->src);
809 ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width,
810 &height, &size_decode);
811 if (ret != IMAGE_UTIL_ERROR_NONE) {
812 ERR("Can not decode");
813 memset(info, 0x00, sizeof(bt_image_info_t));
817 DBG("decoding completed width = %d, height = %d, size = %d\n", width,
818 height, size_decode);
819 if (width > PBAP_IMAGE_THUMB_SIZE || height > PBAP_IMAGE_THUMB_SIZE) {
820 if (width <= 0 || height <= 0) {
822 ERR("image size error(%d)", PBAP_IMAGE_THUMB_SIZE);
823 memset(info, 0x00, sizeof(bt_image_info_t));
827 if (width > height) {
828 resized_width = PBAP_IMAGE_THUMB_SIZE ;
829 resized_height = height * PBAP_IMAGE_THUMB_SIZE / width;
831 resized_height = PBAP_IMAGE_THUMB_SIZE;
832 resized_width = width * PBAP_IMAGE_THUMB_SIZE / height;
835 if (resized_height % 8)
836 resized_height += 8 - (resized_height % 8);
837 if (resized_width % 8)
838 resized_width += 8 - (resized_width % 8);
840 DBG("original size[%d, %d] changed to resize[%d,%d]", width,
841 height, resized_width, resized_height);
843 ret = image_util_calculate_buffer_size(resized_width,
848 img_target = g_malloc0(size_decode);
851 ret = image_util_resize(img_target, &resized_width,
852 &resized_height, img_source, width,
854 if (ret != IMAGE_UTIL_ERROR_NONE) {
855 ERR("image_util_resize failed(%d)", ret);
858 memset(info, 0x00, sizeof(bt_image_info_t));
863 resized_width = width;
864 resized_height = height;
865 img_target = img_source;
867 DBG("Resized w = %d, ht = %d, size = %d\n", width, height, size_decode);
869 if (IMAGE_UTIL_ROTATION_NONE != rotation) {
870 int rotated_width, rotated_height;
871 unsigned char *img_rotate = 0;
872 img_rotate = g_malloc0(size_decode);
873 ret = image_util_rotate(img_rotate, &rotated_width, &rotated_height,
874 rotation, img_target, resized_width,
875 resized_height, colorspace);
877 ERR("image_util_rotate failed");
878 resized_width = rotated_width;
879 resized_height = rotated_height;
881 img_target = img_rotate;
885 ret = image_util_encode_jpeg(img_target, resized_width, resized_height,
886 colorspace, PBAP_IMAGE_ENCODE_QUALITY,
889 if (ret != IMAGE_UTIL_ERROR_NONE) {
890 ERR("image_util_encode_jpeg failed(%d)", ret);
891 info->ret = CONTACTS_ERROR_INTERNAL;
894 DBG("Encoding done\n");
896 dest_fd = open(info->dest, O_RDONLY);
898 ERR("System : Open Failed(%d)", errno);
899 ERR_SECURE("Open : dest path(%s)", info->dest);
903 ret = fchown(dest_fd, getuid(), PBAP_SECURITY_FILE_GROUP);
905 ERR("fchown Failed(%d)", errno);
906 DBG_SECURE("fchown : dest path(%s)", info->dest);
911 ret = fchmod(dest_fd, PBAP_SECURITY_IMAGE_PERMISSION);
913 ERR("fchmod Failed(%d)", errno);
914 ERR_SECURE("fchmod : dest path(%s)", info->dest);
920 info->ret = CONTACTS_ERROR_NONE;
921 type = __bluetooth_pb_contact_photo_type(info->dest);
922 DBG("Cintact image thumb type is = %s\n", type);
925 param = g_strdup_printf("TYPE=%s", type);
929 if (g_file_get_contents(info->dest, &contents, &len, NULL) == FALSE) {
930 ERR("can not read file contents:%s\n", info->dest);
934 __bluetooth_pb_vcard_append_base64_encode_v21(info->string,
935 "PHOTO", param, contents, len, TRUE);
941 memset(info, 0x00, sizeof(bt_image_info_t));
942 DBG("Cintact image thumb created successfuly\n");
948 static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
949 contacts_record_h person)
953 gchar *filename = NULL;
954 struct stat stat_info;
957 gchar *contents = NULL;
961 status = contacts_record_get_str_p(person,
962 _contacts_person.image_thumbnail_path,
965 if (status != CONTACTS_ERROR_NONE || NULL == filename)
968 stat_info.st_size = 0;
970 if (0 > stat(filename, &stat_info))
971 ERR("fstat failed, file does not exist %s", filename);
973 if (PBAP_THUMB_FILE_SIZE > stat_info.st_size) {
974 DBG_SECURE("File size small, so use thubnail %s\n", filename);
976 type = __bluetooth_pb_contact_photo_type(filename);
978 param = g_strdup_printf("TYPE=%s", type);
982 if (g_file_get_contents(filename, &contents, &len, NULL) ==
984 ERR("can not read file contents:%s\n", filename);
988 DBG("Retrieved the contents of the file \n");
989 __bluetooth_pb_vcard_append_base64_encode_v21(string,
990 "PHOTO", param, contents, len, TRUE);
997 ptr = strrchr(filename, '.');
999 memset(dest_thumb_path, 0x00, sizeof(dest_thumb_path));
1000 g_strlcpy(dest_thumb_path, filename, ptr - filename);
1001 g_strlcat(dest_thumb_path, PBAP_THMB_PATH,
1002 sizeof(dest_thumb_path));
1003 g_strlcat(dest_thumb_path, ptr, sizeof(dest_thumb_path));
1004 DBG("Thumbnail path is = %s", dest_thumb_path);
1006 DBG_SECURE("filename = %s Thumbnail path is = %s", filename, dest_thumb_path);
1008 /* image_util_foreach_supported_jpeg_colorspace API will be deprecated in Tizen 5.0. So we should replace it to new API
1009 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#decode
1010 https://developer.tizen.org/development/guides/native-application/media-and-camera/image-editing#encode
1013 bt_image_info_t img_info;
1016 img_info.src = filename;
1017 img_info.dest = dest_thumb_path;
1018 img_info.ret = CONTACTS_ERROR_INTERNAL;
1019 img_info.person = person;
1020 img_info.string = string;
1022 res = image_util_foreach_supported_jpeg_colorspace(
1023 __bt_pbap_image_util_supported_jpeg_colorspace_cb, &img_info);
1025 if (res != IMAGE_UTIL_ERROR_NONE)
1026 ERR("Image resizing is failed");
1032 static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
1033 contacts_record_h contact)
1041 status = contacts_record_get_child_record_count(contact,
1042 _contacts_contact.event, &count);
1044 if (status != CONTACTS_ERROR_NONE)
1047 for (i = 0; i < count; i++) {
1048 contacts_record_h event = NULL;
1054 contacts_event_type_e type;
1056 status = contacts_record_get_child_record_at_p(contact,
1057 _contacts_contact.event, i, &event);
1059 if (status != CONTACTS_ERROR_NONE)
1062 status = contacts_record_get_int(event,
1063 _contacts_event.type,
1066 if (status != CONTACTS_ERROR_NONE)
1069 if (type != CONTACTS_EVENT_TYPE_BIRTH)
1072 status = contacts_record_get_int(event,
1073 _contacts_event.date,
1076 if (status != CONTACTS_ERROR_NONE)
1082 bday = g_strdup_printf("%04d-%02d-%02d",
1083 (date/10000), (date/100)%100, date%100);
1084 __bluetooth_pb_vcard_append_qp_encode_v21(string, "BDAY",
1091 static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
1092 contacts_record_h contact)
1100 status = contacts_record_get_child_record_count(contact,
1101 _contacts_contact.address,
1104 if (status != CONTACTS_ERROR_NONE)
1107 for (i = 0; i < count; i++) {
1108 contacts_record_h address = NULL;
1116 status = contacts_record_get_child_record_at_p(contact,
1117 _contacts_contact.address, i, &address);
1119 if (status != CONTACTS_ERROR_NONE)
1122 addrv = __bluetooth_pb_contact_addr(address);
1127 addr = __bluetooth_pb_vcard_strv_concat(addrv, ";");
1130 paramv = __bluetooth_pb_contact_addr_param(address);
1132 param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
1135 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
1145 static void __bluetooth_pb_vcard_append_email_v21(GString *string,
1146 contacts_record_h contact)
1154 status = contacts_record_get_child_record_count(contact,
1155 _contacts_contact.email,
1158 if (status != CONTACTS_ERROR_NONE)
1161 for (i = 0; i < count; i++) {
1162 contacts_record_h email = NULL;
1167 status = contacts_record_get_child_record_at_p(contact,
1168 _contacts_contact.email, i, &email);
1170 if (status != CONTACTS_ERROR_NONE)
1173 status = contacts_record_get_str_p(email,
1174 _contacts_email.email,
1177 if (status != CONTACTS_ERROR_NONE)
1180 escaped = __bluetooth_pb_vcard_escape(tmp);
1181 __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL,
1189 static void __bluetooth_pb_vcard_append_title_v21(GString *string,
1190 contacts_record_h contact)
1198 status = contacts_record_get_child_record_count(contact,
1199 _contacts_contact.company,
1202 if (status != CONTACTS_ERROR_NONE)
1205 for (i = 0; i < count; i++) {
1206 contacts_record_h company = NULL;
1211 status = contacts_record_get_child_record_at_p(contact,
1212 _contacts_contact.company, i, &company);
1214 if (status != CONTACTS_ERROR_NONE)
1217 status = contacts_record_get_str_p(company,
1218 _contacts_company.job_title,
1221 if (status != CONTACTS_ERROR_NONE)
1224 escaped = __bluetooth_pb_vcard_escape(title);
1225 __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL,
1233 static void __bluetooth_pb_vcard_append_role_v21(GString *string,
1234 contacts_record_h contact)
1242 status = contacts_record_get_child_record_count(contact,
1243 _contacts_contact.company,
1246 if (status != CONTACTS_ERROR_NONE)
1249 for (i = 0; i < count; i++) {
1250 contacts_record_h company = NULL;
1255 status = contacts_record_get_child_record_at_p(contact,
1256 _contacts_contact.company, i, &company);
1258 if (status != CONTACTS_ERROR_NONE)
1261 status = contacts_record_get_str_p(company,
1262 _contacts_company.role,
1265 if (status != CONTACTS_ERROR_NONE)
1268 escaped = __bluetooth_pb_vcard_escape(role);
1269 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL,
1277 static void __bluetooth_pb_vcard_append_org_v21(GString *string,
1278 contacts_record_h contact)
1286 status = contacts_record_get_child_record_count(contact,
1287 _contacts_contact.company,
1290 if (status != CONTACTS_ERROR_NONE)
1293 for (i = 0; i < count; i++) {
1294 contacts_record_h company = NULL;
1299 gchar *department = NULL;
1302 gint department_status;
1304 status = contacts_record_get_child_record_at_p(contact,
1305 _contacts_contact.company, i, &company);
1307 if (status != CONTACTS_ERROR_NONE)
1311 name_status = contacts_record_get_str_p(company,
1312 _contacts_company.name,
1315 department_status = contacts_record_get_str_p(company,
1316 _contacts_company.department,
1319 if ((name_status != CONTACTS_ERROR_NONE) &&
1320 (department_status != CONTACTS_ERROR_NONE))
1323 str = g_string_new(NULL);
1328 escaped = __bluetooth_pb_vcard_escape(name);
1329 g_string_append(str, escaped);
1333 g_string_append(str, ";");
1338 escaped = __bluetooth_pb_vcard_escape(department);
1339 g_string_append(str, escaped);
1343 __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL,
1346 g_string_free(str, TRUE);
1352 static void __bluetooth_pb_vcard_append_note_v21(GString *string,
1353 contacts_record_h contact)
1361 status = contacts_record_get_child_record_count(contact,
1362 _contacts_contact.note,
1365 if (status != CONTACTS_ERROR_NONE)
1368 for (i = 0; i < count; i++) {
1369 contacts_record_h note = NULL;
1374 status = contacts_record_get_child_record_at_p(contact,
1375 _contacts_contact.note, i, ¬e);
1377 if (status != CONTACTS_ERROR_NONE)
1380 status = contacts_record_get_str_p(note,
1381 _contacts_note.note,
1384 if (status != CONTACTS_ERROR_NONE)
1387 escaped = __bluetooth_pb_vcard_escape(tmp);
1388 __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL,
1396 static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
1397 contacts_record_h contact)
1406 status = contacts_record_get_int(contact,
1407 _contacts_contact.changed_time,
1410 if (status != CONTACTS_ERROR_NONE)
1416 gmtime_r((const time_t *)(&time), &result);
1418 rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
1419 (1900 + result.tm_year), (1 + result.tm_mon),
1420 result.tm_mday, result.tm_hour, result.tm_min,
1423 __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
1429 static void __bluetooth_pb_vcard_append_url_v21(GString *string,
1430 contacts_record_h contact)
1438 status = contacts_record_get_child_record_count(contact,
1439 _contacts_contact.url,
1442 if (status != CONTACTS_ERROR_NONE)
1445 for (i = 0; i < count; i++) {
1446 contacts_record_h url = NULL;
1451 status = contacts_record_get_child_record_at_p(contact,
1452 _contacts_contact.url, i, &url);
1454 if (status != CONTACTS_ERROR_NONE)
1460 status = contacts_record_get_str_p(url,
1464 if (status != CONTACTS_ERROR_NONE)
1467 escaped = __bluetooth_pb_vcard_escape(tmp);
1468 __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL,
1476 static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
1477 contacts_record_h contact)
1485 status = contacts_record_get_str_p(contact,
1486 _contacts_contact.uid,
1489 if (status != CONTACTS_ERROR_NONE)
1492 escaped = __bluetooth_pb_vcard_escape(uid);
1493 __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
1499 static void __bluetooth_pb_vcard_append_v30(GString *string,
1510 g_string_append(string, name);
1513 g_string_append_printf(string, ";%s", param);
1515 g_string_append(string, ":");
1518 g_string_append(string, value);
1520 g_string_append(string, "\r\n");
1524 static void __bluetooth_pb_vcard_remove_v30(GString *string,
1525 const gchar *property_name)
1529 gchar *st_pos = NULL;
1531 gboolean matched = FALSE;
1533 if (string == NULL || property_name == NULL)
1538 while (*pos != '\0') {
1539 if (matched == FALSE) {
1540 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1546 attrlen = strlen(property_name);
1547 if (g_ascii_strncasecmp(pos, property_name,
1551 if (*pos == ':' || *pos == ';') {
1559 if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
1562 if (*pos != ' ' && *pos != '\t') {
1563 /* +2 means move over \r\n */
1564 g_string_erase(string,
1565 (st_pos+2)-(string->str),
1580 static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
1584 GString *string = NULL;
1589 string = g_string_new(vcard);
1591 if ((filter & VCARD_BDAY) == 0)
1592 __bluetooth_pb_vcard_remove_v30(string, "BDAY");
1594 if ((filter & VCARD_ADR) == 0)
1595 __bluetooth_pb_vcard_remove_v30(string, "ADR");
1597 if ((filter & VCARD_EMAIL) == 0)
1598 __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
1600 if ((filter & VCARD_TITLE) == 0)
1601 __bluetooth_pb_vcard_remove_v30(string, "TITLE");
1603 if ((filter & VCARD_ROLE) == 0)
1604 __bluetooth_pb_vcard_remove_v30(string, "ROLE");
1606 if ((filter & VCARD_ORG) == 0)
1607 __bluetooth_pb_vcard_remove_v30(string, "ORG");
1609 if ((filter & VCARD_NOTE) == 0)
1610 __bluetooth_pb_vcard_remove_v30(string, "NOTE");
1612 if ((filter & VCARD_REV) == 0)
1613 __bluetooth_pb_vcard_remove_v30(string, "REV");
1615 if ((filter & VCARD_URL) == 0)
1616 __bluetooth_pb_vcard_remove_v30(string, "URL");
1618 if ((filter & VCARD_UID) == 0)
1619 __bluetooth_pb_vcard_remove_v30(string, "UID");
1621 if ((filter & VCARD_NICKNAME) == 0)
1622 __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
1625 return g_string_free(string, FALSE);
1628 static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
1631 const gchar *first_name,
1635 contacts_record_h person = NULL;
1636 contacts_record_h contact = NULL;
1638 GString *str = NULL;
1640 gint contact_id = 0;
1645 const gchar *name = first_name;
1647 status = contacts_db_get_record(_contacts_person._uri,
1651 if (status != CONTACTS_ERROR_NONE)
1654 status = contacts_record_get_int(person,
1655 _contacts_person.display_contact_id,
1658 if (status != CONTACTS_ERROR_NONE)
1661 status = contacts_db_get_record(_contacts_contact._uri,
1665 if (status != CONTACTS_ERROR_NONE) {
1666 contacts_record_destroy(person, TRUE);
1673 DBG("filter[%x]\n", filter);
1675 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1677 /* N, TEL is default */
1678 __bluetooth_pb_vcard_append_n_v21(str, contact);
1680 if (phonelog_id > 0) {
1683 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1684 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0",
1690 __bluetooth_pb_vcard_append_tel_v21(str, contact);
1694 __bluetooth_pb_vcard_append_fn_v21(str, person);
1695 /* Need to check filter
1696 if (f & VCARD_SOUND)*/
1697 __bluetooth_pb_vcard_append_phonetic_first_v21(str, contact);
1698 if (f & VCARD_PHOTO)
1699 __bluetooth_pb_vcard_append_photo_v21(str, person);
1701 __bluetooth_pb_vcard_append_bday_v21(str, contact);
1703 __bluetooth_pb_vcard_append_adr_v21(str, contact);
1704 if (f & VCARD_EMAIL)
1705 __bluetooth_pb_vcard_append_email_v21(str, contact);
1706 if (f & VCARD_TITLE)
1707 __bluetooth_pb_vcard_append_title_v21(str, contact);
1709 __bluetooth_pb_vcard_append_role_v21(str, contact);
1711 __bluetooth_pb_vcard_append_org_v21(str, contact);
1713 __bluetooth_pb_vcard_append_note_v21(str, contact);
1715 __bluetooth_pb_vcard_append_rev_v21(str, contact);
1717 __bluetooth_pb_vcard_append_url_v21(str, contact);
1719 __bluetooth_pb_vcard_append_uid_v21(str, contact);
1722 const gchar *param = va_arg(args, const gchar *);
1723 const gchar *value = va_arg(args, const gchar *);
1726 gchar *escaped = NULL;
1728 escaped = __bluetooth_pb_vcard_escape(value);
1729 __bluetooth_pb_vcard_append_qp_encode_v21(str, name,
1735 name = va_arg(args, const gchar *);
1738 g_string_append(str, "END:VCARD\r\n");
1740 contacts_record_destroy(contact, TRUE);
1741 contacts_record_destroy(person, TRUE);
1744 return g_string_free(str, FALSE);
1748 static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
1751 const gchar *first_name,
1755 contacts_record_h person = NULL;
1757 GString *str = NULL;
1761 const gchar *name = first_name;
1762 gchar *vcard = NULL;
1764 status = contacts_db_get_record(_contacts_person._uri,
1768 if (status != CONTACTS_ERROR_NONE)
1771 status = contacts_vcard_make_from_person(person, &vcard);
1773 if (status != CONTACTS_ERROR_NONE)
1776 /* removing the END:VCARD\r\n" to append extra data */
1777 str = g_string_new_len(vcard, (strlen(vcard)-11));
1780 /* append contents on vcard */
1782 const gchar *param = va_arg(args, const gchar *);
1783 const gchar *value = va_arg(args, const gchar *);
1785 __bluetooth_pb_vcard_append_v30(str, name, param, value);
1787 name = va_arg(args, const gchar *);
1790 /* if phonelog_id exist, we shall show only the phone number, which was
1791 used for that phone log */
1792 if (phonelog_id > 0) {
1795 __bluetooth_pb_vcard_remove_v30(str, "TEL");
1797 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1798 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1802 /* Remove Full contact image and add thumbnail image */
1803 __bluetooth_pb_vcard_remove_v30(str, "PHOTO");
1804 if (filter & VCARD_PHOTO)
1805 __bluetooth_pb_vcard_append_photo_v21(str, person); /* Photo is same as vCard 2.1 */
1807 /* Destroy contact record */
1808 status = contacts_record_destroy(person, TRUE);
1809 if (status != CONTACTS_ERROR_NONE)
1810 ERR("Failed to destroy person");
1812 g_string_append(str, "END:VCARD\r\n");
1814 vcard = g_string_free(str, FALSE);
1816 /* temporary fixed for some application crash */
1818 filter = ~VCARD_NOTE;
1821 gchar *new_vcard = NULL;
1823 new_vcard = __bluetooth_pb_vcard_filter_v30(vcard, filter);
1836 static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
1840 const gchar *first_name,
1844 DBG(" format [%d]\n", format);
1845 gchar *vcard = NULL;
1848 va_start(args, first_name);
1851 case VCARD_FORMAT_3_0:
1852 vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
1853 phonelog_id, filter,
1856 case VCARD_FORMAT_2_1:
1858 vcard = __bluetooth_pb_vcard_real_contact_valist_v21(person_id,
1859 phonelog_id, filter,
1870 static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
1878 str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
1880 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, NULL);
1882 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1883 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
1886 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1888 gchar *datetime = NULL;
1890 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1891 __bluetooth_pb_vcard_append_qp_encode_v21(str,
1892 "X-IRMC-CALL-DATETIME",
1897 g_string_append(str, "END:VCARD\r\n");
1900 return g_string_free(str, FALSE);
1903 static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
1911 str = g_string_new("BEGIN:VCARD\r\nVERSION:3.0\r\n");
1913 __bluetooth_pb_vcard_append_v30(str, "N", NULL, NULL);
1914 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, NULL);
1916 number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
1917 __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
1920 if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
1922 gchar *datetime = NULL;
1924 datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
1925 __bluetooth_pb_vcard_append_v30(str,
1926 "X-IRMC-CALL-DATETIME", attr, datetime);
1930 g_string_append(str, "END:VCARD\r\n");
1933 return g_string_free(str, FALSE);
1936 static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
1942 gchar *vcard = NULL;
1945 case VCARD_FORMAT_3_0:
1946 vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
1949 case VCARD_FORMAT_2_1:
1951 vcard = __bluetooth_pb_vcard_real_call_v21(phonelog_id,
1960 static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
1970 gboolean valid = FALSE;
1972 /* check empty field */
1973 for (i = 0; i < field_size; i++) {
1976 status = contacts_record_get_str_p(record, field[i], &tmp);
1978 if (status != CONTACTS_ERROR_NONE)
1990 strv = g_new0(gchar *, field_size + 1);
1992 for (i = 0; i < field_size; i++) {
1995 status = contacts_record_get_str_p(record, field[i], &tmp);
1997 if (status != CONTACTS_ERROR_NONE)
2001 strv[i] = g_strdup("");
2003 strv[i] = __bluetooth_pb_vcard_escape(tmp);
2010 static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
2013 gchar **strv = NULL;
2015 const gint TEL_PARAM_LEN = 13;
2020 contacts_number_type_e type;
2022 bool is_default = false;
2024 status = contacts_record_get_bool(number, _contacts_number.is_default,
2027 if (status != CONTACTS_ERROR_NONE)
2030 status = contacts_record_get_int(number,
2031 _contacts_number.type,
2034 if (status != CONTACTS_ERROR_NONE)
2037 strv = g_new0(char *, TEL_PARAM_LEN + 1);/* tel param max size is 13 */
2040 strv[i] = g_strdup("PREF");
2044 if (type & CONTACTS_NUMBER_TYPE_HOME) {
2045 strv[i] = g_strdup("HOME");
2049 if (type & CONTACTS_NUMBER_TYPE_WORK) {
2050 strv[i] = g_strdup("WORK");
2054 if (type & CONTACTS_NUMBER_TYPE_VOICE) {
2055 strv[i] = g_strdup("VOICE");
2059 if (type & CONTACTS_NUMBER_TYPE_FAX) {
2060 strv[i] = g_strdup("FAX");
2064 if (type & CONTACTS_NUMBER_TYPE_MSG) {
2065 strv[i] = g_strdup("MSG");
2069 if (type & CONTACTS_NUMBER_TYPE_CELL) {
2070 strv[i] = g_strdup("CELL");
2074 if (type & CONTACTS_NUMBER_TYPE_PAGER) {
2075 strv[i] = g_strdup("PAGER");
2079 if (type & CONTACTS_NUMBER_TYPE_BBS) {
2080 strv[i] = g_strdup("BBS");
2084 if (type & CONTACTS_NUMBER_TYPE_MODEM) {
2085 strv[i] = g_strdup("MODEM");
2089 if (type & CONTACTS_NUMBER_TYPE_CAR) {
2090 strv[i] = g_strdup("CAR");
2094 if (type & CONTACTS_NUMBER_TYPE_ISDN) {
2095 strv[i] = g_strdup("ISDN");
2099 if (type & CONTACTS_NUMBER_TYPE_VIDEO) {
2100 strv[i] = g_strdup("VIDEO");
2104 /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
2110 static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
2113 gchar *filetype = NULL;
2116 if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
2117 ERR_SECURE("file does not regular:%s\n", filename);
2121 ext = strrchr(filename, '.');
2123 ERR("file doesn't have extension\n");
2129 if (g_ascii_strcasecmp(ext, "gif") == 0)
2131 else if (g_ascii_strcasecmp(ext, "cgm") == 0)
2133 else if (g_ascii_strcasecmp(ext, "wmf") == 0)
2135 else if (g_ascii_strcasecmp(ext, "bmp") == 0)
2137 else if (g_ascii_strcasecmp(ext, "met") == 0)
2139 else if (g_ascii_strcasecmp(ext, "dib") == 0)
2141 else if (g_ascii_strcasecmp(ext, "pict") == 0 ||
2142 g_ascii_strcasecmp(ext, "pct") == 0 ||
2143 g_ascii_strcasecmp(ext, "pic") == 0)
2145 else if (g_ascii_strcasecmp(ext, "tiff") == 0 ||
2146 g_ascii_strcasecmp(ext, "tif") == 0)
2148 else if (g_ascii_strcasecmp(ext, "ps") == 0)
2150 else if (g_ascii_strcasecmp(ext, "pdf") == 0)
2152 else if (g_ascii_strcasecmp(ext, "jpeg") == 0 ||
2153 g_ascii_strcasecmp(ext, "jpg") == 0 ||
2154 g_ascii_strcasecmp(ext, "jpe") == 0)
2156 else if (g_ascii_strcasecmp(ext, "mpeg") == 0 ||
2157 g_ascii_strcasecmp(ext, "mpg") == 0)
2159 else if (g_ascii_strcasecmp(ext, "m2v") == 0)
2161 else if (g_ascii_strcasecmp(ext, "avi") == 0)
2163 else if (g_ascii_strcasecmp(ext, "mov") == 0)
2165 else if (g_ascii_strcasecmp(ext, "png") == 0)
2169 return g_strdup(filetype);
2172 static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
2175 const gint ADDR_LEN = 7;
2177 gchar **strv = NULL;
2179 gint addr[] = { _contacts_address.postbox,
2180 _contacts_address.extended,
2181 _contacts_address.street,
2182 _contacts_address.locality,
2183 _contacts_address.region,
2184 _contacts_address.postal_code,
2185 _contacts_address.country };
2187 strv = __bluetooth_pb_contact_add_field_str(address,
2193 static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
2196 contacts_address_type_e type;
2201 gchar **strv = NULL;
2203 status = contacts_record_get_int(address,
2204 _contacts_address.type,
2207 if (status != CONTACTS_ERROR_NONE)
2210 strv = g_new0(gchar *, 7); /* ADDR param max size is 6 */
2212 if (type & CONTACTS_ADDRESS_TYPE_HOME) {
2213 strv[i] = g_strdup("HOME");
2216 if (type & CONTACTS_ADDRESS_TYPE_WORK) {
2217 strv[i] = g_strdup("WORK");
2220 if (type & CONTACTS_ADDRESS_TYPE_DOM) {
2221 strv[i] = g_strdup("DOM");
2224 if (type & CONTACTS_ADDRESS_TYPE_INTL) {
2225 strv[i] = g_strdup("INTL");
2228 if (type & CONTACTS_ADDRESS_TYPE_POSTAL) {
2229 strv[i] = g_strdup("POSTAL");
2232 if (type & CONTACTS_ADDRESS_TYPE_PARCEL) {
2233 strv[i] = g_strdup("PARCEL");
2240 static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
2243 contacts_record_h phone_log;
2245 char time_str[32] = {0,};
2250 struct tm time_info;
2252 status = contacts_db_get_record(_contacts_phone_log._uri,
2256 if (status != CONTACTS_ERROR_NONE)
2259 status = contacts_record_get_int(phone_log,
2260 _contacts_phone_log.log_time,
2263 if (status != CONTACTS_ERROR_NONE)
2269 localtime_r((time_t *)&time, &time_info);
2271 strftime(time_str, sizeof(time_str),
2272 "%Y%m%dT%H%M%S", &time_info);
2274 contacts_record_destroy(phone_log, TRUE);
2277 return g_strdup(time_str);
2280 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
2283 contacts_record_h name = NULL;
2290 gint name_val[] = { _contacts_name.last,
2291 _contacts_name.first,
2292 _contacts_name.addition,
2293 _contacts_name.prefix,
2294 _contacts_name.suffix };
2297 status = contacts_record_get_child_record_at_p(contact,
2298 _contacts_contact.name, 0, &name);
2300 if (status != CONTACTS_ERROR_NONE)
2303 str = g_string_new(NULL);
2305 for (i = 0; i < name_size; i++) {
2307 gchar *escape = NULL;
2310 g_string_append_c(str, ';');
2312 status = contacts_record_get_str_p(name, name_val[i], &tmp);
2314 if (status != CONTACTS_ERROR_NONE)
2317 escape = __bluetooth_pb_vcard_escape(tmp);
2318 g_string_append(str, escape);
2324 return g_string_free(str, FALSE);
2327 static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact)
2330 contacts_record_h name = NULL;
2336 gchar *phonetic_first = NULL;
2337 gchar *phonetic_last = NULL;
2338 gchar *escape = NULL;
2340 status = contacts_record_get_child_record_at_p(contact,
2341 _contacts_contact.name, 0, &name);
2343 if (status != CONTACTS_ERROR_NONE)
2346 status = contacts_record_get_str_p(name, _contacts_name.phonetic_first, &phonetic_first);
2348 if (status != CONTACTS_ERROR_NONE)
2351 if (phonetic_first == NULL)
2354 str = g_string_new(NULL);
2356 status = contacts_record_get_str_p(name, _contacts_name.phonetic_last, &phonetic_last);
2358 if ((status == CONTACTS_ERROR_NONE) && (phonetic_last != NULL)) {
2359 escape = __bluetooth_pb_vcard_escape(phonetic_last);
2360 g_string_append(str, escape);
2362 g_string_append_c(str, ' ');
2365 escape = __bluetooth_pb_vcard_escape(phonetic_first);
2366 g_string_append(str, escape);
2369 g_string_append_c(str, ';');
2370 g_string_append_c(str, ';');
2371 g_string_append_c(str, ';');
2372 g_string_append_c(str, ';');
2375 return g_string_free(str, FALSE);
2379 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
2389 status = contacts_record_get_child_record_count(contact,
2390 _contacts_contact.number,
2393 if (status != CONTACTS_ERROR_NONE)
2396 for (i = 0; i < count; i++) {
2397 contacts_record_h number = NULL;
2401 bool is_default = false;
2403 status = contacts_record_get_child_record_at_p(contact,
2404 _contacts_contact.number, i, &number);
2406 if (status != CONTACTS_ERROR_NONE)
2409 status = contacts_record_get_bool(number,
2410 _contacts_number.is_default,
2413 if (status != CONTACTS_ERROR_NONE)
2416 if (is_default == FALSE)
2419 status = contacts_record_get_str_p(number,
2420 _contacts_number.number,
2423 if (status != CONTACTS_ERROR_NONE)
2427 str = g_strdup(tmp);
2432 /* get first number */
2436 contacts_record_h number = NULL;
2438 status = contacts_record_get_child_record_at_p(contact,
2439 _contacts_contact.number, 0, &number);
2441 if (status != CONTACTS_ERROR_NONE)
2444 status = contacts_record_get_str_p(number,
2445 _contacts_number.number,
2448 if (status != CONTACTS_ERROR_NONE)
2451 str = g_strdup(tmp);
2458 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
2461 contacts_query_h query = NULL;
2462 contacts_filter_h filter = NULL;
2463 contacts_list_h record_list = NULL;
2465 contacts_record_h phone_log = NULL;
2466 contacts_record_h record = NULL;
2471 status = contacts_db_get_record(_contacts_phone_log._uri,
2475 if (status != CONTACTS_ERROR_NONE)
2478 status = contacts_record_get_int(phone_log,
2479 _contacts_phone_log.person_id,
2482 if (status != CONTACTS_ERROR_NONE) {
2483 contacts_record_destroy(phone_log, TRUE);
2487 contacts_record_destroy(phone_log, TRUE);
2492 status = contacts_filter_create(_contacts_person_phone_log._uri,
2495 if (status != CONTACTS_ERROR_NONE)
2499 status = contacts_filter_add_int(filter,
2500 _contacts_person_phone_log.log_id,
2501 CONTACTS_MATCH_EQUAL,
2504 if (status != CONTACTS_ERROR_NONE)
2507 status = contacts_query_create(_contacts_person_phone_log._uri, &query);
2509 if (status != CONTACTS_ERROR_NONE)
2512 status = contacts_query_set_filter(query, filter);
2514 if (status != CONTACTS_ERROR_NONE)
2517 status = contacts_db_get_records_with_query(query, -1, -1,
2520 if (status != CONTACTS_ERROR_NONE)
2523 status = contacts_list_first(record_list);
2525 if (status != CONTACTS_ERROR_NONE)
2528 status = contacts_list_get_current_record_p(record_list, &record);
2530 if (status != CONTACTS_ERROR_NONE)
2533 status = contacts_record_get_int(record,
2534 _contacts_person_phone_log.person_id,
2537 if (status != CONTACTS_ERROR_NONE)
2541 if (record_list != NULL)
2542 contacts_list_destroy(record_list, TRUE);
2544 contacts_filter_destroy(filter);
2547 contacts_query_destroy(query);
2553 int _bluetooth_get_contact_addressbook(gint person_id)
2555 contacts_record_h person = NULL;
2556 contacts_record_h contact = NULL;
2557 contacts_record_h addressbook = NULL;
2559 char* addressbook_name = NULL;
2560 gint contact_id = 0;
2561 gint address_book_id = 0;
2564 status = contacts_db_get_record(_contacts_person._uri,
2567 if (status != CONTACTS_ERROR_NONE)
2568 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2570 status = contacts_record_get_int(person,
2571 _contacts_person.display_contact_id,
2573 contacts_record_destroy(person, TRUE);
2575 if (status != CONTACTS_ERROR_NONE)
2576 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2578 status = contacts_db_get_record(_contacts_contact._uri,
2581 if (status != CONTACTS_ERROR_NONE)
2582 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2584 status = contacts_record_get_int(contact,
2585 _contacts_contact.address_book_id,
2587 contacts_record_destroy(contact, TRUE);
2589 if (status != CONTACTS_ERROR_NONE)
2590 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2592 status = contacts_db_get_record(_contacts_address_book._uri,
2595 if (status != CONTACTS_ERROR_NONE)
2596 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2598 status = contacts_record_get_str_p(addressbook, _contacts_address_book.name,
2600 contacts_record_destroy(addressbook, TRUE);
2602 if (status != CONTACTS_ERROR_NONE)
2603 return PBAP_ADDRESSBOOK_PHONE; /* Default*/
2605 if (address_book_id == 0 || _bt_is_sim_addressbook(addressbook_name) == false)
2606 return PBAP_ADDRESSBOOK_PHONE;
2608 return PBAP_ADDRESSBOOK_SIM;
2611 gchar *_bluetooth_pb_vcard_contact(gint person_id,
2621 str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
2628 gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
2633 GString *str = g_string_new("BEGIN:VCARD\r\n");
2637 fn = _bluetooth_pb_owner_name();
2638 name = g_strdup_printf("%s;;;;", fn);
2641 case VCARD_FORMAT_3_0:
2642 g_string_append(str, "VERSION:3.0\r\n");
2644 __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
2645 __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
2646 __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL",
2649 case VCARD_FORMAT_2_1:
2651 g_string_append(str, "VERSION:2.1\r\n");
2653 __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
2655 if (filter == 0 || (filter & VCARD_FN))
2656 __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN",
2659 __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL",
2665 g_string_append(str, "END:VCARD\r\n");
2671 return g_string_free(str, FALSE);
2674 gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
2685 ERR("Unknown attribute type ignored\n");
2689 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2691 DBG("person_id %d\n", person_id);
2694 if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
2695 gchar *datetime = NULL;
2697 datetime = __bluetooth_pb_phonelog_datetime(
2700 str = __bluetooth_pb_vcard_real_contact_with_properties(
2704 "X-IRMC-CALL-DATETIME", attr, datetime,
2710 str = __bluetooth_pb_vcard_real_contact_with_properties(
2717 str = __bluetooth_pb_vcard_real_call(phonelog_id, filter,
2724 gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
2727 contacts_record_h person = NULL;
2733 status = contacts_db_get_record(_contacts_person._uri,
2737 if (status != CONTACTS_ERROR_NONE)
2740 status = contacts_record_get_str(person,
2741 _contacts_person.display_name,
2744 if (status != CONTACTS_ERROR_NONE)
2747 contacts_record_destroy(person, TRUE);
2753 gchar *_bluetooth_pb_name_from_person_id(gint person_id)
2756 contacts_record_h person = NULL;
2757 contacts_record_h contact = NULL;
2760 gint contact_id = 0;
2764 status = contacts_db_get_record(_contacts_person._uri,
2768 if (status != CONTACTS_ERROR_NONE)
2771 status = contacts_record_get_int(person,
2772 _contacts_person.display_contact_id,
2775 if (status != CONTACTS_ERROR_NONE) {
2776 contacts_record_destroy(person, TRUE);
2780 status = contacts_db_get_record(_contacts_contact._uri,
2784 if (status != CONTACTS_ERROR_NONE) {
2785 contacts_record_destroy(person, TRUE);
2789 str = __bluetooth_pb_name_from_contact(contact);
2791 contacts_record_destroy(contact, TRUE);
2792 contacts_record_destroy(person, TRUE);
2798 gchar *_bluetooth_pb_number_from_person_id(gint person_id)
2801 contacts_record_h person = NULL;
2802 contacts_record_h contact = NULL;
2805 gint contact_id = 0;
2809 status = contacts_db_get_record(_contacts_person._uri,
2813 if (status != CONTACTS_ERROR_NONE)
2817 status = contacts_record_get_int(person,
2818 _contacts_person.display_contact_id,
2821 if (status != CONTACTS_ERROR_NONE) {
2822 contacts_record_destroy(person, TRUE);
2826 status = contacts_db_get_record(_contacts_contact._uri,
2830 if (status != CONTACTS_ERROR_NONE) {
2831 contacts_record_destroy(person, TRUE);
2835 str = __bluetooth_pb_number_from_contact(contact);
2837 contacts_record_destroy(contact, TRUE);
2838 contacts_record_destroy(person, TRUE);
2844 gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
2850 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2853 str = _bluetooth_pb_fn_from_person_id(person_id);
2861 gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
2867 person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
2870 str = _bluetooth_pb_name_from_person_id(person_id);
2874 tmp = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
2875 str = g_strdup_printf("%s;;;;", tmp);
2884 gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
2887 contacts_record_h phone_log;
2894 status = contacts_db_get_record(_contacts_phone_log._uri,
2895 phonelog_id, &phone_log);
2897 if (status != CONTACTS_ERROR_NONE)
2900 status = contacts_record_get_str_p(phone_log,
2901 _contacts_phone_log.address,
2904 if (status != CONTACTS_ERROR_NONE) {
2905 contacts_record_destroy(phone_log, TRUE);
2909 str = g_strdup(tmp);
2911 contacts_record_destroy(phone_log, TRUE);
2917 gchar *_bluetooth_pb_owner_name(void)
2922 name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
2925 name = g_strdup("My Name");
2931 bool _bt_is_sim_addressbook(const char *addressbook)
2933 return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX);