Fix the build fail for other devices
[platform/core/connectivity/bluetooth-agent.git] / pb-agent / bluetooth_pb_agent.c
1 /*
2  * Bluetooth-agent
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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.leek@samsung.com>
10  *
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
14  *
15  *              http://www.apache.org/licenses/LICENSE-2.0
16  *
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.
22  *
23  */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <signal.h>
30 #include <glib.h>
31 #include <dbus/dbus-glib.h>
32
33
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37
38 #include <contacts.h>
39
40 #include <TapiUtility.h>
41 #include <ITapiSim.h>
42
43 #include "bluetooth_pb_agent.h"
44 #include "bluetooth_pb_vcard.h"
45
46 #define BLUETOOTH_PB_AGENT_TIMEOUT 600
47
48 typedef struct {
49         GObject parent;
50
51         DBusGConnection *bus;
52         DBusGProxy *proxy;
53
54         TapiHandle *tapi_handle;
55         gchar *tel_number;
56         guint timeout_id;
57
58         PhoneBookType pb_type;
59 } BluetoothPbAgent;
60
61 typedef struct {
62         GObjectClass parent;
63
64         void (*clear) (BluetoothPbAgent *agent);
65 } BluetoothPbAgentClass;
66
67 enum {
68         CLEAR,
69         LAST_SIGNAL
70 };
71
72 GType bluetooth_pb_agent_get_type(void);
73
74 #define BLUETOOTH_PB_TYPE_AGENT (bluetooth_pb_agent_get_type())
75
76 #define BLUETOOTH_PB_AGENT(object) \
77         (G_TYPE_CHECK_INSTANCE_CAST((object), \
78         BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgent))
79 #define BLUETOOTH_PB_AGENT_CLASS(klass) \
80         (G_TYPE_CHECK_CLASS_CAST((klass), \
81         BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgentClass))
82 #define BLUETOOTH_IS_PB_AGENT(object) \
83         (G_TYPE_CHECK_INSTANCE_TYPE((object), \
84         BLUETOOTH_PB_TYPE_AGENT))
85 #define BLUETOOTH_IS_PB_AGENT_CLASS(klass) \
86         (G_TYPE_CHECK_CLASS_TYPE((klass), \
87         BLUETOOTH_PB_TYPE_AGENT))
88 #define BLUETOOTH_PB_AGENT_GET_CLASS(obj) \
89         (G_TYPE_INSTANCE_GET_CLASS((obj), \
90         BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgentClass))
91
92 G_DEFINE_TYPE(BluetoothPbAgent, bluetooth_pb_agent, G_TYPE_OBJECT)
93
94 #define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", G_TYPE_STRING, \
95                                                         G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID))
96
97 static guint signals[LAST_SIGNAL] = { 0 };
98 static guint total_missed_call_count = 0;
99 static guint unnotified_missed_call_count = 0;
100
101 static GMainLoop *mainloop = NULL;
102
103 static void bluetooth_pb_agent_finalize(GObject *obj);
104
105 static void bluetooth_pb_agent_clear(BluetoothPbAgent *agent);
106
107 /* Dbus messages */
108 static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
109                                                 const gchar ***folder_list,
110                                                 GError **error);
111
112 static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
113                                         const char *name,
114                                         guint64 filter,
115                                         guint8 format,
116                                         guint16 max_list_count,
117                                         guint16 list_start_offset,
118                                         DBusGMethodInvocation *context);
119
120 static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
121                                                 const char *name,
122                                                 DBusGMethodInvocation *context);
123
124 static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
125                                                 const char *name,
126                                                 DBusGMethodInvocation *context);
127
128 static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
129                                                 const gchar *folder,
130                                                 const gchar *id,
131                                                 guint64 filter,
132                                                 guint8 format,
133                                                 DBusGMethodInvocation *context);
134
135 static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
136                                         const gchar *command,
137                                         DBusGMethodInvocation *context);
138
139 static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
140                                         const gchar *command,
141                                         gint32 start_index,
142                                         gint32 end_index,
143                                         DBusGMethodInvocation *context);
144
145 static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *agent,
146                                                         const gchar *command,
147                                                         const gchar *find_text,
148                                                         DBusGMethodInvocation *context);
149
150 static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
151                                                 gchar *path,
152                                                 DBusGMethodInvocation *context);
153
154 static gboolean bluetooth_pb_add_contact (BluetoothPbAgent *agent,
155                                         const char *filename,
156                                         GError **error);
157
158 static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
159                                         DBusGMethodInvocation *context);
160
161 static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
162                                         gint code,
163                                         const gchar *message);
164
165 static PhoneBookType __bluetooth_pb_get_pb_type(const char *name);
166
167 static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name);
168
169 static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
170                                                 gint *match,
171                                                 gint size);
172
173 static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
174                                                 gint size);
175
176 static contacts_query_h __bluetooth_pb_query_person(int addressbook);
177
178 static contacts_query_h __bluetooth_pb_query_person_number(void);
179
180 static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void);
181
182 static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void);
183
184 static contacts_query_h __bluetooth_pb_query_phone_log_missed(void);
185
186 static contacts_query_h __bluetooth_pb_query_phone_log_combined(void);
187
188 static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
189                                 guint *count);
190
191 static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count);
192
193 static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record);
194
195 static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
196                                 PhoneBookType pb_type,
197                                 guint64 filter,
198                                 guint8 format,
199                                 guint16 max_list_count,
200                                 guint16 list_start_offset,
201                                 GPtrArray *vcards);
202
203 static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
204                                         contacts_query_h query,
205                                         GPtrArray *ptr_array);
206
207 static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
208                                         contacts_query_h query,
209                                         GPtrArray *ptr_array);
210
211 static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
212                                 PhoneBookType pb_type,
213                                 GPtrArray *ptr_array);
214
215 static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
216                                                 contacts_query_h query,
217                                                 gint start_index,
218                                                 gint end_index,
219                                                 GPtrArray *ptr_array);
220
221 static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
222                                                 contacts_query_h query,
223                                                 gint start_index,
224                                                 gint end_index,
225                                                 GPtrArray *ptr_array);
226
227 static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
228                                                 PhoneBookType pb_type,
229                                                 gint start_index,
230                                                 gint end_index,
231                                                 GPtrArray *ptr_array);
232
233 static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
234                                                 contacts_query_h query,
235                                                 const gchar *find_text,
236                                                 GPtrArray *ptr_array);
237
238 static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
239                                                 contacts_query_h query,
240                                                 const gchar *find_text,
241                                                 GPtrArray *ptr_array);
242
243 static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
244                                         PhoneBookType pb_type,
245                                         const gchar *find_text,
246                                         GPtrArray *ptr_array);
247
248 static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
249                                                 const gchar *name,
250                                                 const gchar *number,
251                                                 gint handle);
252
253 static void __bluetooth_pb_list_ptr_array_free(gpointer data);
254
255 static void __bluetooth_pb_agent_signal_handler(int signum);
256
257 static void __bluetooth_pb_contact_changed(const gchar *view_uri,
258                                         void *user_data);
259
260 static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent);
261
262 static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data);
263
264 static void __bluetooth_pb_tel_callback(TapiHandle *handle,
265                                         int result,
266                                         void *data,
267                                         void *user_data);
268
269 static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent);
270
271 #include "bluetooth_pb_agent_glue.h"
272
273 static void bluetooth_pb_agent_init(BluetoothPbAgent *agent)
274 {
275         FN_START;
276         agent->bus = NULL;
277         agent->proxy = NULL;
278         agent->tapi_handle = NULL;
279         agent->tel_number = NULL;
280         agent->timeout_id = 0;
281         agent->pb_type = TELECOM_NONE;
282         FN_END;
283 }
284
285 static void bluetooth_pb_agent_class_init(BluetoothPbAgentClass *klass)
286 {
287         FN_START;
288         GObjectClass *object_class = (GObjectClass *) klass;
289
290         klass->clear = bluetooth_pb_agent_clear;
291
292         object_class->finalize = bluetooth_pb_agent_finalize;
293
294         signals[CLEAR] = g_signal_new("clear",
295                         G_TYPE_FROM_CLASS(klass),
296                         G_SIGNAL_RUN_LAST,
297                         G_STRUCT_OFFSET(BluetoothPbAgentClass, clear),
298                         NULL, NULL,
299                         g_cclosure_marshal_VOID__VOID,
300                         G_TYPE_NONE, 0);
301
302         dbus_g_object_type_install_info(BLUETOOTH_PB_TYPE_AGENT,
303                                         &dbus_glib_bluetooth_pb_object_info);
304         FN_END;
305 }
306
307 static void bluetooth_pb_agent_finalize(GObject *obj)
308 {
309         FN_START;
310         BluetoothPbAgent *agent  = BLUETOOTH_PB_AGENT(obj);
311
312         if (agent->tapi_handle) {
313                 tel_deinit(agent->tapi_handle);
314                 agent->tapi_handle = NULL;
315         }
316
317         if (agent->tel_number) {
318                 g_free(agent->tel_number);
319                 agent->tel_number = NULL;
320         }
321
322         if(agent->timeout_id) {
323                 g_source_remove(agent->timeout_id);
324                 agent->timeout_id = 0;
325         }
326
327         if (agent->proxy) {
328                 g_object_unref(agent->proxy);
329                 agent->proxy = NULL;
330         }
331
332         if (agent->bus) {
333                 dbus_g_connection_unref(agent->bus);
334                 agent->bus = NULL;
335         }
336
337
338         G_OBJECT_CLASS(bluetooth_pb_agent_parent_class)->finalize(obj);
339         FN_END;
340 }
341
342 static void bluetooth_pb_agent_clear(BluetoothPbAgent *agent)
343 {
344         FN_START;
345         agent->pb_type = TELECOM_NONE;
346         FN_END;
347 }
348
349 static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
350                                                 const gchar ***folder_list,
351                                                 GError **error)
352 {
353         FN_START;
354         gint size;
355         gint i;
356         gchar **folder;
357
358         size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list);
359         folder = g_new0(gchar *, size);
360
361         for (i = 0; i < size; i++)
362                 folder[i] = g_strdup(bluetooth_pb_agent_folder_list[i]);
363
364         *folder_list = (const gchar **)folder;
365
366         FN_END;
367         return TRUE;
368 }
369
370 static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
371                                         const char *name,
372                                         guint64 filter,
373                                         guint8 format,
374                                         guint16 max_list_count,
375                                         guint16 list_start_offset,
376                                         DBusGMethodInvocation *context)
377 {
378         FN_START;
379         PhoneBookType pb_type = TELECOM_NONE;
380         GPtrArray *vcards = NULL;
381         gchar **vcards_str = NULL;
382
383         INFO("name: %s filter: %lld format: %d max_list_count: %d list_start_offset: %d\n",
384                         name, filter, format, max_list_count, list_start_offset);
385
386         __bluetooth_pb_agent_timeout_add_seconds(agent);
387
388         pb_type = __bluetooth_pb_get_pb_type(name);
389
390         if (pb_type == TELECOM_NONE) {
391                 __bluetooth_pb_dbus_return_error(context,
392                                         G_FILE_ERROR_INVAL,
393                                         "unsupported name defined");
394                 return FALSE;
395         }
396
397         vcards = g_ptr_array_new();
398
399         if (max_list_count > 0) {
400                 __bluetooth_pb_get_vcards(agent, pb_type,
401                                 filter, format,
402                                 max_list_count, list_start_offset,
403                                 vcards);
404
405         }
406
407         g_ptr_array_add(vcards, NULL);
408
409         vcards_str = (gchar **) g_ptr_array_free(vcards, FALSE);
410
411         if (pb_type == TELECOM_MCH) {
412                 dbus_g_method_return(context, vcards_str, unnotified_missed_call_count);
413                 INFO("Notified [%d] missed call count", unnotified_missed_call_count);
414                 unnotified_missed_call_count = 0;
415         } else {
416                 dbus_g_method_return(context, vcards_str, 0);
417         }
418
419         g_strfreev(vcards_str);
420
421         FN_END;
422         return TRUE;
423 }
424
425 static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
426                                                 const char *name,
427                                                 DBusGMethodInvocation *context)
428 {
429         FN_START;
430         PhoneBookType pb_type = TELECOM_NONE;
431         guint count = 0;
432
433         DBG_SECURE("name: %s\n", name);
434
435         __bluetooth_pb_agent_timeout_add_seconds(agent);
436
437         pb_type = __bluetooth_pb_get_pb_type(name);
438
439         if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
440                 __bluetooth_pb_dbus_return_error(context,
441                                         G_FILE_ERROR_INVAL,
442                                         "unsupported name defined");
443                 return FALSE;
444         }
445
446         /* for owner */
447 #ifdef PBAP_SIM_ENABLE
448         if (pb_type == TELECOM_PB || pb_type == SIM_PB)
449                 count++;
450 #else
451         if (pb_type == TELECOM_PB)
452                 count++;
453 #endif
454         if (pb_type == TELECOM_MCH) {
455                 dbus_g_method_return(context, count, unnotified_missed_call_count);
456                 INFO("Notified [%d] missed call count", unnotified_missed_call_count);
457                 unnotified_missed_call_count = 0;
458         } else {
459                 dbus_g_method_return(context, count, 0);
460         }
461
462         FN_END;
463         return TRUE;
464 }
465
466
467 static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
468                                                 const char *name,
469                                                 DBusGMethodInvocation *context)
470 {
471         FN_START;
472         PhoneBookType pb_type = TELECOM_NONE;
473
474         GPtrArray *ptr_array;
475
476         DBG_SECURE("name: %s\n", name);
477
478         __bluetooth_pb_agent_timeout_add_seconds(agent);
479
480         pb_type = __bluetooth_pb_get_pb_type(name);
481
482         if (pb_type == TELECOM_NONE) {
483                 __bluetooth_pb_dbus_return_error(context,
484                                         G_FILE_ERROR_INVAL,
485                                         "unsupported name defined");
486                 return FALSE;
487         }
488
489         ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
490
491         __bluetooth_pb_get_list(agent, pb_type, ptr_array);
492
493 //      __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
494         INFO("pb_type[%d] / number of missed_call[%d]", pb_type, unnotified_missed_call_count);
495
496         if (pb_type == TELECOM_MCH) {
497                 dbus_g_method_return(context, ptr_array, unnotified_missed_call_count);
498                 INFO("Notified [%d] missed call count", unnotified_missed_call_count);
499                 unnotified_missed_call_count = 0;
500         } else {
501                 dbus_g_method_return(context, ptr_array, 0);
502         }
503
504         if (ptr_array)
505                 g_ptr_array_free(ptr_array, TRUE);
506
507         FN_END;
508         return TRUE;
509 }
510
511
512 static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
513                                                 const gchar *folder,
514                                                 const gchar *id,
515                                                 guint64 filter,
516                                                 guint8 format,
517                                                 DBusGMethodInvocation *context)
518 {
519         FN_START;
520         PhoneBookType pb_type = TELECOM_NONE;
521
522         gint handle = 0;
523         gchar *str = NULL;
524
525         const gchar *attr = NULL;
526
527         DBG_SECURE("folder: %s id: %s filter: %ld format: %d\n",
528                         folder, id, filter, format);
529
530         __bluetooth_pb_agent_timeout_add_seconds(agent);
531
532         if (!g_str_has_suffix(id, ".vcf")) {
533                 __bluetooth_pb_dbus_return_error(context,
534                                         G_FILE_ERROR_INVAL,
535                                         "invalid vcf file");
536                 return FALSE;
537         }
538
539         handle = (gint)g_ascii_strtoll(id, NULL, 10);
540
541         pb_type = __bluetooth_pb_get_pb_type(folder);
542
543         if (pb_type == TELECOM_NONE) {
544                 __bluetooth_pb_dbus_return_error(context,
545                                 G_FILE_ERROR_INVAL,
546                                 "unsupported name defined");
547                 return FALSE;
548         }
549
550         /* create index cache */
551         __bluetooth_pb_get_list(agent, pb_type, NULL);
552
553         switch(pb_type) {
554         case TELECOM_PB:
555                 if (handle == 0) {
556                         str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
557                                                                 filter, format);
558                 } else {
559                         if (_bluetooth_get_contact_addressbook(handle) == PBAP_ADDRESSBOOK_PHONE)
560                                 str = _bluetooth_pb_vcard_contact(handle, filter, format);
561                 }
562                 break;
563
564         case TELECOM_ICH:
565                 str = _bluetooth_pb_vcard_call(handle, filter, format, "RECEIVED");
566                 break;
567         case TELECOM_OCH:
568                 str = _bluetooth_pb_vcard_call(handle, filter, format, "DIALED");
569                 break;
570         case TELECOM_MCH:
571                 str = _bluetooth_pb_vcard_call(handle, filter, format, "MISSED");
572                 break;
573         case TELECOM_CCH: {
574                 contacts_record_h record = NULL;
575
576                 gint status;
577
578                 status = contacts_db_get_record(_contacts_phone_log._uri,
579                                 handle, &record);
580
581                 if (status != CONTACTS_ERROR_NONE)
582                         break;
583
584                 attr = __bluetooth_pb_phone_log_get_log_type(record);
585                 str = _bluetooth_pb_vcard_call(handle, filter, format, attr);
586
587                 contacts_record_destroy(record, TRUE);
588                 break;
589         }
590 #ifdef PBAP_SIM_ENABLE
591         case SIM_PB:
592                 if (handle == 0) {
593                         str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
594                                                                 filter, format);
595                 } else {
596                         if (_bluetooth_get_contact_addressbook(handle) == PBAP_ADDRESSBOOK_SIM)
597                                 str = _bluetooth_pb_vcard_contact(handle, filter, format);
598                 }
599                 break;
600 #endif
601         default:
602                 __bluetooth_pb_dbus_return_error(context,
603                                         G_FILE_ERROR_INVAL,
604                                         "unsupported name defined");
605                 return FALSE;
606         }
607
608         dbus_g_method_return(context, str);
609         g_free(str);
610
611         FN_END;
612         return TRUE;
613 }
614
615 static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
616                                         const gchar *command,
617                                         DBusGMethodInvocation *context)
618 {
619         FN_START;
620         PhoneBookType pb_type = TELECOM_NONE;
621         guint count = 0;
622
623         DBG("command: %s\n", command);
624
625         __bluetooth_pb_agent_timeout_add_seconds(agent);
626
627         pb_type = __bluetooth_pb_get_storage_pb_type(command);
628
629         if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
630                 __bluetooth_pb_dbus_return_error(context,
631                                         G_FILE_ERROR_INVAL,
632                                         "unsupported name defined");
633                 return FALSE;
634         }
635
636         dbus_g_method_return(context, count);
637
638         FN_END;
639         return TRUE;
640 }
641
642 static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
643                                         const gchar *command,
644                                         gint start_index,
645                                         gint end_index,
646                                         DBusGMethodInvocation *context)
647 {
648         FN_START;
649         PhoneBookType pb_type = TELECOM_NONE;
650
651         GPtrArray *ptr_array = NULL;
652
653         DBG("command: %s, start_index: %d, end_index: %d\n",
654                         command, start_index, end_index);
655
656         __bluetooth_pb_agent_timeout_add_seconds(agent);
657
658         pb_type = __bluetooth_pb_get_storage_pb_type(command);
659
660         if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
661                 __bluetooth_pb_dbus_return_error(context,
662                                         G_FILE_ERROR_INVAL,
663                                         "unsupported name defined");
664                 return FALSE;
665         }
666
667         ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
668
669         __bluetooth_pb_get_list_number(agent, pb_type,
670                         start_index, end_index,
671                         ptr_array);
672
673         dbus_g_method_return(context, ptr_array);
674
675         if (ptr_array)
676                 g_ptr_array_free(ptr_array, TRUE);
677
678         FN_END;
679         return TRUE;
680 }
681
682 static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *agent,
683                                                         const gchar *command,
684                                                         const gchar *find_text,
685                                                         DBusGMethodInvocation *context)
686 {
687         FN_START;
688         PhoneBookType pb_type = TELECOM_NONE;
689
690         GPtrArray *ptr_array = NULL;
691
692         DBG("command: %s, find text: %s\n", command, find_text);
693
694         __bluetooth_pb_agent_timeout_add_seconds(agent);
695
696         pb_type = __bluetooth_pb_get_storage_pb_type(command);
697
698         if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
699                 __bluetooth_pb_dbus_return_error(context,
700                                         G_FILE_ERROR_INVAL,
701                                         "unsupported name defined");
702                 return FALSE;
703         }
704
705         ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
706
707         __bluetooth_pb_get_list_name(agent, pb_type,
708                         find_text, ptr_array);
709
710         dbus_g_method_return(context, ptr_array);
711
712         if (ptr_array)
713                 g_ptr_array_free(ptr_array, TRUE);
714
715         FN_END;
716         return TRUE;
717 }
718
719 static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
720                                         gchar *path, DBusGMethodInvocation *context)
721 {
722         FN_START;
723         guint count = 0;
724         PhoneBookType pb_type = TELECOM_NONE;
725
726         DBG("%s() %d\n", __FUNCTION__, __LINE__);
727
728         __bluetooth_pb_agent_timeout_add_seconds(agent);
729
730         pb_type = __bluetooth_pb_get_storage_pb_type(path);
731
732         if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
733                 __bluetooth_pb_dbus_return_error(context,
734                                         G_FILE_ERROR_INVAL,
735                                         "unsupported name defined");
736                 return FALSE;
737         }
738
739         dbus_g_method_return(context, count);
740
741         DBG("%s() %d\n", __FUNCTION__, __LINE__);
742
743         FN_END;
744         return TRUE;
745 }
746
747
748 #if 0
749 static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
750 {
751         FN_START;
752         FILE *fp = NULL;
753         int read_len = -1;
754         int received_file_size = 0;
755         struct stat file_attr;
756
757         if (file_path == NULL || stream == NULL) {
758                 ERR("Invalid data \n");
759                 return -1;
760         }
761
762         DBG_SECURE("file_path = %s\n", file_path);
763
764         if ((fp = fopen(file_path, "r+")) == NULL) {
765                 ERR_SECURE("Cannot open %s\n", file_path);
766                 return -1;
767         }
768
769         if (fstat(fileno(fp), &file_attr) == 0) {
770                 received_file_size = file_attr.st_size;
771                 DBG("file_attr.st_size = %d, size = %d\n", file_attr.st_size, received_file_size);
772
773                 if (received_file_size <= 0) {
774                         ERR_SECURE("Some problem in the file size [%s]  \n", file_path);
775                         fclose(fp);
776                         fp = NULL;
777                         return -1;
778                 }
779
780                 *stream = (char *)malloc(sizeof(char) * received_file_size);
781                 if (NULL == *stream) {
782                         fclose(fp);
783                         fp = NULL;
784                         return -1;
785                 }
786         } else {
787                 ERR_SECURE("Some problem in the file [%s]  \n", file_path);
788                 fclose(fp);
789                 fp = NULL;
790                 return -1;
791         }
792
793         read_len = fread(*stream, 1, received_file_size, fp);
794
795         if (read_len == 0) {
796                 if (fp != NULL) {
797                         fclose(fp);
798                         fp = NULL;
799                 }
800                 DBG_SECURE("Cannot open %s\n", file_path);
801                 return -1;
802         }
803
804         if (fp != NULL) {
805                 fclose(fp);
806                 fp = NULL;
807         }
808         FN_END;
809         return 0;
810 }
811 #endif
812
813 static gboolean bluetooth_pb_add_contact(BluetoothPbAgent *agent, const char *filename,
814                                          GError **error)
815 {
816         FN_START;
817         /* Contact API is changed, Temporary blocked */
818 #if 0
819         CTSstruct *contact_record = NULL;
820         GSList *numbers_list = NULL, *cursor;
821         int is_success = 0;
822         int is_duplicated = 0;
823         int err = 0;
824         char *stream = NULL;
825
826         DBG_SECURE("file_path = %s\n", filename);
827
828         err = contacts_svc_connect();
829         ERR("contact_db_service_connect fucntion call [error] = %d \n", err);
830
831         err = __bluetooth_pb_agent_read_file(filename, &stream);
832
833         if (err != 0) {
834                 contacts_svc_disconnect();
835                 ERR("contacts_svc_disconnect fucntion call [error] = %d \n", err);
836
837                 if (NULL != stream) {
838                         free(stream);
839                         stream = NULL;
840                 }
841                 return FALSE;
842         }
843
844         is_success = contacts_svc_get_contact_from_vcard((const void *)stream, &contact_record);
845
846         DBG("contacts_svc_get_contact_from_vcard fucntion call [is_success] = %d \n", is_success);
847
848         if (0 == is_success) {
849                 contacts_svc_struct_get_list(contact_record, CTS_CF_NUMBER_LIST, &numbers_list);
850                 cursor = numbers_list;
851
852                 for (; cursor; cursor = g_slist_next(cursor)) {
853                         if (contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER,
854                                                         contacts_svc_value_get_str(cursor->data,
855                                                                 CTS_NUM_VAL_NUMBER_STR)) > 0) {
856                                 DBG("is_duplicated\n");
857                                 is_duplicated = TRUE;
858                         }
859                 }
860
861                 if (is_duplicated == FALSE) {
862                         contacts_svc_insert_contact(0, contact_record);
863                 }
864         } else {
865                 ERR("Fail \n");
866         }
867
868         err = contacts_svc_disconnect();
869         ERR("contacts_svc_disconnect fucntion call [error] = %d \n", err);
870
871         if (NULL != stream) {
872                 free(stream);
873                 stream = NULL;
874         }
875 #endif
876         FN_END;
877         return TRUE;
878 }
879
880 static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
881                                         gint code,
882                                         const gchar *message)
883 {
884         FN_START;
885         GQuark quark;
886         GError *error = NULL;
887
888         quark = g_type_qname(bluetooth_pb_agent_get_type());
889         error = g_error_new_literal(quark, code, message);
890
891         DBG("%s\n", message);
892
893         dbus_g_method_return_error(context, error);
894         g_error_free(error);
895         FN_END;
896 }
897
898 static PhoneBookType __bluetooth_pb_get_pb_type(const char *name)
899 {
900         FN_START;
901         gchar *suffix = ".vcf";
902         gint len;
903         gint size;
904         gint i;
905
906         if (name == NULL)
907                 return TELECOM_NONE;
908
909         len = strlen(name);
910
911         if (g_str_has_suffix(name, suffix))
912                 len -= strlen(suffix);
913
914         size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list) - 1;
915         for (i = 0; i < size; i++) {
916                 if (strncmp(name, bluetooth_pb_agent_folder_list[i], len) == 0)
917                         return i;
918         }
919
920         FN_END;
921         return TELECOM_NONE;
922 }
923
924 static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
925 {
926         FN_START;
927         if (name == NULL)
928                 return TELECOM_NONE;
929
930         if (g_strcmp0(name, "\"ME\"") == 0 )
931                 return TELECOM_PB;
932
933         if (g_strcmp0(name, "\"RC\"") == 0)
934                 return TELECOM_ICH;
935
936         if (g_strcmp0(name, "\"DC\"") == 0)
937                 return TELECOM_OCH;
938
939         if (g_strcmp0(name, "\"MC\"") == 0)
940                 return TELECOM_MCH;
941
942         FN_END;
943         return TELECOM_NONE;
944 }
945
946 static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
947                                                 gint *match,
948                                                 gint size)
949 {
950         FN_START;
951         gint i;
952         gint status;
953
954         for (i = 0; i < size; i++) {
955
956                 if ( i > 0) {
957                         status = contacts_filter_add_operator(filter,
958                                         CONTACTS_FILTER_OPERATOR_OR);
959
960                         if (status != CONTACTS_ERROR_NONE)
961                                 return status;
962                 }
963
964                 status = contacts_filter_add_int(filter,
965                                 _contacts_phone_log.log_type,
966                                 CONTACTS_MATCH_EQUAL,
967                                 match[i]);
968
969                 if (status != CONTACTS_ERROR_NONE)
970                         return status;
971         }
972
973         FN_END;
974         return CONTACTS_ERROR_NONE;
975 }
976
977 static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
978                                                 gint size)
979 {
980         FN_START;
981         contacts_query_h query = NULL;
982         contacts_filter_h filter = NULL;
983
984         gint status;
985
986         status = contacts_query_create(_contacts_phone_log._uri,
987                                 &query);
988
989         if (status != CONTACTS_ERROR_NONE)
990                 return NULL;
991
992         status = contacts_filter_create(_contacts_phone_log._uri, &filter);
993
994         if (status != CONTACTS_ERROR_NONE) {
995                 contacts_query_destroy(query);
996                 return NULL;
997         }
998
999         status = __bluetooth_pb_phone_log_filter_append(filter, match, size);
1000
1001         if (status != CONTACTS_ERROR_NONE) {
1002                 contacts_filter_destroy(filter);
1003                 contacts_query_destroy(query);
1004                 return NULL;
1005         }
1006
1007         status = contacts_query_set_filter(query, filter);
1008
1009         if (status != CONTACTS_ERROR_NONE) {
1010                 contacts_filter_destroy(filter);
1011                 contacts_query_destroy(query);
1012                 return NULL;
1013         }
1014
1015         status = contacts_query_set_sort(query,
1016                         _contacts_phone_log.log_time,
1017                         false);
1018
1019         if (status != CONTACTS_ERROR_NONE) {
1020                 contacts_filter_destroy(filter);
1021                 contacts_query_destroy(query);
1022                 return NULL;
1023         }
1024
1025         contacts_filter_destroy(filter);
1026
1027         FN_END;
1028         return query;
1029 }
1030
1031 bool __bt_is_matching_addressbook(const char *addressbook_name, int addressbook)
1032 {
1033         bool is_sim_addressbook = _bt_is_sim_addressbook(addressbook_name);
1034
1035         if ((is_sim_addressbook == false
1036                         && addressbook == PBAP_ADDRESSBOOK_PHONE) ||
1037                 (is_sim_addressbook == true
1038                         && addressbook == PBAP_ADDRESSBOOK_SIM))
1039                 return true;
1040
1041         return false;
1042 }
1043
1044 static contacts_query_h __bluetooth_pb_query_person(int addressbook)
1045 {
1046         FN_START;
1047         contacts_query_h query = NULL;
1048         contacts_filter_h filter = NULL;
1049         contacts_list_h recordList = NULL;
1050         contacts_record_h record = NULL;
1051
1052         char* addressbook_name = NULL;
1053         int address_book_id = 0;
1054         int count = 0;
1055         unsigned int i = 0;
1056         gint status;
1057         bool is_first_condition = true;
1058         DBG("Addressbook [%d]", addressbook);
1059         /* Create query*/
1060         status = contacts_query_create(_contacts_person_contact._uri, &query);
1061         if (status != 0) {
1062                 ERR("Could not create query");
1063                 return NULL;
1064         }
1065
1066         /* Create addressbook Filter*/
1067         contacts_db_get_all_records(_contacts_address_book._uri, 0, 0, &recordList);
1068         contacts_filter_create(_contacts_person_contact._uri, &filter);
1069         contacts_list_get_count(recordList, &count);
1070
1071         for (i = 0; i < count; i++) {
1072                 status = contacts_list_get_current_record_p(recordList, &record);
1073                 if (status != CONTACTS_ERROR_NONE) {
1074                         ERR("Contact list get api failed %d", status);
1075                         goto next;
1076                 }
1077                 status = contacts_record_get_str_p(record, _contacts_address_book.name,
1078                                         &addressbook_name);
1079                 if (status != CONTACTS_ERROR_NONE) {
1080                         ERR("Contact record get api failed %d", status);
1081                         goto next;
1082                 }
1083                 status = contacts_record_get_int(record, _contacts_address_book.id,
1084                                         &address_book_id);
1085                 if (status != CONTACTS_ERROR_NONE) {
1086                         ERR("contacts record get int api failed %d", status);
1087                         goto next;
1088                 }
1089
1090                 DBG("Addressbook ID: [%d] Addressbook Name: [%s]",
1091                                 address_book_id, addressbook_name);
1092
1093                 if (__bt_is_matching_addressbook(addressbook_name,
1094                                 addressbook)) {
1095                         if (is_first_condition)
1096                                 is_first_condition = false;
1097                         else
1098                                 contacts_filter_add_operator(filter,
1099                                                 CONTACTS_FILTER_OPERATOR_OR);
1100                         DBG("SELECTED Addressbook ID: [%d] Addressbook Name: [%s]",
1101                                         address_book_id, addressbook_name);
1102                         status = contacts_filter_add_int(filter,
1103                                         _contacts_person_contact.address_book_id,
1104                                         CONTACTS_MATCH_EQUAL, address_book_id);
1105                         if (status != CONTACTS_ERROR_NONE)
1106                                 ERR("Contact filter add failed %d", status);
1107                 }
1108 next:
1109                 if (contacts_list_next(recordList) != CONTACTS_ERROR_NONE)
1110                         break;
1111         }
1112
1113         contacts_list_destroy(recordList, true);
1114
1115         status = contacts_query_set_filter(query, filter);
1116         if (status != CONTACTS_ERROR_NONE)
1117                 ERR("Could not Apply Filter");
1118
1119         contacts_filter_destroy(filter);
1120         FN_END;
1121         return query;
1122 }
1123
1124 static contacts_query_h __bluetooth_pb_query_person_number(void)
1125 {
1126         FN_START;
1127         contacts_query_h query = NULL;
1128
1129         gint status;
1130
1131         status = contacts_query_create(_contacts_person_number._uri,
1132                                 &query);
1133
1134         if (status != CONTACTS_ERROR_NONE)
1135                 return NULL;
1136
1137         FN_END;
1138         return query;
1139 }
1140
1141 static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void)
1142 {
1143         FN_START;
1144         gint size = 4;
1145         gint match[] = {
1146                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
1147                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
1148                 CONTACTS_PLOG_TYPE_VOICE_REJECT,
1149                 CONTACTS_PLOG_TYPE_VIDEO_REJECT
1150         };
1151
1152         FN_END;
1153         return __bluetooth_pb_query_phone_log(match, size);
1154 }
1155
1156 static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void)
1157 {
1158         FN_START;
1159         gint size = 2;
1160         gint match[] = {
1161                 CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
1162                 CONTACTS_PLOG_TYPE_VIDEO_OUTGOING
1163         };
1164
1165         FN_END;
1166         return __bluetooth_pb_query_phone_log(match, size);
1167 }
1168
1169 static contacts_query_h __bluetooth_pb_query_phone_log_missed(void)
1170 {
1171         FN_START;
1172         gint size = 4;
1173         gint match[] = {
1174                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
1175                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
1176                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
1177                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN
1178         };
1179
1180         FN_END;
1181         return __bluetooth_pb_query_phone_log(match, size);
1182 }
1183
1184 static contacts_query_h __bluetooth_pb_query_phone_log_combined(void)
1185 {
1186         FN_START;
1187         gint size = 10;
1188         gint match[] = {
1189                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
1190                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
1191                 CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
1192                 CONTACTS_PLOG_TYPE_VIDEO_OUTGOING,
1193                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
1194                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
1195                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
1196                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN,
1197                 CONTACTS_PLOG_TYPE_VOICE_REJECT,
1198                 CONTACTS_PLOG_TYPE_VIDEO_REJECT
1199         };
1200
1201         FN_END;
1202         return __bluetooth_pb_query_phone_log(match, size);
1203 }
1204
1205 static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
1206                                 guint *count)
1207 {
1208         FN_START;
1209         contacts_query_h query = NULL;
1210
1211         gint status;
1212         gint signed_count;
1213
1214         switch (pb_type) {
1215         case TELECOM_PB:
1216                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1217                 break;
1218         case TELECOM_ICH:
1219                 query = __bluetooth_pb_query_phone_log_incoming();
1220                 break;
1221         case TELECOM_OCH:
1222                 query = __bluetooth_pb_query_phone_log_outgoing();
1223                 break;
1224         case TELECOM_MCH:
1225                 query = __bluetooth_pb_query_phone_log_missed();
1226                 break;
1227         case TELECOM_CCH:
1228                 query = __bluetooth_pb_query_phone_log_combined();
1229                 break;
1230 #ifdef PBAP_SIM_ENABLE
1231         case SIM_PB:
1232                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1233                 break;
1234 #endif
1235         default:
1236                 return FALSE;
1237         }
1238
1239         if (query == NULL)
1240                 return FALSE;
1241
1242         status = contacts_db_get_count_with_query(query, &signed_count);
1243
1244         if (status != CONTACTS_ERROR_NONE) {
1245                 contacts_query_destroy(query);
1246                 return FALSE;
1247         }
1248
1249         contacts_query_destroy(query);
1250
1251         if (signed_count < 0)
1252                 signed_count = 0;
1253
1254         *count = (gint) signed_count;
1255
1256         FN_END;
1257         return TRUE;
1258 }
1259
1260 static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count)
1261 {
1262         FN_START;
1263         contacts_query_h query = NULL;
1264
1265         gint status;
1266         gint signed_count;
1267
1268         gint size = 2;
1269         gint match[] = {
1270                 CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
1271                 CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN
1272         };
1273
1274         query = __bluetooth_pb_query_phone_log(match, size);
1275
1276         if (query == NULL)
1277                 return FALSE;
1278
1279         status = contacts_db_get_count_with_query(query, &signed_count);
1280
1281         if (status != CONTACTS_ERROR_NONE) {
1282                 contacts_query_destroy(query);
1283                 return FALSE;
1284         }
1285
1286         contacts_query_destroy(query);
1287
1288         if (signed_count < 0)
1289                 signed_count = 0;
1290
1291         *count = (guint)signed_count;
1292
1293         FN_END;
1294         return TRUE;
1295 }
1296
1297 static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record)
1298 {
1299         FN_START;
1300         gint status;
1301         gint log_type;
1302
1303         status = contacts_record_get_int(record,
1304                         _contacts_phone_log.log_type,
1305                         &log_type);
1306
1307         if (status != CONTACTS_ERROR_NONE)
1308                 return NULL;
1309
1310         switch (log_type) {
1311         case CONTACTS_PLOG_TYPE_VOICE_INCOMMING:
1312         case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING:
1313         case CONTACTS_PLOG_TYPE_VOICE_REJECT:
1314         case CONTACTS_PLOG_TYPE_VIDEO_REJECT:
1315                 return "RECEIVED";
1316         case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
1317         case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
1318                 return "DIALED";
1319         case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN:
1320         case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN:
1321         case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN:
1322         case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN:
1323                 return "MISSED";
1324         default:
1325                 return NULL;
1326         }
1327         FN_END;
1328 }
1329
1330 static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
1331                                 PhoneBookType pb_type,
1332                                 guint64 filter,
1333                                 guint8 format,
1334                                 guint16 max_list_count,
1335                                 guint16 list_start_offset,
1336                                 GPtrArray *vcards)
1337 {
1338         FN_START;
1339         contacts_list_h record_list = NULL;
1340         contacts_query_h query = NULL;
1341
1342         gint status;
1343
1344         gint limit;
1345         gint offset;
1346
1347         guint property_id = 0;
1348
1349         const char *attr = NULL;
1350
1351         gboolean get_log = FALSE;
1352
1353         /* contact offset is n - 1 of PBAP */
1354         offset = (gint)list_start_offset - 1;
1355
1356         if ( max_list_count >= 65535)
1357                 limit = -1;     /* contact limit -1 means unrestricted */
1358         else
1359                 limit = (gint)max_list_count;
1360
1361         switch (pb_type) {
1362         case TELECOM_PB:
1363 #ifdef PBAP_SIM_ENABLE
1364         case SIM_PB:
1365 #endif
1366                 /* for owner */
1367                 if (list_start_offset == 0) {
1368                         char *vcard;
1369
1370                         vcard = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
1371                                                                 filter, format);
1372                         if (vcard)
1373                                 g_ptr_array_add(vcards, vcard);
1374
1375                         offset = 0;
1376
1377                         if (limit == 1)
1378                                 return;
1379                         else if (limit > 1)
1380                                 limit--;
1381                 }
1382
1383                 if (pb_type == TELECOM_PB)
1384                         query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1385 #ifdef PBAP_SIM_ENABLE
1386                 else if(pb_type == SIM_PB)
1387                         query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1388 #endif
1389
1390                 property_id = _contacts_person.id;
1391                 break;
1392         case TELECOM_ICH:
1393                 query = __bluetooth_pb_query_phone_log_incoming();
1394                 property_id = _contacts_phone_log.id;
1395                 attr = "RECEIVED";
1396                 break;
1397         case TELECOM_OCH:
1398                 query = __bluetooth_pb_query_phone_log_outgoing();
1399                 property_id = _contacts_phone_log.id;
1400                 attr = "DIALED";
1401                 break;
1402         case TELECOM_MCH:
1403                 query = __bluetooth_pb_query_phone_log_missed();
1404                 property_id = _contacts_phone_log.id;
1405                 attr = "MISSED";
1406                 break;
1407         case TELECOM_CCH:
1408                 query = __bluetooth_pb_query_phone_log_combined();
1409                 property_id = _contacts_phone_log.id;
1410                 get_log = TRUE;
1411                 break;
1412         default:
1413                 return;
1414         }
1415         INFO("Limit is = %d and offset is =%d\n", limit, offset);
1416
1417         /* When limit is passed as ZERO to contacts_db_get_records_with_query API
1418          * then this API will provide all available contacts in its database (unrestricted).
1419          * Now consider a case when client requests for maxlistcount of 1 and start offset as 0
1420          * then we have already read the owner card in above switch case and when it reads owner
1421          * card it decrements the limit by 1.
1422          */
1423         if(limit != 0)
1424         {
1425                 status = contacts_db_get_records_with_query(query, offset, limit, &record_list);
1426
1427                 if (status != CONTACTS_ERROR_NONE) {
1428                         contacts_list_destroy(record_list, TRUE);
1429                         contacts_query_destroy(query);
1430                         return;
1431                 }
1432
1433                 status = contacts_list_first(record_list);
1434
1435                 if (status != CONTACTS_ERROR_NONE) {
1436                         contacts_list_destroy(record_list, TRUE);
1437                         contacts_query_destroy(query);
1438                         return;
1439                 }
1440
1441                 do {
1442                         contacts_record_h record;
1443
1444                         gint id;
1445
1446                         gchar *vcard = NULL;
1447
1448                         record = NULL;
1449                         status = contacts_list_get_current_record_p(record_list, &record);
1450
1451                         if (status != CONTACTS_ERROR_NONE)
1452                                 continue;
1453                         id = 0;
1454                         status = contacts_record_get_int(record, property_id, &id);
1455
1456                         if (status != CONTACTS_ERROR_NONE)
1457                                 continue;
1458
1459                         if (property_id == _contacts_person.id)
1460                                 vcard = _bluetooth_pb_vcard_contact(id, filter, format);
1461                         else {
1462                                 if (get_log)
1463                                         attr = __bluetooth_pb_phone_log_get_log_type(record);
1464
1465                                 vcard = _bluetooth_pb_vcard_call(id, filter, format, attr);
1466                         }
1467
1468                         if (vcard)
1469                                 g_ptr_array_add(vcards, vcard);
1470
1471                 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1472                 contacts_list_destroy(record_list, TRUE);
1473         }
1474
1475         contacts_query_destroy(query);
1476
1477         FN_END;
1478 }
1479
1480 static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
1481                                         contacts_query_h query,
1482                                         GPtrArray *ptr_array)
1483 {
1484         FN_START;
1485         contacts_list_h record_list = NULL;
1486
1487         gint status;
1488
1489         /* Add owner */
1490         if (ptr_array) {
1491                 gchar *tmp;
1492                 gchar *name;
1493
1494                 tmp = _bluetooth_pb_owner_name();
1495                 name = g_strdup_printf("%s;;;;", tmp);
1496                 g_free(tmp);
1497
1498                 __bluetooth_pb_list_ptr_array_add(ptr_array,
1499                                 name, agent->tel_number, 0);
1500
1501                 g_free(name);
1502         }
1503
1504         status = contacts_db_get_records_with_query(query,
1505                         -1, -1, &record_list);
1506
1507         if (status != CONTACTS_ERROR_NONE) {
1508                 contacts_list_destroy(record_list, TRUE);
1509                 return;
1510         }
1511
1512         status = contacts_list_first(record_list);
1513
1514         if (status != CONTACTS_ERROR_NONE) {
1515                 contacts_list_destroy(record_list, TRUE);
1516                 return;
1517         }
1518
1519         do {
1520                 contacts_record_h record;
1521
1522                 gint id;
1523
1524                 record = NULL;
1525                 status = contacts_list_get_current_record_p(record_list,
1526                                 &record);
1527
1528                 if (status != CONTACTS_ERROR_NONE)
1529                         continue;
1530
1531                 id = 0;
1532                 status = contacts_record_get_int(record,
1533                                 _contacts_person_contact.person_id,
1534                                 &id);
1535
1536                 if (status != CONTACTS_ERROR_NONE)
1537                         continue;
1538
1539                 /* create list */
1540                 if (ptr_array) {
1541                         gchar *name;
1542                         gchar *number;
1543
1544                         name = _bluetooth_pb_name_from_person_id(id);
1545                         number = _bluetooth_pb_number_from_person_id(id);
1546
1547                         __bluetooth_pb_list_ptr_array_add(ptr_array,
1548                                         name, number, id);
1549
1550                         g_free(name);
1551                         g_free(number);
1552                 }
1553
1554         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1555
1556         contacts_list_destroy(record_list, TRUE);
1557         FN_END;
1558 }
1559
1560 static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
1561                                         contacts_query_h query,
1562                                         GPtrArray *ptr_array)
1563 {
1564         FN_START;
1565         contacts_list_h record_list = NULL;
1566
1567         gint status;
1568
1569         status = contacts_db_get_records_with_query(query,
1570                         -1, -1, &record_list);
1571
1572         if (status != CONTACTS_ERROR_NONE)
1573                 return;
1574
1575         status = contacts_list_first(record_list);
1576
1577         if (status != CONTACTS_ERROR_NONE) {
1578                 contacts_list_destroy(record_list, TRUE);
1579                 return;
1580         }
1581
1582         do {
1583                 contacts_record_h record;
1584
1585                 gint id;
1586
1587                 record = NULL;
1588                 status = contacts_list_get_current_record_p(record_list,
1589                                 &record);
1590
1591                 if (status != CONTACTS_ERROR_NONE)
1592                         continue;
1593
1594                 id = 0;
1595                 status = contacts_record_get_int(record,
1596                                 _contacts_phone_log.id,
1597                                 &id);
1598
1599                 if (status != CONTACTS_ERROR_NONE)
1600                         continue;
1601
1602                 /* create list */
1603                 if (ptr_array) {
1604                         gchar *name;
1605                         gchar *number;
1606
1607                         name = _bluetooth_pb_name_from_phonelog_id(id);
1608
1609                         number = NULL;
1610                         contacts_record_get_str_p(record,
1611                                         _contacts_phone_log.address,
1612                                         &number);
1613
1614                         __bluetooth_pb_list_ptr_array_add(ptr_array,
1615                                         name, number, id);
1616
1617                         g_free(name);
1618                 }
1619
1620         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1621
1622         contacts_list_destroy(record_list, TRUE);
1623         FN_END;
1624 }
1625
1626
1627 static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
1628                                 PhoneBookType pb_type,
1629                                 GPtrArray *ptr_array)
1630 {
1631         FN_START;
1632         contacts_query_h query;
1633
1634         /* no requires refresh cache */
1635         if (ptr_array == NULL && agent->pb_type == pb_type)
1636                 return;
1637
1638         switch (pb_type) {
1639         case TELECOM_PB:
1640                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1641                 __bluetooth_pb_get_contact_list(agent, query, ptr_array);
1642                 break;
1643         case TELECOM_ICH:
1644                 query = __bluetooth_pb_query_phone_log_incoming();
1645                 __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
1646                 break;
1647         case TELECOM_OCH:
1648                 query = __bluetooth_pb_query_phone_log_outgoing();
1649                 __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
1650                 break;
1651         case TELECOM_MCH:
1652                 query = __bluetooth_pb_query_phone_log_missed();
1653                 __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
1654                 break;
1655         case TELECOM_CCH:
1656                 query = __bluetooth_pb_query_phone_log_combined();
1657                 __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
1658                 break;
1659 #ifdef PBAP_SIM_ENABLE
1660         case SIM_PB:
1661                 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1662                 __bluetooth_pb_get_contact_list(agent, query, ptr_array);
1663                 break;
1664 #endif
1665         default:
1666                 return;
1667         }
1668
1669         agent->pb_type = pb_type;
1670
1671         if (query)
1672                 contacts_query_destroy(query);
1673         FN_END;
1674 }
1675
1676 static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
1677                                                 contacts_query_h query,
1678                                                 gint start_index,
1679                                                 gint end_index,
1680                                                 GPtrArray *ptr_array)
1681 {
1682         FN_START;
1683         contacts_list_h record_list = NULL;
1684         gint status;
1685         gint i;
1686         gint from;
1687         gint to;
1688         gint offset;
1689
1690         from = start_index;
1691         to = end_index;
1692
1693         if (from < 1)
1694                 from = 1;
1695
1696         if (to < 1)
1697                 to = 1;
1698
1699         offset = to - from + 1;
1700         if (offset <= 0)
1701                 return;
1702
1703         i = from;
1704
1705         status = contacts_db_get_records_with_query(query,
1706                         from - 1 , offset,
1707                         &record_list);
1708
1709         if (status != CONTACTS_ERROR_NONE) {
1710                 contacts_list_destroy(record_list, TRUE);
1711                 return;
1712         }
1713
1714         status = contacts_list_first(record_list);
1715
1716         if (status != CONTACTS_ERROR_NONE) {
1717                 contacts_list_destroy(record_list, TRUE);
1718                 return;
1719         }
1720
1721         do {
1722                 contacts_record_h record;
1723
1724                 gchar *display_name;
1725                 gchar *number;
1726
1727                 record = NULL;
1728                 status = contacts_list_get_current_record_p(record_list,
1729                                 &record);
1730
1731                 if (status != CONTACTS_ERROR_NONE)
1732                         continue;
1733
1734                 display_name = NULL;
1735                 number = NULL;
1736
1737                 contacts_record_get_str_p(record,
1738                                 _contacts_person_number.display_name,
1739                                 &display_name);
1740                 contacts_record_get_str_p(record,
1741                                 _contacts_person_number.number,
1742                                 &number);
1743
1744                 __bluetooth_pb_list_ptr_array_add(ptr_array,
1745                                 display_name, number, i);
1746
1747                 i++;
1748         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1749
1750         contacts_list_destroy(record_list, TRUE);
1751         FN_END;
1752 }
1753
1754 static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
1755                                                 contacts_query_h query,
1756                                                 gint start_index,
1757                                                 gint end_index,
1758                                                 GPtrArray *ptr_array)
1759 {
1760         FN_START;
1761         contacts_list_h record_list = NULL;
1762
1763         gint status;
1764
1765         gint i;
1766
1767         gint from;
1768         gint to;
1769         gint offset;
1770
1771         from = start_index;
1772         to = end_index;
1773
1774         if (from < 1)
1775                 from = 1;
1776
1777         if (to < 1)
1778                 to = 1;
1779
1780         offset = to - from + 1;
1781         if (offset <= 0)
1782                 return;
1783
1784         i = from;
1785
1786         status = contacts_db_get_records_with_query(query,
1787                         from - 1 , offset,
1788                         &record_list);
1789
1790         if (status != CONTACTS_ERROR_NONE) {
1791                 contacts_list_destroy(record_list, TRUE);
1792                 return;
1793         }
1794
1795         status = contacts_list_first(record_list);
1796         if (status != CONTACTS_ERROR_NONE) {
1797                 contacts_list_destroy(record_list, TRUE);
1798                 return;
1799         }
1800
1801         do {
1802                 contacts_record_h record = NULL;
1803
1804                 gint id;
1805
1806                 gchar *display_name;
1807                 gchar *number;
1808
1809                 record = NULL;
1810                 status = contacts_list_get_current_record_p(record_list,
1811                                 &record);
1812
1813                 if (status != CONTACTS_ERROR_NONE)
1814                         continue;
1815
1816                 id = 0;
1817                 status = contacts_record_get_int(record,
1818                                 _contacts_phone_log.id,
1819                                 &id);
1820                 if (status != CONTACTS_ERROR_NONE) {
1821                         ERR("contact_record_get_int api failed %d", status);
1822                         continue;
1823                 }
1824
1825                 display_name = _bluetooth_pb_fn_from_phonelog_id(id);
1826
1827                 number = NULL;
1828                 contacts_record_get_str_p(record,
1829                                 _contacts_phone_log.address,
1830                                 &number);
1831
1832
1833                 __bluetooth_pb_list_ptr_array_add(ptr_array,
1834                                 display_name, number, i);
1835
1836                 i++;
1837
1838                 g_free(display_name);
1839
1840         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1841
1842         contacts_list_destroy(record_list, TRUE);
1843         FN_END;
1844 }
1845
1846 static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
1847                                                 PhoneBookType pb_type,
1848                                                 gint start_index,
1849                                                 gint end_index,
1850                                                 GPtrArray *ptr_array)
1851 {
1852         FN_START;
1853         contacts_query_h query;
1854
1855         switch (pb_type) {
1856         case TELECOM_PB:
1857                 query = __bluetooth_pb_query_person_number();
1858                 __bluetooth_pb_get_contact_list_number(agent, query,
1859                                 start_index, end_index, ptr_array);
1860                 break;
1861         case TELECOM_ICH:
1862                 query = __bluetooth_pb_query_phone_log_incoming();
1863                 __bluetooth_pb_get_phone_log_list_number(agent, query,
1864                                 start_index, end_index, ptr_array);
1865                 break;
1866         case TELECOM_OCH:
1867                 query = __bluetooth_pb_query_phone_log_outgoing();
1868                 __bluetooth_pb_get_phone_log_list_number(agent, query,
1869                                 start_index, end_index, ptr_array);
1870                 break;
1871         case TELECOM_MCH:
1872                 query = __bluetooth_pb_query_phone_log_missed();
1873                 __bluetooth_pb_get_phone_log_list_number(agent, query,
1874                                 start_index, end_index, ptr_array);
1875                 break;
1876         case TELECOM_CCH:
1877                 query = __bluetooth_pb_query_phone_log_combined();
1878                 __bluetooth_pb_get_phone_log_list_number(agent, query,
1879                                 start_index, end_index, ptr_array);
1880                 break;
1881         default:
1882                 return;
1883         }
1884
1885         if (query)
1886                 contacts_query_destroy(query);
1887         FN_END;
1888 }
1889
1890 static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
1891                                                 contacts_query_h query,
1892                                                 const gchar *find_text,
1893                                                 GPtrArray *ptr_array)
1894 {
1895         FN_START;
1896         contacts_list_h record_list = NULL;
1897
1898         gint status;
1899         gint i = 1;
1900
1901         status = contacts_db_get_records_with_query(query,
1902                         -1, -1, &record_list);
1903
1904         if (status != CONTACTS_ERROR_NONE) {
1905                 contacts_list_destroy(record_list, TRUE);
1906                 return;
1907         }
1908
1909         status = contacts_list_first(record_list);
1910
1911         if (status != CONTACTS_ERROR_NONE) {
1912                 contacts_list_destroy(record_list, TRUE);
1913                 return;
1914         }
1915
1916         do {
1917                 contacts_record_h record;
1918
1919                 gchar *display_name;
1920
1921                 record = NULL;
1922                 status = contacts_list_get_current_record_p(record_list,
1923                                 &record);
1924
1925                 if (status != CONTACTS_ERROR_NONE)
1926                         continue;
1927
1928                 display_name = NULL;
1929                 contacts_record_get_str_p(record,
1930                                 _contacts_person_number.display_name,
1931                                 &display_name);
1932
1933                 if (g_str_has_prefix(display_name, find_text)) {
1934                         gchar *number;
1935
1936                         number = NULL;
1937                         contacts_record_get_str_p(record,
1938                                         _contacts_person_number.number,
1939                                         &number);
1940
1941                         __bluetooth_pb_list_ptr_array_add(ptr_array,
1942                                         display_name, number, i);
1943                 }
1944
1945                 i++;
1946         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1947         contacts_list_destroy(record_list, TRUE);
1948         FN_END;
1949 }
1950
1951 static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
1952                                                 contacts_query_h query,
1953                                                 const gchar *find_text,
1954                                                 GPtrArray *ptr_array)
1955 {
1956         FN_START;
1957         contacts_list_h record_list = NULL;
1958
1959         gint status;
1960
1961         gint i = 1;
1962
1963         status = contacts_db_get_records_with_query(query,
1964                         -1, -1,
1965                         &record_list);
1966
1967         if (status != CONTACTS_ERROR_NONE) {
1968                 contacts_list_destroy(record_list, TRUE);
1969                 return;
1970         }
1971
1972         status = contacts_list_first(record_list);
1973
1974         if (status != CONTACTS_ERROR_NONE) {
1975                 contacts_list_destroy(record_list, TRUE);
1976                 return;
1977         }
1978
1979         do {
1980                 contacts_record_h record = NULL;
1981
1982                 gint id;
1983
1984                 gchar *display_name;
1985
1986                 record = NULL;
1987                 status = contacts_list_get_current_record_p(record_list,
1988                                 &record);
1989
1990                 if (status != CONTACTS_ERROR_NONE)
1991                         continue;
1992
1993                 id = 0;
1994                 status = contacts_record_get_int(record,
1995                                 _contacts_phone_log.id,
1996                                 &id);
1997                 if (status != CONTACTS_ERROR_NONE) {
1998                         ERR("contacts_record_get_int failed %d", status);
1999                         continue;
2000                 }
2001
2002                 display_name = _bluetooth_pb_fn_from_phonelog_id(id);
2003
2004                 if (g_str_has_prefix(display_name, find_text)) {
2005                         gchar *number = NULL;
2006
2007                         number = NULL;
2008                         contacts_record_get_str_p(record,
2009                                         _contacts_phone_log.address,
2010                                         &number);
2011
2012                         __bluetooth_pb_list_ptr_array_add(ptr_array,
2013                                         display_name, number, i);
2014                 }
2015
2016                 i++;
2017
2018                 g_free(display_name);
2019
2020         } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
2021
2022         contacts_list_destroy(record_list, TRUE);
2023         FN_END;
2024 }
2025
2026 static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
2027                                         PhoneBookType pb_type,
2028                                         const gchar *find_text,
2029                                         GPtrArray *ptr_array)
2030 {
2031         FN_START;
2032         contacts_query_h query;
2033
2034         switch (pb_type) {
2035         case TELECOM_PB:
2036                 query = __bluetooth_pb_query_person_number();
2037                 __bluetooth_pb_get_contact_list_name(agent, query,
2038                                 find_text, ptr_array);
2039                 break;
2040         case TELECOM_ICH:
2041                 query = __bluetooth_pb_query_phone_log_incoming();
2042                 __bluetooth_pb_get_phone_log_list_name(agent, query,
2043                                 find_text, ptr_array);
2044                 break;
2045         case TELECOM_OCH:
2046                 query = __bluetooth_pb_query_phone_log_outgoing();
2047                 __bluetooth_pb_get_phone_log_list_name(agent, query,
2048                                 find_text, ptr_array);
2049                 break;
2050         case TELECOM_MCH:
2051                 query = __bluetooth_pb_query_phone_log_missed();
2052                 __bluetooth_pb_get_phone_log_list_name(agent, query,
2053                                 find_text, ptr_array);
2054                 break;
2055         case TELECOM_CCH:
2056                 query = __bluetooth_pb_query_phone_log_combined();
2057                 __bluetooth_pb_get_phone_log_list_name(agent, query,
2058                                 find_text, ptr_array);
2059                 break;
2060         default:
2061                 return;
2062         }
2063
2064         if (query)
2065                 contacts_query_destroy(query);
2066         FN_END;
2067 }
2068
2069 static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
2070                                                 const gchar *name,
2071                                                 const gchar *number,
2072                                                 gint handle)
2073 {
2074         FN_START;
2075         GValue value = { 0, };
2076         gchar *temp_name = g_strdup(name);
2077         gchar *temp_number = g_strdup(number);
2078
2079         g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
2080         g_value_take_boxed(&value,
2081                         dbus_g_type_specialized_construct(DBUS_STRUCT_STRING_STRING_UINT));
2082
2083         dbus_g_type_struct_set(&value,
2084                                 0, temp_name,
2085                                 1, temp_number,
2086                                 2, handle,
2087                                 G_MAXUINT);
2088
2089         g_ptr_array_add(ptr_array, g_value_get_boxed(&value));
2090         g_free(temp_name);
2091         g_free(temp_number)
2092         FN_END;
2093 }
2094
2095 static void __bluetooth_pb_list_ptr_array_free(gpointer data)
2096 {
2097         FN_START;
2098         GValue value = { 0, };
2099
2100         gchar *name = NULL;
2101         gchar *number = NULL;
2102
2103         if(data == NULL)
2104                 return;
2105
2106         g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
2107         g_value_set_boxed(&value, data);
2108
2109         dbus_g_type_struct_get(&value,
2110                         0, &name,
2111                         1, &number,
2112                         G_MAXUINT);
2113
2114         g_free(name);
2115         g_free(number);
2116         FN_END;
2117 }
2118
2119 static void __bluetooth_pb_agent_signal_handler(int signum)
2120 {
2121         FN_START;
2122         if (mainloop) {
2123                 g_main_loop_quit(mainloop);
2124         } else {
2125                 DBG("Terminate Bluetooth PBAP agent");
2126                 exit(0);
2127         }
2128 }
2129
2130
2131 static void __bluetooth_pb_contact_changed(const gchar *view_uri,
2132                                         void *user_data)
2133 {
2134         FN_START;
2135         BluetoothPbAgent *agent;
2136         guint new_missed_call;
2137
2138         DBG("Received contact changed cb");
2139         g_return_if_fail(BLUETOOTH_IS_PB_AGENT(user_data));
2140         agent = BLUETOOTH_PB_AGENT(user_data);
2141
2142         g_object_ref(agent);
2143         g_signal_emit(agent, signals[CLEAR], 0);
2144         g_object_unref(agent);
2145
2146         __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
2147
2148         if (new_missed_call > total_missed_call_count)
2149                 unnotified_missed_call_count += new_missed_call - total_missed_call_count;
2150
2151         INFO("Missed call count : #prev[%d], #current[%d], #unnotified[%d]",
2152                 total_missed_call_count, new_missed_call, unnotified_missed_call_count);
2153
2154         total_missed_call_count = new_missed_call;
2155         FN_END;
2156 }
2157
2158 static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent)
2159 {
2160         FN_START;
2161         g_return_if_fail(BLUETOOTH_IS_PB_AGENT(agent));
2162
2163         if(agent->timeout_id)
2164                 g_source_remove(agent->timeout_id);
2165
2166         agent->timeout_id = g_timeout_add_seconds(BLUETOOTH_PB_AGENT_TIMEOUT,
2167                                 __bluetooth_pb_agent_timeout_calback,
2168                                 agent);
2169         FN_END;
2170 }
2171
2172 static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data)
2173 {
2174         FN_START;
2175         BluetoothPbAgent *agent;
2176
2177         g_return_val_if_fail(BLUETOOTH_IS_PB_AGENT(user_data), FALSE);
2178
2179         agent = BLUETOOTH_PB_AGENT(user_data);
2180         agent->timeout_id = 0;
2181
2182         if (mainloop)
2183                 g_main_loop_quit(mainloop);
2184
2185         FN_END;
2186         return FALSE;
2187 }
2188
2189 static void __bluetooth_pb_tel_callback(TapiHandle *handle,
2190                                         int result,
2191                                         void *data,
2192                                         void *user_data)
2193 {
2194         FN_START;
2195         BluetoothPbAgent *agent;
2196         TelSimMsisdnList_t *number;
2197
2198         g_return_if_fail(BLUETOOTH_IS_PB_AGENT(user_data));
2199
2200         agent = BLUETOOTH_PB_AGENT(user_data);
2201
2202         __bluetooth_pb_agent_dbus_init(agent);
2203
2204         if (data != NULL) {
2205                 number = (TelSimMsisdnList_t *)data;
2206                 agent->tel_number = g_strdup(number->list[0].num);
2207         }
2208
2209         tel_deinit(agent->tapi_handle);
2210         agent->tapi_handle = NULL;
2211         FN_END;
2212 }
2213
2214 static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
2215 {
2216         FN_START;
2217         guint result = 0;
2218         GError *error = NULL;
2219
2220         agent->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
2221
2222         if (error != NULL) {
2223                 ERR("Couldn't connect to system bus[%s]\n", error->message);
2224                 g_error_free(error);
2225                 return;
2226         }
2227
2228         agent->proxy = dbus_g_proxy_new_for_name(agent->bus,
2229                         DBUS_SERVICE_DBUS,
2230                         DBUS_PATH_DBUS,
2231                         DBUS_INTERFACE_DBUS);
2232
2233         if (agent->proxy == NULL) {
2234                 ERR("Failed to get a proxy for D-Bus\n");
2235                 return;
2236         }
2237
2238         if (!dbus_g_proxy_call(agent->proxy,
2239                                 "RequestName", &error,
2240                                 G_TYPE_STRING, BT_PB_SERVICE_NAME,
2241                                 G_TYPE_UINT, 0,
2242                                 G_TYPE_INVALID,
2243                                 G_TYPE_UINT, &result,
2244                                 G_TYPE_INVALID)) {
2245                 if (error != NULL) {
2246                         ERR("RequestName RPC failed[%s]\n", error->message);
2247                         g_error_free(error);
2248                 }
2249
2250                 g_object_unref(agent->proxy);
2251                 agent->proxy = NULL;
2252
2253                 return;
2254         }
2255         DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
2256         if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
2257                 ERR("Failed to get the primary well-known name.\n");
2258
2259                 g_object_unref(agent->proxy);
2260                 agent->proxy = NULL;
2261
2262                 return;
2263         }
2264
2265         g_object_unref(agent->proxy);
2266         agent->proxy = NULL;
2267
2268         dbus_g_connection_register_g_object(agent->bus,
2269                         BT_PB_SERVICE_OBJECT_PATH,
2270                         G_OBJECT(agent));
2271         FN_END;
2272 }
2273
2274 static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
2275                                         DBusGMethodInvocation *context)
2276 {
2277         FN_START;
2278         g_main_loop_quit(mainloop);
2279         FN_END;
2280         return TRUE;
2281 }
2282
2283 int main(void)
2284 {
2285         FN_START;
2286         BluetoothPbAgent *agent;
2287
2288         gint ret = EXIT_SUCCESS;
2289         gint tapi_result;
2290
2291         struct sigaction sa;
2292         DBG("Starting Bluetooth PBAP agent");
2293
2294         g_type_init();
2295
2296         mainloop = g_main_loop_new(NULL, FALSE);
2297         if (mainloop == NULL) {
2298                 ERR("Couldn't create GMainLoop\n");
2299                 return EXIT_FAILURE;
2300         }
2301
2302         agent = g_object_new(BLUETOOTH_PB_TYPE_AGENT, NULL);
2303
2304         /* connect contact */
2305         if (contacts_connect() != CONTACTS_ERROR_NONE) {
2306                 ERR("Can not connect contacts server\n");
2307                 g_object_unref(agent);
2308                 return EXIT_FAILURE;
2309         }
2310
2311         __bluetooth_pb_get_count_new_missed_call(&total_missed_call_count);
2312
2313         if (contacts_db_add_changed_cb(_contacts_contact._uri,
2314                         __bluetooth_pb_contact_changed,
2315                         (void *)agent) != CONTACTS_ERROR_NONE) {
2316                 ERR("Can not add changed callback");
2317         }
2318
2319         if (contacts_db_add_changed_cb(_contacts_phone_log._uri,
2320                         __bluetooth_pb_contact_changed,
2321                         (void *)agent) != CONTACTS_ERROR_NONE) {
2322                 ERR("Can not add changed callback");
2323         }
2324
2325         /* set signal */
2326         memset(&sa, 0, sizeof(sa));
2327         sa.sa_handler = __bluetooth_pb_agent_signal_handler;
2328         sigaction(SIGTERM, &sa, NULL);
2329         sigaction(SIGINT, &sa, NULL);
2330
2331         /* init tapi */
2332         agent->tapi_handle = tel_init(NULL);
2333         tapi_result = tel_get_sim_msisdn(agent->tapi_handle,
2334                         __bluetooth_pb_tel_callback, agent);
2335
2336         if (tapi_result != TAPI_API_SUCCESS) {
2337                 __bluetooth_pb_agent_dbus_init(agent);
2338         }
2339
2340
2341         __bluetooth_pb_agent_timeout_add_seconds(agent);
2342
2343         g_main_loop_run(mainloop);
2344
2345         if (contacts_db_remove_changed_cb(_contacts_phone_log._uri,
2346                         __bluetooth_pb_contact_changed,
2347                         (void *)agent) != CONTACTS_ERROR_NONE) {
2348                 ERR("Cannot remove changed callback");
2349         }
2350
2351         if (contacts_db_remove_changed_cb(_contacts_contact._uri,
2352                         __bluetooth_pb_contact_changed,
2353                         (void *)agent) != CONTACTS_ERROR_NONE) {
2354                 ERR("Cannot remove changed callback");
2355         }
2356
2357         if (contacts_disconnect() != CONTACTS_ERROR_NONE)
2358                 ERR("contacts_disconnect failed \n");
2359
2360         g_signal_emit(agent, signals[CLEAR], 0);
2361
2362         g_object_unref(agent);
2363
2364         DBG("Terminate Bluetooth PBAP agent");
2365         FN_END;
2366         return ret;
2367 }