Update AG and HF agent codes from wearable product
[platform/core/connectivity/bluetooth-agent.git] / ag-agent / bluetooth-ag-phonebook.c
1 /*
2  * bluetooth-ag-phonebook.c
3  *
4  * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:     Hocheol Seo <hocheol.seo@samsung.com>
7  *              Sangki Park <sangki79.park@samsung.com>
8  *              Chanyeol Park <chanyeol.park@samsung.com>
9  *              Rakesh MK <rakesh.mk@samsung.com>
10  *              Anurag B <biradar.a@samsung.com>
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *              http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  *
24  */
25
26 #include "bluetooth-ag-phonebook.h"
27 #include "bluetooth-ag-agent.h"
28 #include "bluetooth-ag-handler.h"
29
30
31 static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void);
32
33 static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void);
34
35 static contacts_query_h __bluetooth_pb_query_phone_log_missed(void);
36
37 static contacts_query_h __bluetooth_pb_query_phone_log_combined(void);
38
39 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
40 static gchar *_bluetooth_pb_number_from_person_id(gint person_id);
41
42 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
43
44 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
45 #endif
46
47 PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
48 {
49         FN_START;
50         if (name == NULL)
51                 return TELECOM_NONE;
52
53         if (g_strcmp0(name, "\"ME\"") == 0)
54                 return TELECOM_PB;
55
56         if (g_strcmp0(name, "\"RC\"") == 0)
57                 return TELECOM_ICH;
58
59         if (g_strcmp0(name, "\"DC\"") == 0)
60                 return TELECOM_OCH;
61
62         if (g_strcmp0(name, "\"MC\"") == 0)
63                 return TELECOM_MCH;
64 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
65         if (g_strcmp0(name, "\"SM\"") == 0)
66                 return SIM_PB;
67 #endif
68
69         FN_END;
70         return TELECOM_NONE;
71 }
72
73 static bool _bt_is_sim_addressbook(const char *addressbook)
74 {
75         return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX);
76 }
77
78 static bool __bt_is_matching_addressbook(const char *addressbook_name,
79                         int addressbook)
80 {
81         bool is_sim_addressbook = _bt_is_sim_addressbook(addressbook_name);
82
83         if ((is_sim_addressbook == false
84                         && addressbook == PBAP_ADDRESSBOOK_PHONE) ||
85                 (is_sim_addressbook == true
86                         && addressbook == PBAP_ADDRESSBOOK_SIM))
87                 return true;
88
89         return false;
90 }
91
92 static contacts_query_h __bluetooth_pb_query_person(int addressbook)
93 {
94         FN_START;
95         contacts_query_h query = NULL;
96         contacts_filter_h filter = NULL;
97         contacts_list_h recordList = NULL;
98         contacts_record_h record = NULL;
99
100         char *addressbook_name = NULL;
101         int address_book_id = 0;
102         int count = 0;
103         unsigned int i = 0;
104         gint status;
105         bool is_first_condition = true;
106         DBG("Addressbook [%d]", addressbook);
107         /* Create query*/
108         status = contacts_query_create(_contacts_person_contact._uri, &query);
109         if (status != 0) {
110                 ERR("Could not create query");
111                 return NULL;
112         }
113
114         /* Create addressbook Filter*/
115         contacts_db_get_all_records(_contacts_address_book._uri, 0, 0,
116                 &recordList);
117         contacts_filter_create(_contacts_person_contact._uri, &filter);
118         contacts_list_get_count(recordList, &count);
119         INFO("COUNT %d", count);
120         for (i = 0; i < count; i++) {
121                 status = contacts_list_get_current_record_p(recordList, &record);
122                 if (status != CONTACTS_ERROR_NONE) {
123                         ERR("Contact list get api failed %d", status);
124                         goto next;
125                 }
126                 status = contacts_record_get_str_p(record, _contacts_address_book.name,
127                                         &addressbook_name);
128                 if (status != CONTACTS_ERROR_NONE) {
129                         ERR("Contact record get api failed %d", status);
130                         goto next;
131                 }
132                 status = contacts_record_get_int(record, _contacts_address_book.id,
133                                         &address_book_id);
134                 if (status != CONTACTS_ERROR_NONE) {
135                         ERR("contacts record get int api failed %d", status);
136                         goto next;
137                 }
138
139                 DBG("Addressbook ID: [%d] Addressbook Name: [%s]",
140                                 address_book_id, addressbook_name);
141
142                 if (__bt_is_matching_addressbook(addressbook_name,
143                                 addressbook)) {
144                         if (is_first_condition)
145                                 is_first_condition = false;
146                         else
147                                 contacts_filter_add_operator(filter,
148                                                 CONTACTS_FILTER_OPERATOR_OR);
149                         DBG("SELECTED Addressbook ID: [%d] Addressbook Name: [%s]",
150                                         address_book_id, addressbook_name);
151                         status = contacts_filter_add_int(filter,
152                                         _contacts_person_contact.address_book_id,
153                                         CONTACTS_MATCH_EQUAL, address_book_id);
154                         if (status != CONTACTS_ERROR_NONE)
155                                 ERR("Contact filter add failed %d", status);
156                 }
157 next:
158                 if (contacts_list_next(recordList) != CONTACTS_ERROR_NONE)
159                         break;
160         }
161
162         contacts_list_destroy(recordList, true);
163
164         status = contacts_query_set_filter(query, filter);
165         if (status != CONTACTS_ERROR_NONE)
166                 ERR("Could not Apply Filter");
167
168         contacts_filter_destroy(filter);
169         FN_END;
170         return query;
171 }
172
173 gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
174                                 guint *count)
175 {
176         FN_START;
177         contacts_query_h query = NULL;
178
179         gint status;
180         gint signed_count;
181         INFO("Pb type %d", pb_type);
182         switch (pb_type) {
183         case TELECOM_PB:
184                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
185                 break;
186         case TELECOM_ICH:
187                 query = __bluetooth_pb_query_phone_log_incoming();
188                 break;
189         case TELECOM_OCH:
190                 query = __bluetooth_pb_query_phone_log_outgoing();
191                 break;
192         case TELECOM_MCH:
193                 query = __bluetooth_pb_query_phone_log_missed();
194                 break;
195         case TELECOM_CCH:
196                 query = __bluetooth_pb_query_phone_log_combined();
197                 break;
198 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
199         case SIM_PB:
200                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
201                 break;
202 #endif
203         default:
204                 return FALSE;
205         }
206
207         if (query == NULL)
208                 return FALSE;
209
210         status = contacts_db_get_count_with_query(query, &signed_count);
211
212         if (status != CONTACTS_ERROR_NONE) {
213                 contacts_query_destroy(query);
214                 return FALSE;
215         }
216
217         contacts_query_destroy(query);
218
219         if (signed_count < 0)
220                 signed_count = 0;
221
222         *count = (gint) signed_count;
223
224         FN_END;
225         return TRUE;
226 }
227
228 void __bluetooth_pb_list_ptr_array_add(const gchar *name,
229                                                 const gchar *number,
230                                                 gint handle)
231 {
232         FN_START;
233         gchar *temp_name = g_strdup(name);
234         gchar *temp_number = NULL;
235         if (number == NULL)
236                 temp_number = g_strdup("");
237         else
238                 temp_number = g_strdup(number);
239
240         _bt_read_phonebook_entries_indicator(temp_name,
241                                                 temp_number, handle);
242
243         g_free(temp_name);
244         g_free(temp_number);
245         FN_END;
246 }
247
248 void __bluetooth_pb_list_ptr_array_add_by_name(const gchar *name,
249                                                 const gchar *number,
250                                                 gint handle)
251 {
252         FN_START;
253         gchar *temp_name = g_strdup(name);
254         gchar *temp_number = NULL;
255         if (number == NULL)
256                 temp_number = g_strdup("");
257         else
258                 temp_number = g_strdup(number);
259
260         _bt_read_phonebook_entries_indicator_by_name(temp_name,
261                                                 temp_number, handle);
262
263         g_free(temp_name);
264         g_free(temp_number);
265         FN_END;
266 }
267
268 contacts_query_h __bluetooth_pb_query_person_number(void)
269 {
270         FN_START;
271         contacts_query_h query = NULL;
272
273         gint status;
274
275         status = contacts_query_create(_contacts_person_number._uri,
276                                 &query);
277
278         if (status != CONTACTS_ERROR_NONE)
279                 return NULL;
280
281         FN_END;
282         return query;
283 }
284
285 void __bluetooth_pb_get_contact_list_number(
286                                                 contacts_query_h query,
287                                                 gint start_index,
288                                                 gint end_index,
289                                                 gint *count)
290 {
291         FN_START;
292         contacts_list_h record_list = NULL;
293         gint status;
294         gint i;
295         gint from;
296         gint to;
297         gint offset;
298
299         from = start_index;
300         to = end_index;
301
302         if (from < 1)
303                 from = 1;
304
305         if (to < 1)
306                 to = 1;
307
308         offset = to - from + 1;
309         if (offset <= 0)
310                 return;
311
312         i = from;
313
314         status = contacts_db_get_records_with_query(query,
315                         from - 1 , offset,
316                         &record_list);
317
318         if (status != CONTACTS_ERROR_NONE) {
319                 contacts_list_destroy(record_list, TRUE);
320                 return;
321         }
322
323         status = contacts_list_first(record_list);
324
325         if (status != CONTACTS_ERROR_NONE) {
326                 contacts_list_destroy(record_list, TRUE);
327                 return;
328         }
329
330         do {
331                 contacts_record_h record;
332
333                 gchar *display_name;
334                 gchar *number;
335
336                 record = NULL;
337                 status = contacts_list_get_current_record_p(record_list,
338                                 &record);
339
340                 if (status != CONTACTS_ERROR_NONE)
341                         continue;
342
343                 display_name = NULL;
344                 number = NULL;
345
346                 contacts_record_get_str_p(record,
347                                 _contacts_person_number.display_name,
348                                 &display_name);
349                 contacts_record_get_str_p(record,
350                                 _contacts_person_number.number,
351                                 &number);
352
353                 __bluetooth_pb_list_ptr_array_add(display_name, number, i);
354
355                 i++;
356         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
357         *count = i;
358
359         contacts_list_destroy(record_list, TRUE);
360         FN_END;
361 }
362
363 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
364 static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
365 {
366         FN_START;
367         gint count = 0;
368
369         gint status;
370         gint i;
371
372         gchar *str = NULL;
373
374         status = contacts_record_get_child_record_count(contact,
375                         _contacts_contact.number,
376                         &count);
377
378         if (status != CONTACTS_ERROR_NONE)
379                 return NULL;
380
381         for (i = 0; i < count; i++) {
382                 contacts_record_h number = NULL;
383
384                 gchar *tmp = NULL;
385
386                 bool is_default = false;
387
388                 status = contacts_record_get_child_record_at_p(contact,
389                                 _contacts_contact.number, i, &number);
390
391                 if (status != CONTACTS_ERROR_NONE)
392                         continue;
393
394                 status = contacts_record_get_bool(number,
395                                 _contacts_number.is_default,
396                                 &is_default);
397
398                 if (status != CONTACTS_ERROR_NONE)
399                         continue;
400
401                 if (is_default == FALSE)
402                         continue;
403
404                 status = contacts_record_get_str_p(number,
405                                 _contacts_number.number,
406                                 &tmp);
407
408                 if (status != CONTACTS_ERROR_NONE)
409                         continue;
410
411                 if (tmp) {
412                         str = g_strdup(tmp);
413                         break;
414                 }
415         }
416
417         /* get first number */
418         if (str == NULL) {
419                 gchar *tmp = NULL;
420
421                 contacts_record_h number = NULL;
422
423                 status = contacts_record_get_child_record_at_p(contact,
424                                 _contacts_contact.number, 0, &number);
425
426                 if (status != CONTACTS_ERROR_NONE)
427                         return NULL;
428
429                 status = contacts_record_get_str_p(number,
430                                 _contacts_number.number,
431                                 &tmp);
432
433                 if (status != CONTACTS_ERROR_NONE)
434                         return NULL;
435
436                 str = g_strdup(tmp);
437         }
438
439         FN_END;
440         return str;
441 }
442
443 gchar *_bluetooth_pb_number_from_person_id(gint person_id)
444 {
445         FN_START;
446         contacts_record_h person = NULL;
447         contacts_record_h contact = NULL;
448
449         gint status;
450         gint contact_id = 0;
451
452         gchar *str;
453
454         status = contacts_db_get_record(_contacts_person._uri,
455                         person_id,
456                         &person);
457
458         if (status != CONTACTS_ERROR_NONE)
459                 return NULL;
460
461
462         status = contacts_record_get_int(person,
463                         _contacts_person.display_contact_id,
464                         &contact_id);
465
466         if (status != CONTACTS_ERROR_NONE) {
467                 contacts_record_destroy(person, TRUE);
468                 return NULL;
469         }
470
471         status = contacts_db_get_record(_contacts_contact._uri,
472                         contact_id,
473                         &contact);
474
475         if (status != CONTACTS_ERROR_NONE) {
476                 contacts_record_destroy(person, TRUE);
477                 return NULL;
478         }
479
480         str = __bluetooth_pb_number_from_contact(contact);
481
482         contacts_record_destroy(contact, TRUE);
483         contacts_record_destroy(person, TRUE);
484
485         FN_END;
486         return str;
487 }
488
489 gchar *_bluetooth_pb_name_from_person_id(gint person_id)
490 {
491         FN_START;
492         contacts_record_h person = NULL;
493         contacts_record_h contact = NULL;
494
495         gint status;
496         gint contact_id = 0;
497
498         gchar *str;
499
500         status = contacts_db_get_record(_contacts_person._uri,
501                         person_id,
502                         &person);
503
504         if (status != CONTACTS_ERROR_NONE)
505                 return NULL;
506
507         status = contacts_record_get_int(person,
508                         _contacts_person.display_contact_id,
509                         &contact_id);
510
511         if (status != CONTACTS_ERROR_NONE) {
512                 contacts_record_destroy(person, TRUE);
513                 return NULL;
514         }
515
516         status = contacts_db_get_record(_contacts_contact._uri,
517                         contact_id,
518                         &contact);
519
520         if (status != CONTACTS_ERROR_NONE) {
521                 contacts_record_destroy(person, TRUE);
522                 return NULL;
523         }
524
525         str = __bluetooth_pb_name_from_contact(contact);
526
527         contacts_record_destroy(contact, TRUE);
528         contacts_record_destroy(person, TRUE);
529
530         FN_END;
531         return str;
532 }
533
534 static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
535 {
536         FN_START;
537         GString *escaped;
538
539         gchar *st = NULL;
540         gchar *pos = NULL;
541
542         if (str == NULL)
543                 return NULL;
544
545         escaped = g_string_new(NULL);
546
547         st = (gchar *)str;
548         pos = st;
549
550         while (*pos != '\0') {
551                 if (*pos == ';') {
552                         g_string_append_len(escaped, st, (pos - st));
553                         g_string_append(escaped, "\\;");
554
555                         pos++;
556                         st = pos;
557                 } else {
558                         pos++;
559                 }
560         }
561
562         g_string_append_len(escaped, st, (pos - st));
563         FN_END;
564         return g_string_free(escaped, FALSE);
565 }
566
567 static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
568 {
569         FN_START;
570         contacts_record_h name = NULL;
571
572         GString *str;
573
574         gint status;
575         gint i;
576
577         gint name_size = 5;
578         gint name_val[] = { _contacts_name.last,
579                         _contacts_name.first,
580                         _contacts_name.addition,
581                         _contacts_name.prefix,
582                         _contacts_name.suffix };
583
584
585         status = contacts_record_get_child_record_at_p(contact,
586                         _contacts_contact.name, 0, &name);
587
588         if (status != CONTACTS_ERROR_NONE)
589                 return NULL;
590
591         str = g_string_new(NULL);
592
593         for (i = 0; i < name_size; i++) {
594                 gchar *tmp = NULL;
595                 gchar *escape = NULL;
596
597                 status = contacts_record_get_str_p(name, name_val[i], &tmp);
598
599                 if (status != CONTACTS_ERROR_NONE)
600                         continue;
601
602                 escape = __bluetooth_pb_vcard_escape(tmp);
603
604                 g_string_append(str, escape);
605
606                 g_free(escape);
607         }
608
609         FN_END;
610         return g_string_free(str, FALSE);
611 }
612
613 static void __bluetooth_pb_get_contact_list(
614                                         contacts_query_h query,
615                                         gint start_index,
616                                         gint end_index,
617                                         gint *count)
618 {
619         FN_START;
620         contacts_list_h record_list = NULL;
621         gint i = 0;
622
623         gint status;
624
625         status = contacts_db_get_records_with_query(query,
626                         start_index, end_index, &record_list);
627
628         if (status != CONTACTS_ERROR_NONE) {
629                 contacts_list_destroy(record_list, TRUE);
630                 return;
631         }
632
633         status = contacts_list_first(record_list);
634
635         if (status != CONTACTS_ERROR_NONE) {
636                 contacts_list_destroy(record_list, TRUE);
637                 return;
638         }
639
640         do {
641                 contacts_record_h record;
642
643                 gint id;
644
645                 record = NULL;
646                 status = contacts_list_get_current_record_p(record_list,
647                                 &record);
648
649                 if (status != CONTACTS_ERROR_NONE)
650                         continue;
651
652                 id = 0;
653                 status = contacts_record_get_int(record,
654                                 _contacts_person_contact.person_id,
655                                 &id);
656
657                 if (status != CONTACTS_ERROR_NONE)
658                         continue;
659
660                 gchar *name;
661                 gchar *number;
662
663                 name = _bluetooth_pb_name_from_person_id(id);
664                 number = _bluetooth_pb_number_from_person_id(id);
665
666                 __bluetooth_pb_list_ptr_array_add(name, number, id);
667                 i++;
668
669                 g_free(name);
670                 g_free(number);
671
672         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
673
674         *count = i;
675         contacts_list_destroy(record_list, TRUE);
676         FN_END;
677 }
678
679 static void __bluetooth_pb_get_contact_list_by_name(
680                                         contacts_query_h query,
681                                         gint start_index,
682                                         gint end_index,
683                                         const char *str,
684                                         gint *count)
685 {
686         FN_START;
687         contacts_list_h record_list = NULL;
688         gint i = 0;
689         contacts_record_h record;
690         gint id;
691         gint status;
692         gchar *name;
693         gchar *number;
694         char *pb_name_up;
695
696         status = contacts_db_get_records_with_query(query,
697                         start_index, end_index, &record_list);
698
699         if (status != CONTACTS_ERROR_NONE) {
700                 contacts_list_destroy(record_list, TRUE);
701                 return;
702         }
703
704         status = contacts_list_first(record_list);
705
706         if (status != CONTACTS_ERROR_NONE) {
707                 contacts_list_destroy(record_list, TRUE);
708                 return;
709         }
710
711         do {
712                 record = NULL;
713                 status = contacts_list_get_current_record_p(record_list,
714                                 &record);
715
716                 if (status != CONTACTS_ERROR_NONE)
717                         continue;
718
719                 id = 0;
720                 status = contacts_record_get_int(record,
721                                 _contacts_person_contact.person_id,
722                                 &id);
723
724                 if (status != CONTACTS_ERROR_NONE)
725                         continue;
726
727                 name = _bluetooth_pb_name_from_person_id(id);
728                 number = _bluetooth_pb_number_from_person_id(id);
729                 pb_name_up = g_ascii_strup(name, strlen(name));
730
731                 if (g_strstr_len(pb_name_up, -1, str) != NULL)
732                         __bluetooth_pb_list_ptr_array_add_by_name(name, number, id);
733
734                 g_free(pb_name_up);
735                 i++;
736
737                 g_free(name);
738                 g_free(number);
739
740         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
741
742         *count = i;
743         contacts_list_destroy(record_list, TRUE);
744         FN_END;
745 }
746 #endif
747
748 static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void)
749 {
750         FN_START;
751         gint size = 4;
752         gint match[] = {
753                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
754                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
755                 CONTACTS_PLOG_TYPE_VOICE_REJECT,
756                 CONTACTS_PLOG_TYPE_VIDEO_REJECT
757         };
758
759         FN_END;
760         return __bluetooth_pb_query_phone_log(match, size);
761 }
762
763 static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void)
764 {
765         FN_START;
766         gint size = 2;
767         gint match[] = {
768                 CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
769                 CONTACTS_PLOG_TYPE_VIDEO_OUTGOING
770         };
771
772         FN_END;
773         return __bluetooth_pb_query_phone_log(match, size);
774 }
775
776 static contacts_query_h __bluetooth_pb_query_phone_log_missed(void)
777 {
778         FN_START;
779         gint size = 4;
780         gint match[] = {
781                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
782                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
783                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
784                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN
785         };
786
787         FN_END;
788         return __bluetooth_pb_query_phone_log(match, size);
789 }
790
791 static contacts_query_h __bluetooth_pb_query_phone_log_combined(void)
792 {
793         FN_START;
794         gint size = 10;
795         gint match[] = {
796                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
797                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
798                 CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
799                 CONTACTS_PLOG_TYPE_VIDEO_OUTGOING,
800                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
801                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
802                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
803                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN,
804                 CONTACTS_PLOG_TYPE_VOICE_REJECT,
805                 CONTACTS_PLOG_TYPE_VIDEO_REJECT
806         };
807
808         FN_END;
809         return __bluetooth_pb_query_phone_log(match, size);
810 }
811
812
813 gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
814                                                 gint *match,
815                                                 gint size)
816 {
817         FN_START;
818         gint i;
819         gint status;
820
821         for (i = 0; i < size; i++) {
822
823                 if (i > 0) {
824                         status = contacts_filter_add_operator(filter,
825                                         CONTACTS_FILTER_OPERATOR_OR);
826
827                         if (status != CONTACTS_ERROR_NONE)
828                                 return status;
829                 }
830
831                 status = contacts_filter_add_int(filter,
832                                 _contacts_phone_log.log_type,
833                                 CONTACTS_MATCH_EQUAL,
834                                 match[i]);
835
836                 if (status != CONTACTS_ERROR_NONE)
837                         return status;
838         }
839
840         FN_END;
841         return CONTACTS_ERROR_NONE;
842 }
843
844 contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
845                                                 gint size)
846 {
847         FN_START;
848         contacts_query_h query = NULL;
849         contacts_filter_h filter = NULL;
850
851         gint status;
852
853         status = contacts_query_create(_contacts_phone_log._uri,
854                                 &query);
855
856         if (status != CONTACTS_ERROR_NONE)
857                 return NULL;
858
859         status = contacts_filter_create(_contacts_phone_log._uri, &filter);
860
861         if (status != CONTACTS_ERROR_NONE) {
862                 contacts_query_destroy(query);
863                 return NULL;
864         }
865
866         status = __bluetooth_pb_phone_log_filter_append(filter, match, size);
867
868         if (status != CONTACTS_ERROR_NONE) {
869                 contacts_filter_destroy(filter);
870                 contacts_query_destroy(query);
871                 return NULL;
872         }
873
874         status = contacts_query_set_filter(query, filter);
875
876         if (status != CONTACTS_ERROR_NONE) {
877                 contacts_filter_destroy(filter);
878                 contacts_query_destroy(query);
879                 return NULL;
880         }
881
882         status = contacts_query_set_sort(query,
883                         _contacts_phone_log.log_time,
884                         false);
885
886         if (status != CONTACTS_ERROR_NONE) {
887                 contacts_filter_destroy(filter);
888                 contacts_query_destroy(query);
889                 return NULL;
890         }
891
892         contacts_filter_destroy(filter);
893
894         FN_END;
895         return query;
896 }
897
898 static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
899 {
900         FN_START;
901         contacts_query_h query = NULL;
902         contacts_filter_h filter = NULL;
903         contacts_list_h record_list = NULL;
904
905         contacts_record_h phone_log = NULL;
906         contacts_record_h record = NULL;
907
908         gint status;
909         gint person_id = 0;
910
911         status = contacts_db_get_record(_contacts_phone_log._uri,
912                         phonelog_id,
913                         &phone_log);
914
915         if (status != CONTACTS_ERROR_NONE)
916                 return 0;
917
918         status = contacts_record_get_int(phone_log,
919                         _contacts_phone_log.person_id,
920                         &person_id);
921
922         if (status != CONTACTS_ERROR_NONE) {
923                 contacts_record_destroy(phone_log, TRUE);
924                 return 0;
925         }
926
927         contacts_record_destroy(phone_log, TRUE);
928
929         if (person_id)
930                 return person_id;
931
932         status = contacts_filter_create(_contacts_person_phone_log._uri,
933                         &filter);
934
935         if (status != CONTACTS_ERROR_NONE)
936                 return 0;
937
938
939         status = contacts_filter_add_int(filter,
940                         _contacts_person_phone_log.log_id,
941                         CONTACTS_MATCH_EQUAL,
942                         phonelog_id);
943
944         if (status != CONTACTS_ERROR_NONE)
945                 goto done;
946
947         status = contacts_query_create(_contacts_person_phone_log._uri, &query);
948
949         if (status != CONTACTS_ERROR_NONE)
950                 goto done;
951
952         status = contacts_query_set_filter(query, filter);
953
954         if (status != CONTACTS_ERROR_NONE)
955                 goto done;
956
957         status = contacts_db_get_records_with_query(query, -1, -1,
958                                                                 &record_list);
959
960         if (status != CONTACTS_ERROR_NONE)
961                 goto done;
962
963         status = contacts_list_first(record_list);
964
965         if (status != CONTACTS_ERROR_NONE)
966                 goto done;
967
968         status = contacts_list_get_current_record_p(record_list, &record);
969
970         if (status != CONTACTS_ERROR_NONE)
971                 goto done;
972
973         status = contacts_record_get_int(record,
974                         _contacts_person_phone_log.person_id,
975                         &person_id);
976
977         if (status != CONTACTS_ERROR_NONE)
978                 goto done;
979
980 done:
981         if (record_list != NULL)
982                 contacts_list_destroy(record_list, TRUE);
983
984         contacts_filter_destroy(filter);
985
986         if (query != NULL)
987                 contacts_query_destroy(query);
988
989         FN_END;
990         return person_id;
991 }
992
993 gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
994 {
995         FN_START;
996         contacts_record_h person = NULL;
997
998         gint status;
999
1000         gchar *str = NULL;
1001
1002         status = contacts_db_get_record(_contacts_person._uri,
1003                         person_id,
1004                         &person);
1005
1006         if (status != CONTACTS_ERROR_NONE)
1007                 return NULL;
1008
1009         status = contacts_record_get_str(person,
1010                         _contacts_person.display_name,
1011                         &str);
1012
1013         if (status != CONTACTS_ERROR_NONE)
1014                 return NULL;
1015
1016         contacts_record_destroy(person, TRUE);
1017
1018         FN_END;
1019         return str;
1020 }
1021
1022 gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
1023 {
1024         FN_START;
1025         gint person_id = 0;
1026         gchar *str = NULL;
1027
1028         person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
1029
1030         if (person_id > 0)
1031                 str = _bluetooth_pb_fn_from_person_id(person_id);
1032         else
1033                 str = g_strdup("");
1034
1035         FN_END;
1036         return str;
1037 }
1038
1039
1040 static void __bluetooth_pb_get_phone_log_list_number(contacts_query_h query,
1041                                                 gint start_index,
1042                                                 gint end_index,
1043                                                 int *count)
1044 {
1045         FN_START;
1046         contacts_list_h record_list = NULL;
1047
1048         gint status;
1049
1050         gint i;
1051
1052         gint from;
1053         gint to;
1054         gint offset;
1055
1056         from = start_index;
1057         to = end_index;
1058
1059         if (from < 1)
1060                 from = 1;
1061
1062         if (to < 1)
1063                 to = 1;
1064
1065         offset = to - from + 1;
1066         if (offset <= 0)
1067                 return;
1068
1069         i = from;
1070
1071         status = contacts_db_get_records_with_query(query,
1072                         from - 1 , offset,
1073                         &record_list);
1074
1075         if (status != CONTACTS_ERROR_NONE) {
1076                 contacts_list_destroy(record_list, TRUE);
1077                 return;
1078         }
1079
1080         status = contacts_list_first(record_list);
1081         if (status != CONTACTS_ERROR_NONE) {
1082                 contacts_list_destroy(record_list, TRUE);
1083                 return;
1084         }
1085
1086         do {
1087                 contacts_record_h record = NULL;
1088
1089                 gint id;
1090
1091                 gchar *display_name;
1092                 gchar *number;
1093
1094                 record = NULL;
1095                 status = contacts_list_get_current_record_p(record_list,
1096                                 &record);
1097
1098                 if (status != CONTACTS_ERROR_NONE)
1099                         continue;
1100
1101                 id = 0;
1102                 status = contacts_record_get_int(record,
1103                                 _contacts_phone_log.id,
1104                                 &id);
1105                 if (status != CONTACTS_ERROR_NONE) {
1106                         ERR("contact_record_get_int api failed %d", status);
1107                         continue;
1108                 }
1109
1110                 display_name = _bluetooth_pb_fn_from_phonelog_id(id);
1111
1112                 number = NULL;
1113                 contacts_record_get_str_p(record,
1114                                 _contacts_phone_log.address,
1115                                 &number);
1116
1117
1118                 __bluetooth_pb_list_ptr_array_add(display_name, number, i);
1119
1120                 i++;
1121
1122                 g_free(display_name);
1123
1124         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1125         *count = i;
1126
1127         contacts_list_destroy(record_list, TRUE);
1128         FN_END;
1129 }
1130
1131 void __bluetooth_pb_get_list_entries_by_name(
1132                                                 PhoneBookType pb_type,
1133                                                 gint start_index,
1134                                                 gint end_index,
1135                                                 const char *str,
1136                                                 gint *count)
1137 {
1138         FN_START;
1139         contacts_query_h query;
1140
1141         switch (pb_type) {
1142         case TELECOM_PB:
1143                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1144                 __bluetooth_pb_get_contact_list_by_name(query,
1145                                 start_index, end_index, str, count);
1146                 break;
1147
1148         case TELECOM_ICH:
1149                 query = __bluetooth_pb_query_phone_log_incoming();
1150                 __bluetooth_pb_get_contact_list_by_name(query,
1151                                 start_index, end_index, str, count);
1152                 break;
1153         case TELECOM_OCH:
1154                 query = __bluetooth_pb_query_phone_log_outgoing();
1155                 __bluetooth_pb_get_contact_list_by_name(query,
1156                                 start_index, end_index, str, count);
1157                 break;
1158         case TELECOM_MCH:
1159                 query = __bluetooth_pb_query_phone_log_missed();
1160                 __bluetooth_pb_get_contact_list_by_name(query,
1161                                 start_index, end_index, str, count);
1162                 break;
1163         case TELECOM_CCH:
1164                 query = __bluetooth_pb_query_phone_log_combined();
1165                 __bluetooth_pb_get_contact_list_by_name(query,
1166                                 start_index, end_index, str, count);
1167                 break;
1168 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1169         case SIM_PB:
1170                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1171                 __bluetooth_pb_get_contact_list_by_name(query,
1172                         start_index, end_index, str, count);
1173                 break;
1174 #endif
1175         default:
1176                 return;
1177         }
1178
1179         if (query)
1180                 contacts_query_destroy(query);
1181         FN_END;
1182 }
1183
1184 void __bluetooth_pb_get_list_number(
1185                                                 PhoneBookType pb_type,
1186                                                 gint start_index,
1187                                                 gint end_index,
1188                                                 gint *count)
1189 {
1190         FN_START;
1191         contacts_query_h query;
1192
1193         switch (pb_type) {
1194         case TELECOM_PB:
1195                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1196                 __bluetooth_pb_get_contact_list(query,
1197                                 start_index, end_index, count);
1198                 break;
1199
1200         case TELECOM_ICH:
1201                 query = __bluetooth_pb_query_phone_log_incoming();
1202                 __bluetooth_pb_get_phone_log_list_number(query,
1203                                 start_index, end_index, count);
1204                 break;
1205         case TELECOM_OCH:
1206                 query = __bluetooth_pb_query_phone_log_outgoing();
1207                 __bluetooth_pb_get_phone_log_list_number(query,
1208                                 start_index, end_index, count);
1209                 break;
1210         case TELECOM_MCH:
1211                 query = __bluetooth_pb_query_phone_log_missed();
1212                 __bluetooth_pb_get_phone_log_list_number(query,
1213                                 start_index, end_index, count);
1214                 break;
1215         case TELECOM_CCH:
1216                 query = __bluetooth_pb_query_phone_log_combined();
1217                 __bluetooth_pb_get_phone_log_list_number(query,
1218                                 start_index, end_index, count);
1219                 break;
1220 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1221         case SIM_PB:
1222                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1223                 __bluetooth_pb_get_contact_list(query,
1224                         start_index, end_index, count);
1225                 break;
1226 #endif
1227         default:
1228                 return;
1229         }
1230
1231         if (query)
1232                 contacts_query_destroy(query);
1233         FN_END;
1234 }
1235
1236