4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
9 * Jaekyun Lee <jkyun.leek@samsung.com>
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
32 #include <sys/types.h>
36 #include <TapiUtility.h>
39 #include "bluetooth_pb_agent.h"
40 #include "bluetooth_pb_vcard.h"
42 #define BLUETOOTH_PB_AGENT_TIMEOUT 600
45 TapiHandle *tapi_handle;
48 PhoneBookType pb_type;
49 guint pbagent_interface_id;
50 guint pbagent_at_interface_id;
53 static gchar *bluetooth_pb_agent_folder_list[] = {
59 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
65 static guint total_missed_call_count = 0;
66 static guint unnotified_missed_call_count = 0;
68 GMainLoop *g_mainloop;
69 static GDBusConnection *pb_dbus_conn = NULL;
71 static const gchar pb_agent_introspection_xml[] =
73 "<interface name='org.bluez.PbAgent'>"
74 "<method name='GetPhonebookFolderList'>"
75 "<arg type='as' name='folder_list' direction='out'/>"
78 "<method name='GetPhonebook'>"
79 "<arg type='s' name='name'/>"
80 "<arg type='t' name='filter'/>"
81 "<arg type='y' name='format'/>"
82 "<arg type='q' name='max_list_count'/>"
83 "<arg type='q' name='list_start_offset'/>"
84 "<arg type='as' name='phonebook' direction='out'/>"
85 "<arg type='u' name='new_missed_call' direction='out'/>"
88 "<method name='GetPhonebookSize'>"
89 "<arg type='s' name='name'/>"
90 "<arg type='u' name='phonebook_size' direction='out'/>"
91 "<arg type='u' name='new_missed_call' direction='out'/>"
94 "<method name='GetPhonebookList'>"
95 "<arg type='s' name='name'/>"
96 "<arg type='a(ssu)' name='phonebook_list' direction='out'/>"
97 "<arg type='u' name='new_missed_call' direction='out'/>"
100 "<method name='GetPhonebookEntry'>"
101 "<arg type='s' name='folder'/>"
102 "<arg type='s' name='id'/>"
103 "<arg type='t' name='filter'/>"
104 "<arg type='y' name='format'/>"
105 "<arg type='s' name='phonebook_entry' direction='out'/>"
108 "<method name='GetTotalObjectCount'>"
109 "<arg type='s' name='path'/>"
110 "<arg type='u' name='phonebook_size' direction='out'/>"
113 "<method name='AddContact'>"
114 "<arg type='s' name='filename'/>"
117 "<method name='DestroyAgent'>"
121 "<interface name='org.bluez.PbAgent.At'>"
122 "<method name='GetPhonebookSizeAt'>"
123 "<arg type='s' name='command'/>"
124 "<arg type='u' name='phonebook_size' direction='out'/>"
127 "<method name='GetPhonebookEntriesAt'>"
128 "<arg type='s' name='command'/>"
129 "<arg type='i' name='start_index'/>"
130 "<arg type='i' name='end_index'/>"
131 "<arg type='a(ssu)' name='phonebook_entries' direction='out'/>"
134 "<method name='GetPhonebookEntriesFindAt'>"
135 "<arg type='s' name='command'/>"
136 "<arg type='s' name='find_text' />"
137 "<arg type='a(ssu)' name='phonebook_entries' direction='out'/>"
142 static void __bt_pb_agent_method(GDBusConnection *connection,
143 const gchar *sender, const gchar *object_path,
144 const gchar *interface_name, const gchar *method_name,
145 GVariant *parameters, GDBusMethodInvocation *invocation,
148 static GVariant *__bt_pb_get_phonebook_folder_list(GError **error);
150 static GVariant *__bt_pb_get_phonebook(PbAgentData *agent, const char *name,
151 guint64 filter, guint8 format, guint16 max_list_count,
152 guint16 list_start_offset, GError **err);
154 static GVariant *__bt_pb_get_phonebook_size(PbAgentData *agent,
155 const char *name, GError **err);
157 static GVariant *__bt_pb_get_phonebook_list(PbAgentData *agent,
158 const char *name, GError **err);
160 static GVariant *__bt_pb_get_phonebook_entry(PbAgentData *agent,
161 const gchar *folder, const gchar *id, guint64 filter,
162 guint8 format, GError **err);
164 static GVariant *__bt_pb_get_phonebook_size_at(PbAgentData *agent,
165 const gchar *command, GError **err);
167 static GVariant *__bt_pb_get_phonebook_entries_at(PbAgentData *agent,
168 const gchar *command, gint32 start_index,
169 gint32 end_index, GError **err);
171 static GVariant *__bt_pb_get_phonebook_entries_find_at(PbAgentData *agent,
172 const gchar *command, const gchar *find_text,
175 static GVariant *__bt_pb_get_total_object_count(PbAgentData *agent,
176 gchar *path, GError **err);
178 static gboolean __bt_pb_add_contact(PbAgentData *agent, const char *filename,
181 static gboolean __bt_pb_destroy_agent();
183 static GError *__bt_pb_error(gint error_code, const gchar *error_message);
185 static PhoneBookType __bluetooth_pb_get_pb_type(const char *name);
187 static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name);
189 static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
190 gint *match, gint size);
192 static contacts_query_h __bluetooth_pb_query_phone_log(gint *match, gint size);
194 static contacts_query_h __bluetooth_pb_query_person(int addressbook);
196 static contacts_query_h __bluetooth_pb_query_person_number(void);
198 static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void);
200 static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void);
202 static contacts_query_h __bluetooth_pb_query_phone_log_missed(void);
204 static contacts_query_h __bluetooth_pb_query_phone_log_combined(void);
206 static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type, guint *count);
208 static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count);
210 static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record);
212 static void __bluetooth_pb_get_vcards(PbAgentData *agent, PhoneBookType pb_type,
213 guint64 filter, guint8 format, guint16 max_list_count,
214 guint16 list_start_offset, GVariantBuilder *vcards);
216 static void __bluetooth_pb_get_contact_list(PbAgentData *agent,
217 contacts_query_h query, GVariantBuilder *builder);
219 static void __bluetooth_pb_get_phone_log_list(PbAgentData *agent,
220 contacts_query_h query, GVariantBuilder *builder);
222 static void __bluetooth_pb_get_list(PbAgentData *agent, PhoneBookType pb_type,
223 GVariantBuilder *builder);
225 static void __bluetooth_pb_get_contact_list_number(PbAgentData *agent,
226 contacts_query_h query, gint start_index,
227 gint end_index, GVariantBuilder *builder);
229 static void __bluetooth_pb_get_phone_log_list_number(PbAgentData *agent,
230 contacts_query_h query, gint start_index,
231 gint end_index, GVariantBuilder *builder);
233 static void __bluetooth_pb_get_list_number(PbAgentData *agent,
234 PhoneBookType pb_type, gint start_index,
235 gint end_index, GVariantBuilder *builder);
237 static void __bluetooth_pb_get_contact_list_name(PbAgentData *agent,
238 contacts_query_h query, const gchar *find_text,
239 GVariantBuilder *builder);
241 static void __bluetooth_pb_get_phone_log_list_name(PbAgentData *agent,
242 contacts_query_h query, const gchar *find_text,
243 GVariantBuilder *builder);
245 static void __bluetooth_pb_get_list_name(PbAgentData *agent,
246 PhoneBookType pb_type, const gchar *find_text,
247 GVariantBuilder *builder);
249 static void __bluetooth_pb_list_ptr_array_add(GVariantBuilder *builder,
250 const gchar *name, const gchar *number, gint handle);
252 static void __bluetooth_pb_agent_signal_handler(int signum);
254 static void __bluetooth_pb_contact_changed(const gchar *view_uri,
257 static void __bluetooth_pb_agent_timeout_add_seconds(PbAgentData *agent);
259 static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data);
261 static void __bluetooth_pb_tel_callback(TapiHandle *handle, int result,
262 void *data, void *user_data);
264 static gboolean __bt_pb_dbus_init(PbAgentData *agent);
266 static gboolean __bt_pb_dbus_deinit(PbAgentData *agent);
268 static const GDBusInterfaceVTable method_table = {
269 __bt_pb_agent_method,
274 static void __bt_pb_agent_method(GDBusConnection *connection,
275 const gchar *sender, const gchar *object_path,
276 const gchar *interface_name, const gchar *method_name,
277 GVariant *parameters, GDBusMethodInvocation *invocation,
281 INFO("method: %s; object_path: %s", method_name, object_path);
282 PbAgentData *agent = (PbAgentData *)user_data;
284 if (g_strcmp0(interface_name, "org.bluez.PbAgent") == 0) {
285 if (g_strcmp0(method_name, "GetPhonebookFolderList") == 0) {
286 GVariant *folder_list = NULL;
288 folder_list = __bt_pb_get_phonebook_folder_list(&err);
291 g_dbus_method_invocation_return_value(invocation,
293 } else if (g_strcmp0(method_name, "GetPhonebook") == 0) {
294 GVariant *phonebook = NULL;
298 guint16 max_list_count;
299 guint16 list_start_offset;
301 g_variant_get(parameters, "(&styqq)", &name, &filter,
302 &format, &max_list_count,
304 phonebook = __bt_pb_get_phonebook(agent, name, filter,
305 format, max_list_count,
306 list_start_offset, &err);
309 g_dbus_method_invocation_return_value(invocation,
311 } else if (g_strcmp0(method_name, "GetPhonebookSize") == 0) {
312 GVariant *phonebook_size = NULL;
315 g_variant_get(parameters, "(&s)", &name);
316 phonebook_size = __bt_pb_get_phonebook_size(agent, name,
320 g_dbus_method_invocation_return_value(invocation,
322 } else if (g_strcmp0(method_name, "GetPhonebookList") == 0) {
323 GVariant *phonebook_list = NULL;
326 g_variant_get(parameters, "(&s)", &name);
327 phonebook_list = __bt_pb_get_phonebook_list(agent, name,
331 g_dbus_method_invocation_return_value(invocation,
333 } else if (g_strcmp0(method_name, "GetPhonebookEntry") == 0) {
334 GVariant *phonebook_entry = NULL;
340 g_variant_get(parameters, "(&s&sty)", &folder, &id,
342 phonebook_entry = __bt_pb_get_phonebook_entry(agent,
343 folder, id, filter, format, &err);
346 g_dbus_method_invocation_return_value(invocation,
348 } else if (g_strcmp0(method_name, "GetTotalObjectCount") == 0) {
349 GVariant *phonebook_size = NULL;
352 g_variant_get(parameters, "(&s)", &path);
353 phonebook_size = __bt_pb_get_total_object_count(agent,
357 g_dbus_method_invocation_return_value(invocation,
359 } else if (g_strcmp0(method_name, "AddContact") == 0) {
360 const char *filename;
362 g_variant_get(parameters, "(&s)", &filename);
363 __bt_pb_add_contact(agent, filename, &err);
366 g_dbus_method_invocation_return_value(invocation, NULL);
367 } else if (g_strcmp0(method_name, "DestroyAgent") == 0) {
368 g_dbus_method_invocation_return_value(invocation, NULL);
369 __bt_pb_destroy_agent();
371 } else if (g_strcmp0(interface_name, "org.bluez.PbAgent.At") == 0) {
372 if (g_strcmp0(method_name, "GetPhonebookSizeAt") == 0) {
373 GVariant *phonebook_size = NULL;
374 const gchar *command;
376 g_variant_get(parameters, "(&s)", &command);
377 phonebook_size = __bt_pb_get_phonebook_size_at(agent,
381 g_dbus_method_invocation_return_value(invocation,
383 } else if (g_strcmp0(method_name,
384 "GetPhonebookEntriesAt") == 0) {
385 GVariant *phonebook_entries = NULL;
386 const gchar *command;
390 g_variant_get(parameters, "(&sii)",
391 &command, &start_index, &end_index);
392 phonebook_entries = __bt_pb_get_phonebook_entries_at(agent,
393 command, start_index,
397 g_dbus_method_invocation_return_value(invocation,
399 } else if (g_strcmp0(method_name,
400 "GetPhonebookEntriesFindAt") == 0) {
401 GVariant *phonebook_entries = NULL;
402 const gchar *command;
403 const gchar *find_text;
405 g_variant_get(parameters, "(&s&s)", &command, &find_text);
406 phonebook_entries = __bt_pb_get_phonebook_entries_find_at(agent,
407 command, find_text, &err);
410 g_dbus_method_invocation_return_value(invocation,
419 g_dbus_method_invocation_return_gerror(invocation, err);
425 static void bluetooth_pb_agent_clear(PbAgentData *agent)
428 agent->pb_type = TELECOM_NONE;
432 static GDBusConnection *__bt_pb_get_gdbus_connection(void)
440 pb_dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
443 ERR("Unable to connect to dbus: %s", err->message);
452 static GVariant *__bt_pb_get_phonebook_folder_list(GError **error)
455 GVariant *folder_list;
458 GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
460 size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list);
462 for (i = 0; i < size; i++)
463 g_variant_builder_add(builder, "s",
464 bluetooth_pb_agent_folder_list[i]);
466 folder_list = g_variant_new("(as)", builder);
467 g_variant_builder_unref(builder);
474 static GVariant *__bt_pb_get_phonebook(PbAgentData *agent, const char *name,
475 guint64 filter, guint8 format, guint16 max_list_count,
476 guint16 list_start_offset, GError **err)
480 PhoneBookType pb_type = TELECOM_NONE;
481 GVariantBuilder *vcards;
483 INFO("name: %s filter: %lld format: %d max_list_count: %d list_start_offset: %d\n",
484 name, filter, format, max_list_count, list_start_offset);
486 __bluetooth_pb_agent_timeout_add_seconds(agent);
488 pb_type = __bluetooth_pb_get_pb_type(name);
490 if (pb_type == TELECOM_NONE) {
491 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
492 "unsupported name defined");
496 vcards = g_variant_builder_new(G_VARIANT_TYPE("as"));
498 if (max_list_count > 0) {
499 __bluetooth_pb_get_vcards(agent, pb_type, filter, format,
500 max_list_count, list_start_offset, vcards);
503 if (pb_type == TELECOM_MCH) {
504 phonebook = g_variant_new("(asu)", vcards,
505 unnotified_missed_call_count);
506 INFO("Notified [%d] missed call count",
507 unnotified_missed_call_count);
508 unnotified_missed_call_count = 0;
510 phonebook = g_variant_new("(asu)", vcards, 0);
513 g_variant_builder_unref(vcards);
519 static GVariant *__bt_pb_get_phonebook_size(PbAgentData *agent,
520 const char *name, GError **err)
523 GVariant *phonebook_size;
524 PhoneBookType pb_type = TELECOM_NONE;
527 DBG_SECURE("name: %s\n", name);
529 __bluetooth_pb_agent_timeout_add_seconds(agent);
531 pb_type = __bluetooth_pb_get_pb_type(name);
533 if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
534 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
535 "unsupported name defined");
540 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
541 if (pb_type == TELECOM_PB || pb_type == SIM_PB)
544 if (pb_type == TELECOM_PB)
547 if (pb_type == TELECOM_MCH) {
548 phonebook_size = g_variant_new("(uu)", count,
549 unnotified_missed_call_count);
550 INFO("Notified [%d] missed call count",
551 unnotified_missed_call_count);
552 unnotified_missed_call_count = 0;
554 phonebook_size = g_variant_new("(uu)", count, 0);
558 return phonebook_size;
562 static GVariant *__bt_pb_get_phonebook_list(PbAgentData *agent,
563 const char *name, GError **err)
566 GVariant *phonebook_list;
567 PhoneBookType pb_type = TELECOM_NONE;
569 GVariantBuilder *builder;
571 DBG_SECURE("name: %s\n", name);
573 __bluetooth_pb_agent_timeout_add_seconds(agent);
575 pb_type = __bluetooth_pb_get_pb_type(name);
577 if (pb_type == TELECOM_NONE) {
578 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
579 "unsupported name defined");
583 builder = g_variant_builder_new(G_VARIANT_TYPE("a(ssu)"));
585 __bluetooth_pb_get_list(agent, pb_type, builder);
587 INFO("pb_type[%d] / number of missed_call[%d]", pb_type,
588 unnotified_missed_call_count);
590 if (pb_type == TELECOM_MCH) {
591 phonebook_list = g_variant_new("(a(ssu)u)", builder,
592 unnotified_missed_call_count);
593 INFO("Notified [%d] missed call count",
594 unnotified_missed_call_count);
595 unnotified_missed_call_count = 0;
597 phonebook_list = g_variant_new("(a(ssu)u)", builder, 0);
600 g_variant_builder_unref(builder);
603 return phonebook_list;
606 static GVariant *__bt_pb_get_phonebook_entry(PbAgentData *agent,
607 const gchar *folder, const gchar *id, guint64 filter,
608 guint8 format, GError **err)
611 GVariant *phonebook_entry;
612 PhoneBookType pb_type = TELECOM_NONE;
615 const gchar *attr = NULL;
617 DBG_SECURE("folder: %s id: %s filter: %ld format: %d\n",
618 folder, id, filter, format);
620 __bluetooth_pb_agent_timeout_add_seconds(agent);
622 if (!g_str_has_suffix(id, ".vcf")) {
623 *err = __bt_pb_error(G_FILE_ERROR_INVAL, "invalid vcf file");
627 handle = (gint)g_ascii_strtoll(id, NULL, 10);
629 pb_type = __bluetooth_pb_get_pb_type(folder);
631 if (pb_type == TELECOM_NONE) {
632 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
633 "unsupported name defined");
637 /* create index cache */
638 __bluetooth_pb_get_list(agent, pb_type, NULL);
643 str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
646 if (_bluetooth_get_contact_addressbook(handle) == PBAP_ADDRESSBOOK_PHONE)
647 str = _bluetooth_pb_vcard_contact(handle,
653 str = _bluetooth_pb_vcard_call(handle, filter, format,
657 str = _bluetooth_pb_vcard_call(handle, filter, format, "DIALED");
660 str = _bluetooth_pb_vcard_call(handle, filter, format, "MISSED");
663 contacts_record_h record = NULL;
667 status = contacts_db_get_record(_contacts_phone_log._uri,
670 if (status != CONTACTS_ERROR_NONE)
673 attr = __bluetooth_pb_phone_log_get_log_type(record);
674 str = _bluetooth_pb_vcard_call(handle, filter, format, attr);
676 contacts_record_destroy(record, TRUE);
679 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
682 str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
685 if (_bluetooth_get_contact_addressbook(handle) == PBAP_ADDRESSBOOK_SIM)
686 str = _bluetooth_pb_vcard_contact(handle,
692 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
693 "unsupported name defined");
697 phonebook_entry = g_variant_new("(s)", str);
702 return phonebook_entry;
705 static GVariant *__bt_pb_get_phonebook_size_at(PbAgentData *agent,
706 const gchar *command, GError **err)
709 GVariant *phonebook_size;
710 PhoneBookType pb_type = TELECOM_NONE;
713 DBG("command: %s\n", command);
715 __bluetooth_pb_agent_timeout_add_seconds(agent);
717 pb_type = __bluetooth_pb_get_storage_pb_type(command);
719 if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
720 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
721 "unsupported name defined");
725 phonebook_size = g_variant_new("(u)", count);
728 return phonebook_size;
731 static GVariant *__bt_pb_get_phonebook_entries_at(PbAgentData *agent,
732 const gchar *command, gint32 start_index,
733 gint32 end_index, GError **err)
736 GVariant *phonebook_entries;
737 PhoneBookType pb_type = TELECOM_NONE;
738 GVariantBuilder *builder;
740 DBG("command: %s, start_index: %d, end_index: %d\n",
741 command, start_index, end_index);
743 __bluetooth_pb_agent_timeout_add_seconds(agent);
745 pb_type = __bluetooth_pb_get_storage_pb_type(command);
747 if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
748 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
749 "unsupported name defined");
753 builder = g_variant_builder_new(G_VARIANT_TYPE("a(ssu)"));
755 __bluetooth_pb_get_list_number(agent, pb_type,
756 start_index, end_index, builder);
758 phonebook_entries = g_variant_new("(a(ssu))", builder);
759 g_variant_builder_unref(builder);
762 return phonebook_entries;
765 static GVariant *__bt_pb_get_phonebook_entries_find_at(PbAgentData *agent,
766 const gchar *command, const gchar *find_text,
770 GVariant *phonebook_entries;
771 PhoneBookType pb_type = TELECOM_NONE;
772 GVariantBuilder *builder;
774 DBG("command: %s, find text: %s\n", command, find_text);
776 __bluetooth_pb_agent_timeout_add_seconds(agent);
778 pb_type = __bluetooth_pb_get_storage_pb_type(command);
780 if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
781 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
782 "unsupported name defined");
786 builder = g_variant_builder_new(G_VARIANT_TYPE("a(ssu)"));
788 __bluetooth_pb_get_list_name(agent, pb_type, find_text, builder);
790 phonebook_entries = g_variant_new("(a(ssu))", builder);
792 g_variant_builder_unref(builder);
795 return phonebook_entries;
798 static GVariant *__bt_pb_get_total_object_count(PbAgentData *agent,
799 gchar *path, GError **err)
802 GVariant *phonebook_size;
804 PhoneBookType pb_type = TELECOM_NONE;
806 __bluetooth_pb_agent_timeout_add_seconds(agent);
808 pb_type = __bluetooth_pb_get_storage_pb_type(path);
810 if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
811 *err = __bt_pb_error(G_FILE_ERROR_INVAL,
812 "unsupported name defined");
816 phonebook_size = g_variant_new("(u)", count);
819 return phonebook_size;
823 static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
828 int received_file_size = 0;
829 struct stat file_attr;
831 if (file_path == NULL || stream == NULL) {
832 ERR("Invalid data \n");
836 DBG_SECURE("file_path = %s\n", file_path);
838 if ((fp = fopen(file_path, "r+")) == NULL) {
839 ERR_SECURE("Cannot open %s\n", file_path);
843 if (fstat(fileno(fp), &file_attr) == 0) {
844 received_file_size = file_attr.st_size;
845 DBG("file_attr.st_size = %d, size = %d\n", file_attr.st_size,
848 if (received_file_size <= 0) {
849 ERR_SECURE("Some problem in the file size [%s] \n",
856 *stream = (char *)malloc(sizeof(char) *received_file_size);
857 if (NULL == *stream) {
863 ERR_SECURE("Some problem in the file [%s] \n", file_path);
869 read_len = fread(*stream, 1, received_file_size, fp);
876 DBG_SECURE("Cannot open %s\n", file_path);
889 static gboolean __bt_pb_add_contact(PbAgentData *agent, const char *filename,
893 /* Contact API is changed, Temporary blocked */
895 CTSstruct *contact_record = NULL;
896 GSList *numbers_list = NULL, *cursor;
898 int is_duplicated = 0;
902 DBG_SECURE("file_path = %s\n", filename);
904 err = contacts_svc_connect();
905 ERR("contact_db_service_connect fucntion call [error] = %d \n", err);
907 err = __bluetooth_pb_agent_read_file(filename, &stream);
910 contacts_svc_disconnect();
911 ERR("contacts_svc_disconnect fucntion call [error] = %d \n", err);
913 if (NULL != stream) {
920 is_success = contacts_svc_get_contact_from_vcard((const void *)stream,
923 DBG("contacts_svc_get_contact_from_vcard fucntion call [is_success] = %d \n", is_success);
925 if (0 == is_success) {
926 contacts_svc_struct_get_list(contact_record, CTS_CF_NUMBER_LIST,
928 cursor = numbers_list;
930 for (; cursor; cursor = g_slist_next(cursor)) {
931 if (contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER,
932 contacts_svc_value_get_str(cursor->data,
933 CTS_NUM_VAL_NUMBER_STR)) > 0) {
934 DBG("is_duplicated\n");
935 is_duplicated = TRUE;
939 if (is_duplicated == FALSE)
940 contacts_svc_insert_contact(0, contact_record);
945 err = contacts_svc_disconnect();
946 ERR("contacts_svc_disconnect fucntion call [error] = %d \n", err);
948 if (NULL != stream) {
957 /* Create GError from error code and error message*/
958 static GError *__bt_pb_error(gint error_code, const gchar *error_message)
960 return g_error_new(g_quark_from_string("PB Agent"),
961 error_code, "PB Agent Error: %s", error_message);
964 static PhoneBookType __bluetooth_pb_get_pb_type(const char *name)
967 gchar *suffix = ".vcf";
977 if (g_str_has_suffix(name, suffix))
978 len -= strlen(suffix);
980 size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list) - 1;
981 for (i = 0; i < size; i++) {
982 if (strncmp(name, bluetooth_pb_agent_folder_list[i], len) == 0)
990 static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
996 if (g_strcmp0(name, "\"ME\"") == 0)
999 if (g_strcmp0(name, "\"RC\"") == 0)
1002 if (g_strcmp0(name, "\"DC\"") == 0)
1005 if (g_strcmp0(name, "\"MC\"") == 0)
1007 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1008 if (g_strcmp0(name, "\"SM\"") == 0)
1012 return TELECOM_NONE;
1015 static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
1016 gint *match, gint size)
1022 for (i = 0; i < size; i++) {
1025 status = contacts_filter_add_operator(filter,
1026 CONTACTS_FILTER_OPERATOR_OR);
1028 if (status != CONTACTS_ERROR_NONE)
1032 status = contacts_filter_add_int(filter,
1033 _contacts_phone_log.log_type,
1034 CONTACTS_MATCH_EQUAL, match[i]);
1036 if (status != CONTACTS_ERROR_NONE)
1041 return CONTACTS_ERROR_NONE;
1044 static contacts_query_h __bluetooth_pb_query_phone_log(gint *match, gint size)
1047 contacts_query_h query = NULL;
1048 contacts_filter_h filter = NULL;
1051 status = contacts_query_create(_contacts_phone_log._uri, &query);
1053 if (status != CONTACTS_ERROR_NONE)
1056 status = contacts_filter_create(_contacts_phone_log._uri, &filter);
1058 if (status != CONTACTS_ERROR_NONE) {
1059 contacts_query_destroy(query);
1063 status = __bluetooth_pb_phone_log_filter_append(filter, match, size);
1065 if (status != CONTACTS_ERROR_NONE) {
1066 contacts_filter_destroy(filter);
1067 contacts_query_destroy(query);
1071 status = contacts_query_set_filter(query, filter);
1073 if (status != CONTACTS_ERROR_NONE) {
1074 contacts_filter_destroy(filter);
1075 contacts_query_destroy(query);
1079 status = contacts_query_set_sort(query, _contacts_phone_log.log_time,
1082 if (status != CONTACTS_ERROR_NONE) {
1083 contacts_filter_destroy(filter);
1084 contacts_query_destroy(query);
1088 contacts_filter_destroy(filter);
1094 bool __bt_is_matching_addressbook(const char *addressbook_name, int addressbook)
1096 bool is_sim_addressbook = _bt_is_sim_addressbook(addressbook_name);
1098 if ((is_sim_addressbook == false
1099 && addressbook == PBAP_ADDRESSBOOK_PHONE) ||
1100 (is_sim_addressbook == true
1101 && addressbook == PBAP_ADDRESSBOOK_SIM))
1107 static contacts_query_h __bluetooth_pb_query_person(int addressbook)
1110 contacts_query_h query = NULL;
1111 contacts_filter_h filter = NULL;
1112 contacts_list_h recordList = NULL;
1113 contacts_record_h record = NULL;
1114 char *addressbook_name = NULL;
1115 int address_book_id = 0;
1119 bool is_first_condition = true;
1121 DBG("Addressbook [%d]", addressbook);
1123 status = contacts_query_create(_contacts_person_contact._uri, &query);
1125 ERR("Could not create query");
1129 /* Create addressbook Filter*/
1130 status = contacts_db_get_all_records(_contacts_address_book._uri, 0, 0,
1132 if (status != CONTACTS_ERROR_NONE)
1133 ERR("Contact list get api failed %d", status);
1135 contacts_filter_create(_contacts_person_contact._uri, &filter);
1136 contacts_list_get_count(recordList, &count);
1138 for (i = 0; i < count; i++) {
1139 status = contacts_list_get_current_record_p(recordList, &record);
1140 if (status != CONTACTS_ERROR_NONE) {
1141 ERR("Contact list get api failed %d", status);
1144 status = contacts_record_get_str_p(record,
1145 _contacts_address_book.name,
1147 if (status != CONTACTS_ERROR_NONE) {
1148 ERR("Contact record get api failed %d", status);
1151 status = contacts_record_get_int(record,
1152 _contacts_address_book.id,
1154 if (status != CONTACTS_ERROR_NONE) {
1155 ERR("contacts record get int api failed %d", status);
1159 DBG("Addressbook ID: [%d] Addressbook Name: [%s]",
1160 address_book_id, addressbook_name);
1162 if (__bt_is_matching_addressbook(addressbook_name,
1164 if (is_first_condition)
1165 is_first_condition = false;
1167 contacts_filter_add_operator(filter,
1168 CONTACTS_FILTER_OPERATOR_OR);
1169 DBG("SELECTED Addressbook ID: [%d] Addressbook Name: [%s]",
1170 address_book_id, addressbook_name);
1171 status = contacts_filter_add_int(filter,
1172 _contacts_person_contact.address_book_id,
1173 CONTACTS_MATCH_EQUAL, address_book_id);
1174 if (status != CONTACTS_ERROR_NONE)
1175 ERR("Contact filter add failed %d", status);
1178 if (contacts_list_next(recordList) != CONTACTS_ERROR_NONE)
1182 contacts_list_destroy(recordList, true);
1184 if (is_first_condition) {
1185 ERR("ADDRESSBOOK NOT FOUND");
1186 contacts_filter_destroy(filter);
1187 contacts_query_destroy(query);
1191 status = contacts_query_set_filter(query, filter);
1192 if (status != CONTACTS_ERROR_NONE)
1193 ERR("Could not Apply Filter");
1195 contacts_filter_destroy(filter);
1200 static contacts_query_h __bluetooth_pb_query_person_number(void)
1203 contacts_query_h query = NULL;
1206 status = contacts_query_create(_contacts_person_number._uri, &query);
1208 if (status != CONTACTS_ERROR_NONE)
1215 static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void)
1220 CONTACTS_PLOG_TYPE_VOICE_INCOMING,
1221 CONTACTS_PLOG_TYPE_VIDEO_INCOMING,
1222 CONTACTS_PLOG_TYPE_VOICE_REJECT,
1223 CONTACTS_PLOG_TYPE_VIDEO_REJECT
1227 return __bluetooth_pb_query_phone_log(match, size);
1230 static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void)
1235 CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
1236 CONTACTS_PLOG_TYPE_VIDEO_OUTGOING
1240 return __bluetooth_pb_query_phone_log(match, size);
1243 static contacts_query_h __bluetooth_pb_query_phone_log_missed(void)
1248 CONTACTS_PLOG_TYPE_VOICE_INCOMING_UNSEEN,
1249 CONTACTS_PLOG_TYPE_VIDEO_INCOMING_UNSEEN,
1250 CONTACTS_PLOG_TYPE_VOICE_INCOMING_SEEN,
1251 CONTACTS_PLOG_TYPE_VIDEO_INCOMING_SEEN
1255 return __bluetooth_pb_query_phone_log(match, size);
1258 static contacts_query_h __bluetooth_pb_query_phone_log_combined(void)
1263 CONTACTS_PLOG_TYPE_VOICE_INCOMING,
1264 CONTACTS_PLOG_TYPE_VIDEO_INCOMING,
1265 CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
1266 CONTACTS_PLOG_TYPE_VIDEO_OUTGOING,
1267 CONTACTS_PLOG_TYPE_VOICE_INCOMING_UNSEEN,
1268 CONTACTS_PLOG_TYPE_VIDEO_INCOMING_UNSEEN,
1269 CONTACTS_PLOG_TYPE_VOICE_INCOMING_SEEN,
1270 CONTACTS_PLOG_TYPE_VIDEO_INCOMING_SEEN,
1271 CONTACTS_PLOG_TYPE_VOICE_REJECT,
1272 CONTACTS_PLOG_TYPE_VIDEO_REJECT
1276 return __bluetooth_pb_query_phone_log(match, size);
1279 static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
1283 contacts_query_h query = NULL;
1289 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1292 query = __bluetooth_pb_query_phone_log_incoming();
1295 query = __bluetooth_pb_query_phone_log_outgoing();
1298 query = __bluetooth_pb_query_phone_log_missed();
1301 query = __bluetooth_pb_query_phone_log_combined();
1303 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1305 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1315 status = contacts_db_get_count_with_query(query, &signed_count);
1317 if (status != CONTACTS_ERROR_NONE) {
1318 contacts_query_destroy(query);
1322 contacts_query_destroy(query);
1324 if (signed_count < 0)
1327 *count = (gint) signed_count;
1333 static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count)
1336 contacts_query_h query = NULL;
1341 CONTACTS_PLOG_TYPE_VOICE_INCOMING_UNSEEN,
1342 CONTACTS_PLOG_TYPE_VIDEO_INCOMING_UNSEEN
1345 query = __bluetooth_pb_query_phone_log(match, size);
1350 status = contacts_db_get_count_with_query(query, &signed_count);
1352 if (status != CONTACTS_ERROR_NONE) {
1353 contacts_query_destroy(query);
1357 contacts_query_destroy(query);
1359 if (signed_count < 0)
1362 *count = (guint)signed_count;
1368 static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record)
1374 status = contacts_record_get_int(record, _contacts_phone_log.log_type,
1377 if (status != CONTACTS_ERROR_NONE)
1381 case CONTACTS_PLOG_TYPE_VOICE_INCOMING:
1382 case CONTACTS_PLOG_TYPE_VIDEO_INCOMING:
1383 case CONTACTS_PLOG_TYPE_VOICE_REJECT:
1384 case CONTACTS_PLOG_TYPE_VIDEO_REJECT:
1386 case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
1387 case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
1389 case CONTACTS_PLOG_TYPE_VOICE_INCOMING_UNSEEN:
1390 case CONTACTS_PLOG_TYPE_VIDEO_INCOMING_UNSEEN:
1391 case CONTACTS_PLOG_TYPE_VOICE_INCOMING_SEEN:
1392 case CONTACTS_PLOG_TYPE_VIDEO_INCOMING_SEEN:
1400 static void __bluetooth_pb_get_vcards(PbAgentData *agent, PhoneBookType pb_type,
1401 guint64 filter, guint8 format, guint16 max_list_count,
1402 guint16 list_start_offset, GVariantBuilder *vcards)
1405 contacts_list_h record_list = NULL;
1406 contacts_query_h query = NULL;
1410 guint property_id = 0;
1411 const char *attr = NULL;
1412 gboolean get_log = FALSE;
1414 /* contact offset is n - 1 of PBAP */
1415 offset = (gint)list_start_offset - 1;
1417 if (max_list_count >= 65535)
1418 limit = -1; /* contact limit -1 means unrestricted */
1420 limit = (gint)max_list_count;
1424 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1428 if (list_start_offset == 0) {
1431 vcard = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
1434 g_variant_builder_add(vcards, "s", vcard);
1444 if (pb_type == TELECOM_PB)
1445 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1446 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1447 else if (pb_type == SIM_PB)
1448 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1451 property_id = _contacts_person.id;
1454 query = __bluetooth_pb_query_phone_log_incoming();
1455 property_id = _contacts_phone_log.id;
1459 query = __bluetooth_pb_query_phone_log_outgoing();
1460 property_id = _contacts_phone_log.id;
1464 query = __bluetooth_pb_query_phone_log_missed();
1465 property_id = _contacts_phone_log.id;
1469 query = __bluetooth_pb_query_phone_log_combined();
1470 property_id = _contacts_phone_log.id;
1476 INFO("Limit is = %d and offset is =%d\n", limit, offset);
1478 if (query == NULL) {
1479 ERR("Query is NULL");
1482 /* When limit is passed as ZERO to contacts_db_get_records_with_query
1483 * API then this API will provide all available contacts in its database
1484 * (unrestricted). Now consider a case when client requests for
1485 * maxlistcount of 1 and start offset as 0 then we have already read the
1486 * owner card in above switch case and when it reads owner card it
1487 * decrements the limit by 1.
1490 status = contacts_db_get_records_with_query(query, offset,
1491 limit, &record_list);
1493 if (status != CONTACTS_ERROR_NONE) {
1494 contacts_list_destroy(record_list, TRUE);
1495 contacts_query_destroy(query);
1499 status = contacts_list_first(record_list);
1501 if (status != CONTACTS_ERROR_NONE) {
1502 contacts_list_destroy(record_list, TRUE);
1503 contacts_query_destroy(query);
1508 contacts_record_h record;
1510 gchar *vcard = NULL;
1512 status = contacts_list_get_current_record_p(record_list,
1515 if (status != CONTACTS_ERROR_NONE)
1517 status = contacts_record_get_int(record, property_id,
1520 if (status != CONTACTS_ERROR_NONE)
1523 if (property_id == _contacts_person.id)
1524 vcard = _bluetooth_pb_vcard_contact(id, filter,
1528 attr = __bluetooth_pb_phone_log_get_log_type(record);
1530 vcard = _bluetooth_pb_vcard_call(id, filter,
1535 g_variant_builder_add(vcards, "s", vcard);
1537 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1538 contacts_list_destroy(record_list, TRUE);
1541 contacts_query_destroy(query);
1546 static void __bluetooth_pb_get_contact_list(PbAgentData *agent,
1547 contacts_query_h query, GVariantBuilder *builder)
1550 contacts_list_h record_list = NULL;
1558 tmp = _bluetooth_pb_owner_name();
1559 name = g_strdup_printf("%s;;;;", tmp);
1562 __bluetooth_pb_list_ptr_array_add(builder, name,
1563 agent->tel_number, 0);
1568 if (query == NULL) {
1569 ERR("Query is NULL");
1573 status = contacts_db_get_records_with_query(query, -1, -1,
1576 if (status != CONTACTS_ERROR_NONE) {
1577 contacts_list_destroy(record_list, TRUE);
1581 status = contacts_list_first(record_list);
1583 if (status != CONTACTS_ERROR_NONE) {
1584 contacts_list_destroy(record_list, TRUE);
1589 contacts_record_h record;
1592 status = contacts_list_get_current_record_p(record_list,
1595 if (status != CONTACTS_ERROR_NONE)
1598 status = contacts_record_get_int(record,
1599 _contacts_person_contact.person_id, &id);
1601 if (status != CONTACTS_ERROR_NONE)
1609 name = _bluetooth_pb_name_from_person_id(id);
1610 number = _bluetooth_pb_number_from_person_id(id);
1612 __bluetooth_pb_list_ptr_array_add(builder, name,
1619 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1621 contacts_list_destroy(record_list, TRUE);
1625 static void __bluetooth_pb_get_phone_log_list(PbAgentData *agent,
1626 contacts_query_h query, GVariantBuilder *builder)
1629 contacts_list_h record_list = NULL;
1632 status = contacts_db_get_records_with_query(query, -1, -1,
1635 if (status != CONTACTS_ERROR_NONE)
1638 status = contacts_list_first(record_list);
1640 if (status != CONTACTS_ERROR_NONE) {
1641 contacts_list_destroy(record_list, TRUE);
1646 contacts_record_h record;
1649 status = contacts_list_get_current_record_p(record_list,
1652 if (status != CONTACTS_ERROR_NONE)
1655 status = contacts_record_get_int(record,
1656 _contacts_phone_log.id, &id);
1658 if (status != CONTACTS_ERROR_NONE)
1666 name = _bluetooth_pb_name_from_phonelog_id(id);
1668 contacts_record_get_str_p(record,
1669 _contacts_phone_log.address, &number);
1671 __bluetooth_pb_list_ptr_array_add(builder, name,
1677 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1679 contacts_list_destroy(record_list, TRUE);
1684 static void __bluetooth_pb_get_list(PbAgentData *agent, PhoneBookType pb_type,
1685 GVariantBuilder *builder)
1688 contacts_query_h query;
1690 /* no requires refresh cache */
1691 if (builder == NULL && agent->pb_type == pb_type)
1696 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1697 __bluetooth_pb_get_contact_list(agent, query, builder);
1700 query = __bluetooth_pb_query_phone_log_incoming();
1701 __bluetooth_pb_get_phone_log_list(agent, query, builder);
1704 query = __bluetooth_pb_query_phone_log_outgoing();
1705 __bluetooth_pb_get_phone_log_list(agent, query, builder);
1708 query = __bluetooth_pb_query_phone_log_missed();
1709 __bluetooth_pb_get_phone_log_list(agent, query, builder);
1712 query = __bluetooth_pb_query_phone_log_combined();
1713 __bluetooth_pb_get_phone_log_list(agent, query, builder);
1715 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1717 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1718 __bluetooth_pb_get_contact_list(agent, query, builder);
1725 agent->pb_type = pb_type;
1728 contacts_query_destroy(query);
1732 static void __bluetooth_pb_get_contact_list_number(PbAgentData *agent,
1733 contacts_query_h query, gint start_index,
1734 gint end_index, GVariantBuilder *builder)
1737 contacts_list_h record_list = NULL;
1753 offset = to - from + 1;
1759 status = contacts_db_get_records_with_query(query, from - 1 , offset,
1762 if (status != CONTACTS_ERROR_NONE) {
1763 contacts_list_destroy(record_list, TRUE);
1767 status = contacts_list_first(record_list);
1769 if (status != CONTACTS_ERROR_NONE) {
1770 contacts_list_destroy(record_list, TRUE);
1775 contacts_record_h record;
1776 gchar *display_name;
1779 status = contacts_list_get_current_record_p(record_list,
1782 if (status != CONTACTS_ERROR_NONE)
1785 contacts_record_get_str_p(record,
1786 _contacts_person_number.display_name,
1788 contacts_record_get_str_p(record,
1789 _contacts_person_number.number, &number);
1791 __bluetooth_pb_list_ptr_array_add(builder, display_name,
1795 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1797 contacts_list_destroy(record_list, TRUE);
1801 static void __bluetooth_pb_get_phone_log_list_number(PbAgentData *agent,
1802 contacts_query_h query, gint start_index,
1803 gint end_index, GVariantBuilder *builder)
1806 contacts_list_h record_list = NULL;
1822 offset = to - from + 1;
1828 status = contacts_db_get_records_with_query(query, from - 1 , offset,
1831 if (status != CONTACTS_ERROR_NONE) {
1832 contacts_list_destroy(record_list, TRUE);
1836 status = contacts_list_first(record_list);
1837 if (status != CONTACTS_ERROR_NONE) {
1838 contacts_list_destroy(record_list, TRUE);
1843 contacts_record_h record;
1845 gchar *display_name;
1848 status = contacts_list_get_current_record_p(record_list,
1851 if (status != CONTACTS_ERROR_NONE)
1854 status = contacts_record_get_int(record,
1855 _contacts_phone_log.id, &id);
1856 if (status != CONTACTS_ERROR_NONE) {
1857 ERR("contact_record_get_int api failed %d", status);
1861 display_name = _bluetooth_pb_fn_from_phonelog_id(id);
1863 contacts_record_get_str_p(record, _contacts_phone_log.address,
1866 __bluetooth_pb_list_ptr_array_add(builder, display_name,
1871 g_free(display_name);
1873 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1875 contacts_list_destroy(record_list, TRUE);
1879 static void __bluetooth_pb_get_list_number(PbAgentData *agent,
1880 PhoneBookType pb_type, gint start_index,
1881 gint end_index, GVariantBuilder *builder)
1884 contacts_query_h query;
1886 DBG("type = %d", pb_type);
1889 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE);
1890 __bluetooth_pb_get_contact_list_number(agent, query,
1891 start_index, end_index, builder);
1894 query = __bluetooth_pb_query_phone_log_incoming();
1895 __bluetooth_pb_get_phone_log_list_number(agent, query,
1896 start_index, end_index, builder);
1899 query = __bluetooth_pb_query_phone_log_outgoing();
1900 __bluetooth_pb_get_phone_log_list_number(agent, query,
1901 start_index, end_index, builder);
1904 query = __bluetooth_pb_query_phone_log_missed();
1905 __bluetooth_pb_get_phone_log_list_number(agent, query,
1906 start_index, end_index, builder);
1909 query = __bluetooth_pb_query_phone_log_combined();
1910 __bluetooth_pb_get_phone_log_list_number(agent, query,
1911 start_index, end_index, builder);
1913 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
1915 query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM);
1916 __bluetooth_pb_get_contact_list_number(agent, query,
1917 start_index, end_index, builder);
1926 contacts_query_destroy(query);
1930 static void __bluetooth_pb_get_contact_list_name(PbAgentData *agent,
1931 contacts_query_h query, const gchar *find_text,
1932 GVariantBuilder *builder)
1935 contacts_list_h record_list = NULL;
1939 status = contacts_db_get_records_with_query(query,
1940 -1, -1, &record_list);
1942 if (status != CONTACTS_ERROR_NONE) {
1943 contacts_list_destroy(record_list, TRUE);
1947 status = contacts_list_first(record_list);
1949 if (status != CONTACTS_ERROR_NONE) {
1950 contacts_list_destroy(record_list, TRUE);
1955 contacts_record_h record;
1956 gchar *display_name;
1958 status = contacts_list_get_current_record_p(record_list,
1961 if (status != CONTACTS_ERROR_NONE)
1964 contacts_record_get_str_p(record,
1965 _contacts_person_number.display_name, &display_name);
1967 if (g_str_has_prefix(display_name, find_text)) {
1970 contacts_record_get_str_p(record,
1971 _contacts_person_number.number, &number);
1973 __bluetooth_pb_list_ptr_array_add(builder, display_name,
1978 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
1979 contacts_list_destroy(record_list, TRUE);
1983 static void __bluetooth_pb_get_phone_log_list_name(PbAgentData *agent,
1984 contacts_query_h query, const gchar *find_text,
1985 GVariantBuilder *builder)
1988 contacts_list_h record_list = NULL;
1992 status = contacts_db_get_records_with_query(query, -1, -1,
1995 if (status != CONTACTS_ERROR_NONE) {
1996 contacts_list_destroy(record_list, TRUE);
2000 status = contacts_list_first(record_list);
2002 if (status != CONTACTS_ERROR_NONE) {
2003 contacts_list_destroy(record_list, TRUE);
2008 contacts_record_h record;
2010 gchar *display_name;
2012 status = contacts_list_get_current_record_p(record_list,
2015 if (status != CONTACTS_ERROR_NONE)
2018 status = contacts_record_get_int(record,
2019 _contacts_phone_log.id, &id);
2020 if (status != CONTACTS_ERROR_NONE) {
2021 ERR("contacts_record_get_int failed %d", status);
2025 display_name = _bluetooth_pb_fn_from_phonelog_id(id);
2027 if (g_str_has_prefix(display_name, find_text)) {
2030 contacts_record_get_str_p(record,
2031 _contacts_phone_log.address, &number);
2033 __bluetooth_pb_list_ptr_array_add(builder, display_name,
2039 g_free(display_name);
2041 } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
2043 contacts_list_destroy(record_list, TRUE);
2047 static void __bluetooth_pb_get_list_name(PbAgentData *agent,
2048 PhoneBookType pb_type, const gchar *find_text,
2049 GVariantBuilder *builder)
2052 contacts_query_h query;
2056 query = __bluetooth_pb_query_person_number();
2057 __bluetooth_pb_get_contact_list_name(agent, query,
2058 find_text, builder);
2061 query = __bluetooth_pb_query_phone_log_incoming();
2062 __bluetooth_pb_get_phone_log_list_name(agent, query,
2063 find_text, builder);
2066 query = __bluetooth_pb_query_phone_log_outgoing();
2067 __bluetooth_pb_get_phone_log_list_name(agent, query,
2068 find_text, builder);
2071 query = __bluetooth_pb_query_phone_log_missed();
2072 __bluetooth_pb_get_phone_log_list_name(agent, query,
2073 find_text, builder);
2076 query = __bluetooth_pb_query_phone_log_combined();
2077 __bluetooth_pb_get_phone_log_list_name(agent, query,
2078 find_text, builder);
2085 contacts_query_destroy(query);
2089 static void __bluetooth_pb_list_ptr_array_add(GVariantBuilder *builder,
2090 const gchar *name, const gchar *number, gint handle)
2093 gchar *temp_name = g_strdup(name);
2094 gchar *temp_number = g_strdup(number);
2096 g_variant_builder_add(builder, "(ssu)", temp_name, temp_number, handle);
2103 static void __bluetooth_pb_agent_signal_handler(int signum)
2107 g_main_loop_quit(g_mainloop);
2109 DBG("Terminate Bluetooth PBAP agent");
2114 static void __bluetooth_pb_contact_changed(const gchar *view_uri,
2118 guint new_missed_call;
2119 PbAgentData *agent = (PbAgentData *)user_data;
2120 GDBusConnection *conn = __bt_pb_get_gdbus_connection();
2122 DBG("Received contact changed cb");
2124 g_dbus_connection_emit_signal(conn, NULL,
2125 "/org/bluez/pb_agent", "org.bluez.PbAgent",
2126 "clear", NULL, NULL);
2128 bluetooth_pb_agent_clear(agent);
2130 __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
2132 if (new_missed_call > total_missed_call_count)
2133 unnotified_missed_call_count += new_missed_call -
2134 total_missed_call_count;
2136 INFO("Missed call count : #prev[%d], #current[%d], #unnotified[%d]",
2137 total_missed_call_count, new_missed_call,
2138 unnotified_missed_call_count);
2140 total_missed_call_count = new_missed_call;
2144 static void __bluetooth_pb_agent_timeout_add_seconds(PbAgentData *agent)
2148 if (agent->timeout_id)
2149 g_source_remove(agent->timeout_id);
2151 agent->timeout_id = g_timeout_add_seconds(BLUETOOTH_PB_AGENT_TIMEOUT,
2152 __bluetooth_pb_agent_timeout_calback, agent);
2156 static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data)
2159 PbAgentData *agent = (PbAgentData *)user_data;
2161 agent->timeout_id = 0;
2164 g_main_loop_quit(g_mainloop);
2170 static void __bluetooth_pb_tel_callback(TapiHandle *handle, int result,
2171 void *data, void *user_data)
2174 PbAgentData *agent = (PbAgentData *)user_data;
2175 TelSimMsisdnList_t *number;
2177 __bt_pb_dbus_init(agent);
2180 number = (TelSimMsisdnList_t *)data;
2181 agent->tel_number = g_strdup(number->list[0].num);
2184 tel_deinit(agent->tapi_handle);
2185 agent->tapi_handle = NULL;
2189 static gboolean __bt_pb_destroy_agent()
2192 g_main_loop_quit(g_mainloop);
2197 static GDBusNodeInfo *__bt_pb_create_method_node_info
2198 (const gchar *introspection_data)
2201 GDBusNodeInfo *node_info = NULL;
2203 if (introspection_data == NULL)
2206 node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
2209 ERR("Unable to create node: %s", err->message);
2210 g_clear_error(&err);
2215 static gboolean __bt_pb_dbus_init(PbAgentData *agent)
2219 GDBusNodeInfo *node_info = NULL;
2220 GError *error = NULL;
2221 GDBusConnection *conn = __bt_pb_get_gdbus_connection();
2224 ERR("Error in creating the gdbus connection");
2228 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, BT_PB_SERVICE_NAME,
2229 G_BUS_NAME_OWNER_FLAGS_NONE, NULL,
2230 NULL, NULL, NULL, NULL);
2234 node_info = __bt_pb_create_method_node_info(pb_agent_introspection_xml);
2235 if (node_info == NULL)
2238 pb_id = g_dbus_connection_register_object(conn, BT_PB_SERVICE_OBJECT_PATH,
2239 node_info->interfaces[0], &method_table,
2240 agent, NULL, &error);
2243 ERR("Failed to register: %s", error->message);
2244 g_clear_error(&error);
2248 agent->pbagent_interface_id = pb_id;
2250 pb_id = g_dbus_connection_register_object(conn, BT_PB_SERVICE_OBJECT_PATH,
2251 node_info->interfaces[1], &method_table,
2252 agent, NULL, &error);
2255 ERR("Failed to register: %s", error->message);
2256 g_clear_error(&error);
2260 g_dbus_node_info_unref(node_info);
2262 agent->pbagent_at_interface_id = pb_id;
2268 g_object_unref(pb_dbus_conn);
2269 pb_dbus_conn = NULL;
2273 g_object_unref(conn);
2276 g_dbus_node_info_unref(node_info);
2279 g_bus_unown_name(owner_id);
2284 static gboolean __bt_pb_dbus_deinit(PbAgentData *agent)
2287 if (agent->pbagent_interface_id != 0) {
2288 g_dbus_connection_unregister_object(pb_dbus_conn,
2289 agent->pbagent_interface_id);
2290 agent->pbagent_interface_id = 0;
2292 if (agent->pbagent_at_interface_id != 0) {
2293 g_dbus_connection_unregister_object(pb_dbus_conn,
2294 agent->pbagent_at_interface_id);
2295 agent->pbagent_at_interface_id = 0;
2298 g_object_unref(pb_dbus_conn);
2299 pb_dbus_conn = NULL;
2310 gint ret = EXIT_SUCCESS;
2312 struct sigaction sa;
2314 DBG("Starting Bluetooth PBAP agent");
2316 g_mainloop = g_main_loop_new(NULL, FALSE);
2317 if (g_mainloop == NULL) {
2318 ERR("Couldn't create GMainLoop\n");
2319 return EXIT_FAILURE;
2322 agent = (PbAgentData *)g_malloc(sizeof(PbAgentData));
2325 return EXIT_FAILURE;
2327 agent->pbagent_interface_id = 0;
2328 agent->pbagent_at_interface_id = 0;
2329 agent->tel_number = NULL;
2331 /* connect contact */
2332 if (contacts_connect() != CONTACTS_ERROR_NONE) {
2333 ERR("Can not connect contacts server\n");
2335 return EXIT_FAILURE;
2338 __bluetooth_pb_get_count_new_missed_call(&total_missed_call_count);
2340 if (contacts_db_add_changed_cb(_contacts_contact._uri,
2341 __bluetooth_pb_contact_changed,
2342 (void *)agent) != CONTACTS_ERROR_NONE) {
2343 ERR("Can not add changed callback");
2346 if (contacts_db_add_changed_cb(_contacts_phone_log._uri,
2347 __bluetooth_pb_contact_changed,
2348 (void *)agent) != CONTACTS_ERROR_NONE) {
2349 ERR("Can not add changed callback");
2353 memset(&sa, 0, sizeof(sa));
2354 sa.sa_handler = __bluetooth_pb_agent_signal_handler;
2355 sigaction(SIGTERM, &sa, NULL);
2356 sigaction(SIGINT, &sa, NULL);
2359 agent->tapi_handle = tel_init(NULL);
2360 tapi_result = tel_get_sim_msisdn(agent->tapi_handle,
2361 __bluetooth_pb_tel_callback, agent);
2363 if (tapi_result != TAPI_API_SUCCESS)
2364 __bt_pb_dbus_init(agent);
2366 __bluetooth_pb_agent_timeout_add_seconds(agent);
2368 g_main_loop_run(g_mainloop);
2370 if (contacts_db_remove_changed_cb(_contacts_phone_log._uri,
2371 __bluetooth_pb_contact_changed,
2372 (void *)agent) != CONTACTS_ERROR_NONE) {
2373 ERR("Cannot remove changed callback");
2376 if (contacts_db_remove_changed_cb(_contacts_contact._uri,
2377 __bluetooth_pb_contact_changed,
2378 (void *)agent) != CONTACTS_ERROR_NONE) {
2379 ERR("Cannot remove changed callback");
2382 if (contacts_disconnect() != CONTACTS_ERROR_NONE)
2383 ERR("contacts_disconnect failed \n");
2385 g_dbus_connection_emit_signal(pb_dbus_conn, NULL,
2386 "/org/bluez/pb_agent", "org.bluez.PbAgent",
2387 "clear", NULL, NULL);
2389 bluetooth_pb_agent_clear(agent);
2391 if (agent->tapi_handle)
2392 tel_deinit(agent->tapi_handle);
2393 if (agent->tel_number)
2394 g_free(agent->tel_number);
2396 __bt_pb_dbus_deinit(agent);
2400 DBG("Terminate Bluetooth PBAP agent");