Initialize Tizen 2.3 2.3a_release submit/tizen_2.3/20140531.055718
authorSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 03:30:43 +0000 (12:30 +0900)
committerSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 03:30:43 +0000 (12:30 +0900)
54 files changed:
mobile/AUTHORS [new file with mode: 0644]
mobile/CMakeLists.txt [new file with mode: 0644]
mobile/LICENSE.APLv2 [new file with mode: 0644]
mobile/NOTICE [new file with mode: 0644]
mobile/bluetooth-agent.manifest [new file with mode: 0644]
mobile/bluetooth-agent.rule [new file with mode: 0644]
mobile/hfp-agent/CMakeLists.txt [new file with mode: 0644]
mobile/hfp-agent/bluetooth-hfp-agent.c [new file with mode: 0644]
mobile/hfp-agent/bluetooth-hfp-agent.h [new file with mode: 0644]
mobile/hfp-agent/hfp_agent.xml [new file with mode: 0644]
mobile/hfp-agent/org.bluez.hfp_agent.service [new file with mode: 0644]
mobile/map-agent/CMakeLists.txt [new file with mode: 0644]
mobile/map-agent/bluetooth_map_agent.c [new file with mode: 0644]
mobile/map-agent/bluetooth_map_agent.h [new file with mode: 0644]
mobile/map-agent/bluetooth_map_agent.xml [new file with mode: 0644]
mobile/map-agent/map_bmessage.c [new file with mode: 0644]
mobile/map-agent/map_bmessage.h [new file with mode: 0644]
mobile/map-agent/org.bluez.map_agent.service [new file with mode: 0644]
mobile/pb-agent/CMakeLists.txt [new file with mode: 0644]
mobile/pb-agent/bluetooth_pb_agent.c [new file with mode: 0644]
mobile/pb-agent/bluetooth_pb_agent.h [new file with mode: 0644]
mobile/pb-agent/bluetooth_pb_agent.xml [new file with mode: 0644]
mobile/pb-agent/bluetooth_pb_vcard.c [new file with mode: 0644]
mobile/pb-agent/bluetooth_pb_vcard.h [new file with mode: 0644]
mobile/pb-agent/org.bluez.pb_agent.service [new file with mode: 0644]
packaging/bluetooth-agent.spec [new file with mode: 0644]
wearable/AUTHORS [new file with mode: 0644]
wearable/CMakeLists.txt [new file with mode: 0644]
wearable/LICENSE.APLv2 [new file with mode: 0644]
wearable/NOTICE [new file with mode: 0644]
wearable/bluetooth-agent.manifest [new file with mode: 0644]
wearable/hf-agent/CMakeLists.txt [new file with mode: 0644]
wearable/hf-agent/bluetooth-hf-agent.c [new file with mode: 0755]
wearable/hf-agent/bluetooth-hf-agent.h [new file with mode: 0644]
wearable/hf-agent/org.bluez.hf_agent.service [new file with mode: 0644]
wearable/hfp-agent/CMakeLists.txt [new file with mode: 0644]
wearable/hfp-agent/bluetooth-hfp-agent.c [new file with mode: 0644]
wearable/hfp-agent/bluetooth-hfp-agent.h [new file with mode: 0644]
wearable/hfp-agent/hfp_agent.xml [new file with mode: 0644]
wearable/hfp-agent/org.bluez.hfp_agent.service [new file with mode: 0644]
wearable/map-agent/CMakeLists.txt [new file with mode: 0644]
wearable/map-agent/bluetooth_map_agent.c [new file with mode: 0644]
wearable/map-agent/bluetooth_map_agent.h [new file with mode: 0644]
wearable/map-agent/bluetooth_map_agent.xml [new file with mode: 0644]
wearable/map-agent/map_bmessage.c [new file with mode: 0644]
wearable/map-agent/map_bmessage.h [new file with mode: 0644]
wearable/map-agent/org.bluez.map_agent.service [new file with mode: 0644]
wearable/pb-agent/CMakeLists.txt [new file with mode: 0644]
wearable/pb-agent/bluetooth_pb_agent.c [new file with mode: 0644]
wearable/pb-agent/bluetooth_pb_agent.h [new file with mode: 0644]
wearable/pb-agent/bluetooth_pb_agent.xml [new file with mode: 0644]
wearable/pb-agent/bluetooth_pb_vcard.c [new file with mode: 0644]
wearable/pb-agent/bluetooth_pb_vcard.h [new file with mode: 0644]
wearable/pb-agent/org.bluez.pb_agent.service [new file with mode: 0644]

diff --git a/mobile/AUTHORS b/mobile/AUTHORS
new file mode 100644 (file)
index 0000000..46d1687
--- /dev/null
@@ -0,0 +1,2 @@
+Jinmin Jung <jinmin@samsung.com>
+DoHyun Pyun <dh79.pyun@samsung.com>
diff --git a/mobile/CMakeLists.txt b/mobile/CMakeLists.txt
new file mode 100644 (file)
index 0000000..db1036d
--- /dev/null
@@ -0,0 +1,10 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+ADD_SUBDIRECTORY(map-agent)
+
+ADD_SUBDIRECTORY(pb-agent)
+
+ADD_SUBDIRECTORY(hfp-agent)
+
+# install rule file
+INSTALL(FILES ${CMAKE_BINARY_DIR}/bluetooth-agent.rule DESTINATION /opt/etc/smack/accesses.d)
diff --git a/mobile/LICENSE.APLv2 b/mobile/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..6b0b127
--- /dev/null
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/mobile/NOTICE b/mobile/NOTICE
new file mode 100644 (file)
index 0000000..0e0f016
--- /dev/null
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/mobile/bluetooth-agent.manifest b/mobile/bluetooth-agent.manifest
new file mode 100644 (file)
index 0000000..b26254b
--- /dev/null
@@ -0,0 +1,15 @@
+<manifest>
+    <define>
+        <domain name="bt_agent"/>
+    </define>
+
+    <assign>
+        <filesystem path="/usr/share/dbus-1/services/org.bluez.hfp_agent.service" label="_"/>
+        <filesystem path="/usr/share/dbus-1/services/org.bluez.map_agent.service" label="_"/>
+        <filesystem path="/usr/share/dbus-1/services/org.bluez.pb_agent.service" label="_"/>
+    </assign>
+
+    <request>
+        <domain name="bt_agent"/>
+    </request>
+</manifest>
diff --git a/mobile/bluetooth-agent.rule b/mobile/bluetooth-agent.rule
new file mode 100644 (file)
index 0000000..00b4a56
--- /dev/null
@@ -0,0 +1,18 @@
+root bt_agent rw---
+_default_ bt_agent rw---
+bt_agent system::vconf_network r----
+bt_agent contacts-service::phonelog rw---
+bt_agent contacts-service::svc rw---
+bt_agent telephony_framework::api_sms r----
+bt_agent telephony_framework::api_sim r----
+bt_agent msg-service::write rw---
+bt_agent msg-service::read rw---
+bt_agent msg-service::db rw---
+bt_agent msg-service rwx--
+bt_agent dbus -w---
+bt_agent sys-assert::core rwxat
+bt_agent system::share rwxat
+bt_agent system::vconf rwxat
+bt_agent device::sys_logging -w---
+bt_agent device::app_logging -w---
+dbus bt_agent rwx--
diff --git a/mobile/hfp-agent/CMakeLists.txt b/mobile/hfp-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f5fc75f
--- /dev/null
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-hfp-agent C)
+
+SET(SRCS bluetooth-hfp-agent.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_hfp_agent
+               REQUIRED
+               dbus-glib-1 vconf appsvc contacts-service2 tapi capi-appfw-application aul)
+
+FOREACH(flag ${pkgs_hfp_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
+               ARGS "--prefix=bt_hfp_agent \\
+               ${CMAKE_CURRENT_SOURCE_DIR}/hfp_agent.xml \\
+               --mode=glib-server \\
+               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_hfp_agent_glue.h")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_hfp_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.hfp_agent.service
+               DESTINATION share/dbus-1/services)
diff --git a/mobile/hfp-agent/bluetooth-hfp-agent.c b/mobile/hfp-agent/bluetooth-hfp-agent.c
new file mode 100644 (file)
index 0000000..6fbce22
--- /dev/null
@@ -0,0 +1,2058 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <signal.h>
+
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+#include <app.h>
+#include <aul.h>
+
+#include "vconf.h"
+#include "vconf-keys.h"
+#include "contacts.h"
+#include "appsvc.h"
+
+#include "bluetooth-hfp-agent.h"
+
+static GMainLoop *gmain_loop = NULL;
+static DBusGConnection *g_connection = NULL;
+static DBusConnection *gconn = NULL;
+static gboolean nrec_status = FALSE;
+
+#define BT_ERROR_INTERNAL "InternalError"
+#define BT_ERROR_NOT_AVAILABLE "NotAvailable"
+#define BT_ERROR_NOT_CONNECTED "NotConnected"
+#define BT_ERROR_BUSY "InProgress"
+#define BT_ERROR_INVALID_PARAM "InvalidArguments"
+#define BT_ERROR_ALREADY_EXSIST "AlreadyExists"
+#define BT_ERROR_ALREADY_CONNECTED "Already Connected"
+#define BT_ERROR_NO_MEMORY "No memory"
+#define BT_ERROR_I_O_ERROR "I/O error"
+#define BT_ERROR_OPERATION_NOT_AVAILABLE "Operation currently not available"
+#define BT_ERROR_BATTERY "Battery error "
+#define BT_ERROR_SIGNAL "Signal error"
+#define BT_ERROR_NO_CALL_LOG "No Call log"
+#define BT_ERROR_INVLAID_DTMF "Invalid dtmf"
+
+#define BLUEZ_SERVICE_NAME "org.bluez"
+#define TELEPHONY_CSD_INTERFACE "org.tizen.telephony.csd"
+#define TELEPHONY_CSD_OBJECT_PATH "/org/tizen/csd"
+#define TELEPHONY_APP_INTERFACE "org.tizen.csd.Call.Instance"
+
+#define BT_HFP_AGENT_SET_PROPERTY "SetProperty"
+
+#define BT_HFP_AGENT_OBJECT "/org/bluez/agent/hfp_agent"
+#define BT_HFP_AGENT_INTERFACE "org.bluez.hfp_agent"
+
+#define BT_SIGNAL_ARRAY_MAX 2
+
+/* AT+CSQ : Returns received signal strength indication.
+     Command response: +CSQ: <rssi>,<ber>
+    <ber> is not supported and has a constant value of 99, included for compatibility reasons.
+*/
+#define BT_SIGNAL_QUALITY_BER 99
+
+/*Length of the string used to send telephone number to app-svc
+   format: tel:<number>
+*/
+#define BT_MAX_TEL_NUM_STRING 20
+
+/**
+ * @brief Outgoing call type status
+ *
+ * 0 : Follow last call log \n
+ * 1 : Voice call \n
+ * 2 : Video call \n
+ */
+#define BT_FOLLOW_CALL_LOG 0
+#define BT_VOICE_CALL 1
+#define BT_VIDEO_CALL 2
+
+/**
+ * @brief The status of making outgoing calls with BT headsets
+ *
+ * 0 : Even when device locked \n
+ * 1 : Only when device unlocked \n
+ */
+#define BT_MO_EVEN_LOCKED 0
+#define BT_MO_ONLY_UNLOCKED 1
+
+#define BT_CHECK_SIGNAL_STRENGTH(rssi) \
+       if (rssi >= VCONFKEY_TELEPHONY_RSSI_4) \
+               rssi = VCONFKEY_TELEPHONY_RSSI_5
+
+typedef struct {
+       GObject parent;
+} BtHfpAgent;
+
+typedef struct {
+       GObjectClass parent;
+} BtHfpAgentClass;
+
+GType bt_hfp_agent_get_type(void);
+
+#define BT_HFP_TYPE_AGENT (bt_hfp_agent_get_type())
+
+#define BT_HFP_AGENT(object)(G_TYPE_CHECK_INSTANCE_CAST((object), \
+                       BT_HFP_TYPE_AGENT , BtHfpAgent))
+
+#define BT_HFP_AGENT_CLASS(klass)(G_TYPE_CHECK_CLASS_CAST((klass), \
+                       BT_HFP_TYPE_AGENT , BtHfpAgentClass))
+
+#define BT_IS_HFP_AGENT(object)(G_TYPE_CHECK_INSTANCE_TYPE((object), \
+                       BT_HFP_TYPE_AGENT))
+
+#define BT_IS_HFP_AGENT_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), \
+                       BT_HFP_TYPE_AGENT))
+
+#define BT_HFP_AGENT_GET_CLASS(obj)(G_TYPE_INSTANCE_GET_CLASS((obj), \
+                       BT_HFP_TYPE_AGENT , BtHfpAgentClass))
+
+G_DEFINE_TYPE(BtHfpAgent, bt_hfp_agent, G_TYPE_OBJECT)
+
+static gboolean bt_hfp_agent_register_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_unregister_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_incoming_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_outgoing_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_change_call_status(BtHfpAgent *agent,
+                               const gchar *path, gint status, gint call_id,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_answer_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_release_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_reject_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_threeway_call(BtHfpAgent *agent, gint call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent,
+                               const gchar *number, guint flags,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_dial_memory(BtHfpAgent *agent, gint location,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_send_dtmf(BtHfpAgent *agent, const gchar *dtmf,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_voice_dial(BtHfpAgent *agent, gboolean activate,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_battery_status(BtHfpAgent *object,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_signal_quality(BtHfpAgent *object,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_properties(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_operator_name(BtHfpAgent *object,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_nrec_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_connection_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context);
+
+static void __bt_hfp_agent_reg_sim_event(TapiHandle *handle, void *user_data);
+
+static void __bt_hfp_agent_dereg_sim_event(TapiHandle *handle);
+
+#include "bluetooth_hfp_agent_glue.h"
+
+static void bt_hfp_agent_init(BtHfpAgent *obj)
+{
+       DBG("\n");
+
+       g_assert(obj != NULL);
+}
+
+static void bt_hfp_agent_finalize(GObject *obj)
+{
+       DBG("\n");
+
+       G_OBJECT_CLASS(bt_hfp_agent_parent_class)->finalize(obj);
+}
+
+static void bt_hfp_agent_class_init(BtHfpAgentClass *klass)
+{
+       DBG("\n");
+
+       GObjectClass *object_class = (GObjectClass *)klass;
+
+       g_assert(klass != NULL);
+
+       object_class->finalize = bt_hfp_agent_finalize;
+
+       dbus_g_object_type_install_info(BT_HFP_TYPE_AGENT,
+                                       &dbus_glib_bt_hfp_agent_object_info);
+}
+
+static GQuark __bt_hfp_agent_error_quark(void)
+{
+       DBG("\n");
+
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string("agent");
+
+       return quark;
+}
+
+static GError *__bt_hfp_agent_set_error(bt_hfp_agent_error_t error)
+{
+       ERR("error[%d]\n", error);
+
+       switch (error) {
+       case BT_HFP_AGENT_ERROR_NOT_AVAILABLE:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_NOT_AVAILABLE);
+       case BT_HFP_AGENT_ERROR_NOT_CONNECTED:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_NOT_CONNECTED);
+       case BT_HFP_AGENT_ERROR_BUSY:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_BUSY);
+       case BT_HFP_AGENT_ERROR_INVALID_PARAM:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_INVALID_PARAM);
+       case BT_HFP_AGENT_ERROR_ALREADY_EXSIST:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_ALREADY_EXSIST);
+       case BT_HFP_AGENT_ERROR_ALREADY_CONNECTED:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_ALREADY_CONNECTED);
+       case BT_HFP_AGENT_ERROR_NO_MEMORY:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_NO_MEMORY);
+       case BT_HFP_AGENT_ERROR_I_O_ERROR:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_I_O_ERROR);
+       case BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_AVAILABLE);
+       case BT_HFP_AGENT_ERROR_BATTERY_STATUS:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_BATTERY);
+       case BT_HFP_AGENT_ERROR_SIGNAL_STATUS:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_SIGNAL);
+       case BT_HFP_AGENT_ERROR_NO_CALL_LOGS:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_NO_CALL_LOG);
+       case BT_HFP_AGENT_ERROR_INTERNAL:
+       default:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_INTERNAL);
+       }
+}
+
+static int __bt_hfp_agent_get_error(const char *error_message)
+{
+       if (error_message == NULL) {
+               DBG("Error message NULL\n");
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       ERR("Error message = %s \n", error_message);
+
+       if (g_strcmp0(error_message, BT_ERROR_NOT_AVAILABLE) == 0)
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       else if (g_strcmp0(error_message, BT_ERROR_NOT_CONNECTED) == 0)
+               return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+       else if (g_strcmp0(error_message, BT_ERROR_BUSY) == 0)
+               return BT_HFP_AGENT_ERROR_BUSY;
+       else if (g_strcmp0(error_message, BT_ERROR_INVALID_PARAM) == 0)
+               return BT_HFP_AGENT_ERROR_INVALID_PARAM;
+       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_EXSIST) == 0)
+               return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
+       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_CONNECTED) == 0)
+               return BT_HFP_AGENT_ERROR_ALREADY_CONNECTED;
+       else if (g_strcmp0(error_message, BT_ERROR_NO_MEMORY) == 0)
+               return BT_HFP_AGENT_ERROR_NO_MEMORY;
+       else if (g_strcmp0(error_message, BT_ERROR_I_O_ERROR) == 0)
+               return BT_HFP_AGENT_ERROR_I_O_ERROR;
+       else if (g_strcmp0(error_message, BT_ERROR_OPERATION_NOT_AVAILABLE) == 0)
+               return BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE;
+       else if (g_strcmp0(error_message, BT_ERROR_INVLAID_DTMF) == 0)
+               return BT_HFP_AGENT_ERROR_INVALID_DTMF;
+       else
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+}
+
+static int __bt_hfp_agent_dbus_method_send(const char *service,
+                               const char *path, const char *interface,
+                               const char *method, gboolean response,
+                               int type, ...)
+{
+       DBusMessage *msg;
+       DBusMessage *reply;
+       DBusError err;
+       va_list args;
+       int error;
+
+       msg = dbus_message_new_method_call(service, path, interface,
+                                                               method);
+       if (!msg) {
+               ERR("Unable to allocate new D-Bus %s message \n", method);
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       va_start(args, type);
+
+       if (!dbus_message_append_args_valist(msg, type, args)) {
+               dbus_message_unref(msg);
+               va_end(args);
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       va_end(args);
+
+       dbus_error_init(&err);
+
+       if (response) {
+               reply = dbus_connection_send_with_reply_and_block(gconn,
+                                                       msg, -1, &err);
+               dbus_message_unref(msg);
+
+               if (!reply) {
+                       ERR("Error returned in method call\n");
+                       if (dbus_error_is_set(&err)) {
+                               error = __bt_hfp_agent_get_error(err.message);
+                               dbus_error_free(&err);
+                               return error;
+                       } else {
+                               ERR("Error is not set\n");
+                               return BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+               }
+               dbus_message_unref(reply);
+       } else {
+               dbus_connection_send(gconn, msg, NULL);
+               dbus_message_unref(msg);
+       }
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+/**
+ * [Org.Hfp.App.Interface] interface functions
+ */
+static gboolean bt_hfp_agent_register_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context)
+{
+       gboolean flag = TRUE;
+       char *sender;
+       GError *error;
+       int ret;
+
+       if (path == NULL) {
+               ERR("Invalid Argument path\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "RegisterTelephonyAgent", TRUE,
+                               DBUS_TYPE_BOOLEAN, &flag,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_unregister_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context)
+{
+       gboolean flag = FALSE;
+       char *sender;
+       GError *error;
+       int ret;
+
+       if (path == NULL) {
+               ERR("Invalid Argument path\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "RegisterTelephonyAgent", TRUE,
+                               DBUS_TYPE_BOOLEAN, &flag,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_incoming_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       char *sender;
+       int ret;
+
+       if (path == NULL || number == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+       DBG("Call id = %d\n", call_id);
+       DBG_SECURE("Phone number = %s\n", number);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "Incoming", TRUE,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &number,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_STRING, &sender,
+                               DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_outgoing_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       char *sender;
+       int ret;
+
+       if (path == NULL || number == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+       DBG("Call id = %d\n", call_id);
+       DBG_SECURE("Phone number = %s\n", number);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "Outgoing", TRUE,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &number,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_STRING, &sender,
+                               DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_change_call_status(BtHfpAgent *agent,
+                               const gchar *path, gint status, gint call_id,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       char *sender;
+       int ret;
+
+       if (path == NULL) {
+               ERR("Invalid Argument path\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+       DBG("Call id[%d] :: Status[%d]\n", call_id, status);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "SetCallStatus", TRUE,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_UINT32, &status,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_STRING, &sender,
+                               DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+void __bt_append_entry(DBusMessageIter *iter,
+                       const char *key, int type, void *val)
+{
+       DBusMessageIter entry;
+       DBusMessageIter value;
+       const char *str;
+       char signal[BT_SIGNAL_ARRAY_MAX] = { type, '\0' };
+
+       if (type == DBUS_TYPE_STRING) {
+               str = *((const char **) val);
+               if (str == NULL) {
+                       return;
+               }
+       }
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+       dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+       dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+                                               signal, &value);
+       dbus_message_iter_append_basic(&value, type, val);
+       dbus_message_iter_close_container(&entry, &value);
+       dbus_message_iter_close_container(iter, &entry);
+}
+
+static gboolean bt_hfp_agent_get_properties(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context)
+{
+       DBusMessage *reply;
+       DBusMessageIter iter;
+       DBusMessageIter dict;
+       GError *error;
+
+       reply = dbus_g_method_get_reply(context);
+       if (!reply) {
+               ERR("Internal error\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+                       DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                       DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+                       DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+       DBG("NREC status [%d]\n", nrec_status);
+       __bt_append_entry(&dict, "nrec", DBUS_TYPE_BOOLEAN, &nrec_status);
+       dbus_message_iter_close_container(&iter, &dict);
+       dbus_g_method_send_reply(context, reply);
+
+       return TRUE;
+}
+
+
+/**
+ * [Org.Hfp.Bluez.Interface] interface functions
+ */
+static gboolean bt_hfp_agent_answer_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Answer", FALSE,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_release_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Release", FALSE,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_reject_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Reject", FALSE,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_threeway_call(BtHfpAgent *agent, gint value,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Value = %d", value);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Threeway", TRUE,
+                               DBUS_TYPE_UINT32, &value,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean __bt_is_phone_locked(int *phone_lock_state)
+{
+       int ret;
+
+       if (NULL == phone_lock_state)
+               return FALSE;
+
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, phone_lock_state);
+       if (ret != 0) {
+               ERR("Failed to read  [%s]\n", VCONFKEY_IDLE_LOCK_STATE);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_get_outgoing_callapp_type(int *callapp_type)
+{
+       int ret;
+
+       if (NULL == callapp_type)
+               return FALSE;
+
+       ret = vconf_get_int(VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, callapp_type);
+       if (ret != 0) {
+               ERR("Failed to read  [%s]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT);
+               return FALSE;
+       }
+
+       DBG(" [%s] = [%d]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, *callapp_type);
+
+       return TRUE;
+}
+
+static gboolean __bt_get_outgoing_call_condition(int *condition)
+{
+       int ret;
+
+       if (NULL == condition)
+               return FALSE;
+
+       ret = vconf_get_int(VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT, condition);
+       if (ret != 0) {
+               ERR("Failed to read  [%s]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_make_call(const char *number)
+{
+       bundle *b;
+       char telnum[BT_MAX_TEL_NUM_STRING];
+       int ret;
+
+       b = bundle_create();
+       if (NULL == b)
+               return FALSE;
+
+       ret = appsvc_set_operation(b, APPSVC_OPERATION_CALL);
+       if(ret < 0) {
+               ERR("Failed to success appsvc_set_operation: %d ", ret);
+               goto fail;
+       }
+       snprintf(telnum, sizeof(telnum), "tel:%s", number);
+
+       ret = appsvc_set_uri(b, telnum);
+       if(ret < 0) {
+               ERR("Failed to success appsvc_set_uri: %d ", ret);
+               goto fail;
+       }
+
+       ret = appsvc_add_data(b, "ctindex", "-1");
+       if(ret < 0) {
+               ERR("Failed to success appsvc_set_uri: %d ", ret);
+               goto fail;
+       }
+
+       ret = appsvc_run_service(b, 0, NULL, NULL);
+       if(ret < 0) {
+               ERR("callee failed: %d ", ret);
+               goto fail;
+       }
+
+       bundle_free(b);
+
+       return TRUE;
+fail:
+       bundle_free(b);
+
+       return FALSE;
+}
+
+static gboolean __bt_hfp_agent_make_video_call(const char *mo_number)
+{
+       bundle *kb;
+
+       kb = bundle_create();
+       if (NULL == kb)
+               return FALSE;
+
+       bundle_add(kb, "KEY_CALL_TYPE", "MO");
+       bundle_add(kb, "number", mo_number);
+       aul_launch_app("org.tizen.vtmain", kb);
+       bundle_free(kb);
+
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int error_code = BT_HFP_AGENT_ERROR_NONE;
+       char *last_number = NULL;
+       int log_type;
+       int callapp_type;
+       int phone_lock_state;
+       int condition;
+       contacts_list_h list = NULL;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_record_h record = NULL;
+       unsigned int projections[] = {
+               _contacts_phone_log.address,
+               _contacts_phone_log.log_type,
+       };
+
+       DBG("\n");
+
+       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_connect2 failed \n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       if (filter == NULL)
+               goto done;
+
+       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               CONTACTS_PLOG_TYPE_VOICE_OUTGOING) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_int failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_operator failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_int failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       contacts_query_create(_contacts_phone_log._uri, &query);
+
+       if (query == NULL)
+               goto done;
+
+       contacts_query_set_filter(query, filter);
+
+       if (contacts_query_set_projection(query, projections,
+                               sizeof(projections)/sizeof(unsigned int)) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_query_set_projection failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_query_set_sort(query, _contacts_phone_log.log_time, false) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_query_set_sort failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_db_get_records_with_query(query, 0, 1, &list)  !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_db_get_records_with_query failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_first(list)  != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_list_first failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_get_current_record_p(list, &record)  !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (record == NULL)
+               goto done;
+
+       if (contacts_record_get_str(record, _contacts_phone_log.address,
+                               &last_number)!= CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (last_number == NULL) {
+               ERR("No last number \n");
+               error_code = BT_HFP_AGENT_ERROR_NO_CALL_LOGS;
+               goto done;
+       }
+
+       if (!__bt_is_phone_locked(&phone_lock_state)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (!__bt_get_outgoing_call_condition(&condition)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (condition == BT_MO_ONLY_UNLOCKED &&
+                       phone_lock_state == VCONFKEY_IDLE_LOCK) {
+               ERR("Call failed. Phone is locked.\n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       switch (callapp_type) {
+               case BT_VOICE_CALL:
+                       if (!__bt_hfp_agent_make_call(last_number)) {
+                               ERR("Problem launching application \n");
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+                       break;
+               case BT_VIDEO_CALL:
+                       if(!__bt_hfp_agent_make_video_call(last_number)) {
+                               ERR("Problem launching application \n");
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+                       break;
+               case BT_FOLLOW_CALL_LOG:
+                       if(contacts_record_get_int(record,
+                               _contacts_phone_log.log_type,
+                               &log_type) != CONTACTS_ERROR_NONE) {
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                               break;
+                       }
+                       if (log_type == CONTACTS_PLOG_TYPE_VOICE_OUTGOING) {
+                               if (!__bt_hfp_agent_make_call(last_number)) {
+                                       ERR("Problem launching application \n");
+                                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                               }
+                       }
+                       else if(log_type == CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) {
+                               if(!__bt_hfp_agent_make_video_call(last_number)) {
+                                       ERR("Problem launching application \n");
+                                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                               }
+                       } else {
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+                       break;
+               default:
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       break;
+       }
+
+done:
+       if (list != NULL)
+               contacts_list_destroy(list, TRUE);
+
+       if (filter != NULL)
+               contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       contacts_disconnect2();
+
+       if (last_number != NULL)
+               g_free(last_number);
+
+       if (error_code == BT_HFP_AGENT_ERROR_NONE) {
+               dbus_g_method_return(context);
+               return TRUE;
+       } else {
+               error = __bt_hfp_agent_set_error(error_code);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+}
+
+static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent,
+                               const gchar *number, guint flags,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int error_code;
+       int callapp_type;
+       int phone_lock_state;
+       int condition;
+
+       if (number == NULL) {
+               ERR("Invalid Argument\n");
+               error_code = BT_HFP_AGENT_ERROR_INVALID_PARAM;
+               goto fail;
+       }
+
+       DBG_SECURE("Number = %s \n", number);
+       DBG("flags = %d", flags);
+
+       if (!__bt_is_phone_locked(&phone_lock_state)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (!__bt_get_outgoing_call_condition(&condition)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (condition == BT_MO_ONLY_UNLOCKED &&
+                       phone_lock_state == VCONFKEY_IDLE_LOCK) {
+               ERR("Call failed. Phone is locked.\n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (callapp_type == BT_VIDEO_CALL) {
+               if(!__bt_hfp_agent_make_video_call(number)) {
+                       ERR("Problem launching application \n");
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+       } else {
+               if (!__bt_hfp_agent_make_call(number)) {
+                       ERR("Problem launching application \n");
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+fail:
+       error = __bt_hfp_agent_set_error(error_code);
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bt_hfp_agent_dial_memory(BtHfpAgent *agent, gint location,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int error_code = BT_HFP_AGENT_ERROR_NONE;
+       char *number = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_query_h query = NULL;
+       contacts_list_h list = NULL;
+       contacts_record_h record = NULL;
+       unsigned int projections[] = {
+               _contacts_speeddial.number,
+       };
+
+       DBG("location = %d \n", location);
+
+       /*Get number from contacts location*/
+       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_connect2 failed \n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       contacts_filter_create(_contacts_speeddial._uri, &filter);
+
+       if (filter == NULL)
+               goto done;
+
+       if (contacts_filter_add_int(filter, _contacts_speeddial.speeddial_number,
+                               CONTACTS_MATCH_EQUAL, location) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       contacts_query_create(_contacts_speeddial._uri, &query);
+
+       if (query == NULL)
+               goto done;
+
+       contacts_query_set_filter(query, filter);
+
+       if (contacts_query_set_projection(query, projections,
+                               sizeof(projections)/sizeof(unsigned int)) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_db_get_records_with_query(query, 0, 1, &list) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_first(list) != CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_get_current_record_p(list, &record) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (record == NULL)
+               goto done;
+
+       if (contacts_record_get_str(record, _contacts_speeddial.number,
+                                                       &number)!= CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (number == NULL) {
+               ERR("No number at the location \n");
+               error_code = BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX;
+               goto done;
+       }
+
+       DBG_SECURE("number %s\n", number);
+
+       /*Make Voice call*/
+       if (!__bt_hfp_agent_make_call(number)) {
+               ERR("Problem launching application \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       g_free(number);
+done:
+       if (list != NULL)
+               contacts_list_destroy(list, TRUE);
+
+       if (filter != NULL)
+               contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       contacts_disconnect2();
+
+       if (error_code == BT_HFP_AGENT_ERROR_NONE) {
+               dbus_g_method_return(context);
+               return TRUE;
+       } else {
+               error = __bt_hfp_agent_set_error(error_code);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+}
+
+static gboolean bt_hfp_agent_send_dtmf(BtHfpAgent *agent, const gchar *dtmf,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int ret;
+
+       if (dtmf == NULL || path == NULL || sender == NULL) {
+               ERR("Invalid Argument\n");
+               error = __bt_hfp_agent_set_error(
+                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG_SECURE("Dtmf = %s \n", dtmf);
+       DBG("Application path = %s \n", path);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "SendDtmf", FALSE,
+                               DBUS_TYPE_STRING, &dtmf,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       /*App Selector code here needed*/
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_launch_voice_dial(gboolean activate)
+{
+       service_h service = NULL;
+
+       service_create(&service);
+
+       if (service == NULL) {
+               ERR("Service create failed");
+               return FALSE;
+       }
+
+       service_set_package(service, "org.tizen.svoice");
+       service_set_operation(service, SERVICE_OPERATION_DEFAULT);
+       service_add_extra_data(service, "domain", "bt_headset");
+
+       if (!activate)
+               service_add_extra_data(service, "action_type", "deactivate");
+
+       if (service_send_launch_request(service, NULL, NULL) !=
+                                               SERVICE_ERROR_NONE) {
+               ERR("launch failed");
+               service_destroy(service);
+               return FALSE;
+       }
+
+       service_destroy(service);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_voice_dial(BtHfpAgent *agent, gboolean activate,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+
+       DBG("Activate = %d \n", activate);
+
+       if (__bt_hfp_agent_launch_voice_dial(activate) != TRUE) {
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_APPLICATION);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_get_battery_status(BtHfpAgent *object,
+                               DBusGMethodInvocation *context)
+{
+       gint battery_chrg_status;
+       gint battery_capacity;
+       GError *error;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
+                                               &battery_chrg_status)) {
+               ERR("VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW failed\n");
+               goto fail;
+       }
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
+                                               &battery_capacity)) {
+               ERR("VCONFKEY_SYSMAN_BATTERY_CAPACITY failed\n");
+               goto fail;
+       }
+
+       DBG("Status:[%d]  Capacity:[%d]\n", battery_chrg_status, battery_capacity);
+
+       dbus_g_method_return(context, battery_chrg_status, battery_capacity);
+       return TRUE;
+
+fail:
+       error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_BATTERY_STATUS);
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bt_hfp_agent_get_signal_quality(BtHfpAgent *object,
+                                       DBusGMethodInvocation *context)
+{
+       gint rssi;
+       GError *error;
+
+       if (vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi)) {
+               ERR("VCONFKEY_TELEPHONY_RSSI failed\n");
+               goto fail;
+       }
+
+       BT_CHECK_SIGNAL_STRENGTH(rssi);
+       DBG("RSSI : %d \n", rssi);
+
+       dbus_g_method_return(context, rssi, BT_SIGNAL_QUALITY_BER);
+       return TRUE;
+fail:
+       error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_SIGNAL_STATUS);
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bt_hfp_agent_get_operator_name(BtHfpAgent *object,
+                               DBusGMethodInvocation *context)
+{
+       char *operator_name;
+       GError *error;
+
+       operator_name = vconf_get_str(VCONFKEY_TELEPHONY_NWNAME);
+       if (NULL == operator_name) {
+               ERR("vconf_get_str failed \n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       if (!g_utf8_validate(operator_name, -1, NULL)) {
+               free(operator_name);
+               operator_name = strdup("Unknown");
+       }
+
+       DBG_SECURE("operator_name  = [%s] \n", operator_name);
+
+       dbus_g_method_return(context, operator_name);
+       free(operator_name);
+
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_nrec_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context)
+{
+       DBusMessage *signal;
+
+       DBG("NREC status = %d \n", status);
+
+       if (status)
+               nrec_status = FALSE;
+       else
+               nrec_status = TRUE;
+
+       dbus_g_method_return(context);
+
+       /*Emit NREC Status change signal with value*/
+       signal = dbus_message_new_signal(BT_HFP_AGENT_OBJECT,
+                                       BT_HFP_AGENT_INTERFACE,
+                                       "NrecStatusChanged");
+       if (!signal) {
+               ERR("Signal is NULL\n");
+               return FALSE;
+       }
+
+       if (!dbus_message_append_args(signal,
+                               DBUS_TYPE_BOOLEAN, &nrec_status,
+                               DBUS_TYPE_INVALID)) {
+               ERR("Signal appending failed\n");
+               dbus_message_unref(signal);
+               return FALSE;
+       }
+
+       dbus_connection_send(gconn, signal, NULL);
+       dbus_message_unref(signal);
+       return TRUE;
+}
+
+static void __bt_hfp_agent_append_variant(DBusMessageIter *iter,
+                       int type, void *val)
+{
+       DBusMessageIter value_iter;
+       const char *variant;
+
+       switch (type) {
+       case DBUS_TYPE_BOOLEAN:
+               variant = DBUS_TYPE_BOOLEAN_AS_STRING;
+               break;
+       case DBUS_TYPE_STRING:
+               variant = DBUS_TYPE_STRING_AS_STRING;
+               break;
+       case DBUS_TYPE_BYTE:
+               variant = DBUS_TYPE_BYTE_AS_STRING;
+               break;
+       case DBUS_TYPE_UINT16:
+               variant = DBUS_TYPE_UINT16_AS_STRING;
+               break;
+       case DBUS_TYPE_UINT32:
+               variant = DBUS_TYPE_UINT32_AS_STRING;
+               break;
+       case DBUS_TYPE_INT16:
+               variant = DBUS_TYPE_INT16_AS_STRING;
+               break;
+       case DBUS_TYPE_INT32:
+               variant = DBUS_TYPE_INT32_AS_STRING;
+               break;
+       case DBUS_TYPE_OBJECT_PATH:
+               variant = DBUS_TYPE_OBJECT_PATH_AS_STRING;
+               break;
+       default:
+               variant = DBUS_TYPE_VARIANT_AS_STRING;
+               break;
+       }
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, variant,
+                                                       &value_iter);
+       dbus_message_iter_append_basic(&value_iter, type, val);
+       dbus_message_iter_close_container(iter, &value_iter);
+}
+
+static gboolean __bt_hfp_agent_dbus_method_variant_send(const char *path,
+               const char *interface, const char *method, const char *name,
+               int type, void *value)
+{
+       DBusMessage *msg;
+       DBusMessage *reply;
+       DBusError err;
+       DBusMessageIter iter;
+
+       msg = dbus_message_new_method_call(BLUEZ_SERVICE_NAME,
+                       path, interface, method);
+
+       if (!msg) {
+               ERR("Unable to allocate new D-Bus %s message", method);
+               return FALSE;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
+
+       __bt_hfp_agent_append_variant(&iter, type, value);
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(gconn,
+                               msg, -1, &err);
+
+       dbus_message_unref(msg);
+
+       if (!reply) {
+               if (dbus_error_is_set(&err)) {
+                       if (err.message != NULL) {
+                               ERR("Error message = %s\n", err.message);
+                       }
+                       dbus_error_free(&err);
+               }
+               return FALSE;
+       }
+
+       dbus_message_unref(reply);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_registration_status_changed(
+               bt_hfp_agent_network_registration_status_t status)
+{
+       const char *property = g_strdup("RegistrationChanged");
+
+       DBG("status = [%d]", status);
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property, DBUS_TYPE_BYTE, &status)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_subscriber_number_changed(
+                                                       const char *number)
+{
+       const char *property = g_strdup("SubscriberNumberChanged");
+
+       DBG_SECURE("number = [%s]", number);
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property,
+                       DBUS_TYPE_STRING, &number)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_signal_bar_changed(int signal_bar)
+{
+       const char *property = g_strdup("SignalBarsChanged");
+
+       DBG("Level = [%d]", signal_bar);
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property, DBUS_TYPE_INT32, &signal_bar)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_battery_level_changed(int battery_level)
+{
+       const char *property = g_strdup("BatteryBarsChanged");
+       int battery_status;
+
+       DBG("Level = [%d] \n", battery_level);
+
+       /* We need to send battery status ranging from 0-5 */
+       if (battery_level < 5)
+                battery_status = 0;
+       else if (battery_level >= 100)
+               battery_status = 5;
+       else
+               battery_status = battery_level / 20 + 1;
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property,
+                       DBUS_TYPE_INT32, &battery_status)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static void __bt_hfp_agent_send_battery_level(void)
+{
+       int ret;
+       int batt;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &batt);
+       if (ret != 0) {
+               ERR("vconf_get_int failed err = %d \n", ret);
+               return;
+       }
+
+       __bt_hfp_agent_send_battery_level_changed(batt);
+}
+
+static void __bt_hfp_agent_send_signal_status(void)
+{
+       int ret;
+       int signal_level;
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &signal_level);
+       if (ret != 0) {
+               ERR("vconf_get_int failed err = %d \n", ret);
+               return;
+       }
+
+       BT_CHECK_SIGNAL_STRENGTH(signal_level);
+       __bt_hfp_agent_send_signal_bar_changed(signal_level);
+}
+
+static void __bt_hfp_agent_network_send( int service, int roam_status)
+{
+       int ret;
+       bt_hfp_agent_network_registration_status_t network_service;
+
+       switch (service) {
+       case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
+       case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
+       case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
+               service = 0;
+               break;
+       default:
+               service = 1;
+               break;
+       }
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
+       if (ret != 0) {
+               ERR("Get roaming status failed err = %d\n", ret);
+               return;
+       }
+
+       if (roam_status == 0 && service == 1)
+               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_HOME;
+       else if (roam_status == 1 && service == 1)
+               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_ROAMING;
+       else
+               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_UNKOWN;
+
+       __bt_hfp_agent_send_registration_status_changed(network_service);
+}
+
+static void __bt_hfp_agent_send_network_status(void)
+{
+       int ret;
+       int roam_status;
+       int service;
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
+       if (ret != 0) {
+               ERR("vconf_get_int failed for \n");
+               return;
+       }
+
+       DBG("roam_status  = [%d] \n", roam_status);
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &service);
+       if (ret != 0) {
+               ERR("vconf_get_int failed\n");
+               return;
+       }
+
+       DBG("service  = [%d] \n", service);
+
+       __bt_hfp_agent_network_send(service, roam_status);
+}
+
+static void __bt_hfp_agent_send_vconf_values(void)
+{
+       __bt_hfp_agent_send_battery_level();
+       __bt_hfp_agent_send_signal_status();
+       __bt_hfp_agent_send_network_status();
+}
+
+static void __bt_hfp_agent_battery_status_cb(keynode_t *node)
+{
+       int batt = vconf_keynode_get_int(node);
+
+       __bt_hfp_agent_send_battery_level_changed(batt);
+}
+
+static void __bt_hfp_agent_network_signal_status_cb(keynode_t *node)
+{
+       int signal_bar = vconf_keynode_get_int(node);
+
+       BT_CHECK_SIGNAL_STRENGTH(signal_bar);
+       __bt_hfp_agent_send_signal_bar_changed(signal_bar);
+}
+
+static void __bt_hfp_agent_network_register_status_cb(keynode_t *node)
+{
+       int service = vconf_keynode_get_int(node);
+       int roam_status;
+       int ret;
+
+       DBG("Current Signal Level = [%d] \n", service);
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
+       if (ret != 0) {
+               ERR("Get roaming status failed err = %d\n", ret);
+               return;
+       }
+
+       __bt_hfp_agent_network_send(service, roam_status);
+}
+
+static void __bt_hfp_agent_subscribe_vconf_updates(void)
+{
+       int ret;
+
+       DBG("\n");
+
+       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
+                               (void *)__bt_hfp_agent_battery_status_cb, NULL);
+       if (0 != ret) {
+               ERR("Subsrciption to battery status failed err =  [%d]\n", ret);
+       }
+
+       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_RSSI,
+                       (void *)__bt_hfp_agent_network_signal_status_cb, NULL);
+       if (0 != ret) {
+               ERR("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
+       }
+
+       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
+                       (void *)__bt_hfp_agent_network_register_status_cb, NULL);
+       if (0 != ret) {
+               ERR("Subsrciption to network failed err =  [%d]\n", ret);
+       }
+}
+
+static void __bt_hfp_agent_release_vconf_updates(void)
+{
+       int ret;
+
+       DBG("\n");
+
+       ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
+                       (vconf_callback_fn)__bt_hfp_agent_battery_status_cb);
+       if (0 != ret) {
+               ERR("vconf_ignore_key_changed failed\n");
+       }
+
+       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_RSSI,
+               (vconf_callback_fn)__bt_hfp_agent_network_signal_status_cb);
+       if (0 != ret) {
+               ERR("vconf_ignore_key_changed failed\n");
+       }
+
+       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
+               (vconf_callback_fn)__bt_hfp_agent_network_register_status_cb);
+       if (0 != ret) {
+               ERR("vconf_ignore_key_changed failed\n");
+       }
+}
+
+static gboolean bt_hfp_agent_connection_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context)
+{
+       DBG("HF device is %s\n", status ? "Connected" : "Disconnected");
+
+       if (status) {
+               __bt_hfp_agent_send_vconf_values();
+               __bt_hfp_agent_subscribe_vconf_updates();
+       } else {
+               __bt_hfp_agent_release_vconf_updates();
+               nrec_status = FALSE;
+       }
+
+       dbus_g_method_return(context);
+
+       return TRUE;
+}
+
+
+static void __bt_hfp_agent_dbus_init(BtHfpAgent *agent)
+{
+       GError *error = NULL;
+       DBusGProxy *bus_proxy = NULL;
+       guint result;
+
+       g_connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+       if (error != NULL) {
+               ERR("Failed connection to system bus[%s] \n", error->message);
+               g_error_free(error);
+               return;
+       }
+
+       bus_proxy = dbus_g_proxy_new_for_name(g_connection,
+                                       DBUS_SERVICE_DBUS,
+                                       DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+       if (bus_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
+                       BT_HFP_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID,
+                       G_TYPE_UINT, &result, G_TYPE_INVALID)) {
+               if (error != NULL) {
+                       ERR("RequestName RPC failed[%s]\n", error->message);
+                       g_error_free(error);
+               }
+
+               g_object_unref(bus_proxy);
+               return;
+       }
+
+       DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+               ERR("Failed to get the primary well-known name.\n");
+               g_object_unref(bus_proxy);
+               return;
+       }
+
+       g_object_unref(bus_proxy);
+
+       dbus_g_connection_register_g_object(g_connection,
+               BT_HFP_SERVICE_OBJECT_PATH, G_OBJECT(agent));
+
+       gconn = dbus_g_connection_get_connection(g_connection);
+       if (gconn == NULL) {
+               ERR("Failed to get connection \n");
+               return;
+       }
+}
+
+static void  __bt_hfp_agent_tel_cb(TapiHandle *handle,
+                               int result,
+                               void *data,
+                               void *user_data)
+{
+       TelSimMsisdnList_t *number;
+       gchar *subscriber_number;
+
+       if (result == TAPI_API_SIM_LOCKED ||
+               result == TAPI_API_SIM_NOT_INITIALIZED ||
+               result == TAPI_API_SERVICE_NOT_READY) {
+               DBG("initializing the tapi event for SIM status \n");
+               __bt_hfp_agent_reg_sim_event(handle, user_data);
+               return;
+       }
+
+       if (data == NULL)
+       {
+               ERR("data == NULL \n");
+               return;
+       }
+
+       number = (TelSimMsisdnList_t *)data;
+       subscriber_number = g_strdup(number->list[0].num);
+       __bt_hfp_agent_send_subscriber_number_changed(subscriber_number);
+       g_free(subscriber_number);
+}
+
+
+static void __bt_hfp_agent_on_noti_sim_status (TapiHandle *handle,
+               const char *noti_id, void *data, void *user_data)
+{
+       TelSimCardStatus_t *status = data;
+       int tapi_result;
+
+       DBG("event TAPI_NOTI_SIM_STATUS received!! status[%d]", *status);
+
+       if (*status == TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
+               __bt_hfp_agent_dereg_sim_event(handle);
+               tapi_result = tel_get_sim_msisdn(handle, __bt_hfp_agent_tel_cb,
+                                       user_data);
+               if (tapi_result != TAPI_API_SUCCESS)
+                       ERR("Fail to get sim info: %d", tapi_result);
+       }
+}
+
+static void __bt_hfp_agent_reg_sim_event (TapiHandle *handle, void *user_data)
+{
+       int ret;
+       ret = tel_register_noti_event(handle, TAPI_NOTI_SIM_STATUS,
+               __bt_hfp_agent_on_noti_sim_status, user_data);
+
+       if (ret != TAPI_API_SUCCESS)
+               ERR("event register failed(%d)", ret);
+}
+
+static void __bt_hfp_agent_dereg_sim_event (TapiHandle *handle)
+{
+       int ret;
+       ret = tel_deregister_noti_event(handle, TAPI_NOTI_SIM_STATUS);
+
+       if (ret != TAPI_API_SUCCESS)
+               ERR("event deregister failed(%d)", ret);
+}
+
+static void __bt_hfp_agent_sigterm_handler(int signo)
+{
+       if (gmain_loop) {
+               g_main_loop_quit(gmain_loop);
+       } else {
+               DBG("Terminating HFP agent");
+               exit(0);
+       }
+}
+
+int main(void)
+{
+       TapiHandle *handle;
+       BtHfpAgent *bt_hfp_obj = NULL;
+       struct sigaction sa;
+       int tapi_result;
+
+       DBG("Starting Bluetooth HFP agent");
+
+       g_type_init();
+
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_flags = SA_NOCLDSTOP;
+       sa.sa_handler = __bt_hfp_agent_sigterm_handler;
+       sigaction(SIGTERM, &sa, NULL);
+       sigaction(SIGINT, &sa, NULL);
+
+       gmain_loop = g_main_loop_new(NULL, FALSE);
+
+       if (gmain_loop == NULL) {
+               ERR("GMainLoop create failed \n");
+               return EXIT_FAILURE;
+       }
+
+       bt_hfp_obj = g_object_new(BT_HFP_TYPE_AGENT, NULL);
+
+       handle = tel_init(NULL);
+       tapi_result = tel_get_sim_msisdn(handle, __bt_hfp_agent_tel_cb,
+                                       bt_hfp_obj);
+
+       if(tapi_result != TAPI_API_SUCCESS)
+               ERR("Fail to get sim info: %d", tapi_result);
+
+       __bt_hfp_agent_dbus_init(bt_hfp_obj);
+
+       g_main_loop_run(gmain_loop);
+
+       tel_deinit(handle);
+
+       if (bt_hfp_obj) {
+               dbus_g_connection_unregister_g_object(g_connection,
+                                               G_OBJECT(bt_hfp_obj));
+               g_object_unref(bt_hfp_obj);
+       }
+
+       if (g_connection)
+               dbus_g_connection_unref(g_connection);
+
+       if (gmain_loop)
+               g_main_loop_unref(gmain_loop);
+
+       DBG("Terminating Bluetooth HFP agent");
+       return 0;
+}
diff --git a/mobile/hfp-agent/bluetooth-hfp-agent.h b/mobile/hfp-agent/bluetooth-hfp-agent.h
new file mode 100644 (file)
index 0000000..3d9999a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_HFP_AGENT_H_
+#define __DEF_BT_HFP_AGENT_H_
+
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+
+#define BT_HFP_AGENT_ERROR (__bt_hfp_agent_error_quark())
+
+typedef enum {
+       BT_HFP_AGENT_NETWORK_REG_STATUS_HOME,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_ROAMING,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_OFFLINE,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_SEARCHING,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_NO_SIM,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_POWEROFF,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_POWERSAFE,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_NO_COVERAGE,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_REJECTED,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_UNKOWN,
+} bt_hfp_agent_network_registration_status_t;
+
+typedef enum {
+       BT_HFP_AGENT_ERROR_INTERNAL,
+       BT_HFP_AGENT_ERROR_NOT_AVAILABLE,
+       BT_HFP_AGENT_ERROR_NOT_CONNECTED,
+       BT_HFP_AGENT_ERROR_BUSY,
+       BT_HFP_AGENT_ERROR_INVALID_PARAM,
+       BT_HFP_AGENT_ERROR_ALREADY_EXSIST,
+       BT_HFP_AGENT_ERROR_ALREADY_CONNECTED,
+       BT_HFP_AGENT_ERROR_NO_MEMORY,
+       BT_HFP_AGENT_ERROR_I_O_ERROR,
+       BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE,
+       BT_HFP_AGENT_ERROR_NO_CALL_LOGS,
+       BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX,
+       BT_HFP_AGENT_ERROR_INVALID_CHLD_INDEX,
+       BT_HFP_AGENT_ERROR_BATTERY_STATUS,
+       BT_HFP_AGENT_ERROR_SIGNAL_STATUS,
+       BT_HFP_AGENT_ERROR_NOT_SUPPORTED,
+       BT_HFP_AGENT_ERROR_INVALID_NUMBER,
+       BT_HFP_AGENT_ERROR_APPLICATION,
+       BT_HFP_AGENT_ERROR_INVALID_DTMF,
+       BT_HFP_AGENT_ERROR_NONE,
+} bt_hfp_agent_error_t;
+
+#define BT_HFP_SERVICE_OBJECT_PATH "/org/bluez/hfp_agent"
+#define BT_HFP_SERVICE "org.bluez.hfp_agent"
+
+#undef LOG_TAG
+#define LOG_TAG "BT_HFP_AGENT"
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#endif /* __DEF_BT_HFP_AGENT_H_ */
diff --git a/mobile/hfp-agent/hfp_agent.xml b/mobile/hfp-agent/hfp_agent.xml
new file mode 100644 (file)
index 0000000..b942156
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="Org.Hfp.App.Interface">
+
+    <method name="RegisterApplication">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+    </method>
+
+    <method name="UnregisterApplication">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+    </method>
+
+    <method name="IncomingCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="number"/>
+      <arg type="i" name="id"/>
+    </method>
+
+    <method name="OutgoingCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="number"/>
+      <arg type="i" name="id"/>
+    </method>
+
+    <method name="ChangeCallStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+      <arg type="i" name="status"/>
+      <arg type="i" name="id"/>
+    </method>
+
+    <method name="GetProperties">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+    </method>
+
+ </interface>
+
+ <interface name="Org.Hfp.Bluez.Interface">
+
+    <method name="AnswerCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+       <arg type="u" name="callid"/>
+       <arg type="s" name="path"/>
+       <arg type="s" name="sender"/>
+    </method>
+
+    <method name="ReleaseCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="u" name="callid"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="RejectCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="u" name="callid"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="ThreewayCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="u" name="value"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="DialLastNum">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+    </method>
+
+    <method name="DialNum">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="Number"/>
+      <arg type="u" name="flags"/>
+    </method>
+
+    <method name="DialMemory">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="i" name="location"/>
+    </method>
+
+    <method name="SendDtmf">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="dtmf"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="VoiceDial">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="b" name="activate"/>
+    </method>
+
+    <method name="GetBatteryStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="i" name="bcl" direction="out"/>
+      <arg type="i" name="bcs" direction="out"/>
+    </method>
+
+    <method name="GetSignalQuality">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="i" name="rssi" direction="out"/>
+      <arg type="i" name="ber" direction="out"/>
+    </method>
+
+    <method name="GetOperatorName">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="operator" direction="out"/>
+    </method>
+
+    <method name="NrecStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="b" name="status"/>
+    </method>
+
+    <method name="ConnectionStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="b" name="status"/>
+    </method>
+
+  </interface>
+</node>
diff --git a/mobile/hfp-agent/org.bluez.hfp_agent.service b/mobile/hfp-agent/org.bluez.hfp_agent.service
new file mode 100644 (file)
index 0000000..28e2aa2
--- /dev/null
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.bluez.hfp_agent
+Exec=/usr/bin/bluetooth-hfp-agent
+User=root
diff --git a/mobile/map-agent/CMakeLists.txt b/mobile/map-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..932bee4
--- /dev/null
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-map-agent C)
+
+SET(SRCS bluetooth_map_agent.c map_bmessage.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_map_agent
+               REQUIRED
+               dbus-glib-1 dlog msg-service email-service vconf)
+
+FOREACH(flag ${pkgs_map_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
+               ARGS "--prefix=bluetooth_map \\
+               ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent.xml \\
+               --mode=glib-server \\
+               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent_glue.h")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_map_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.map_agent.service
+               DESTINATION share/dbus-1/services)
diff --git a/mobile/map-agent/bluetooth_map_agent.c b/mobile/map-agent/bluetooth_map_agent.c
new file mode 100644 (file)
index 0000000..f321570
--- /dev/null
@@ -0,0 +1,2178 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <time.h>
+#include "vconf.h"
+#include "vconf-keys.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+/*Messaging Header Files*/
+#include "msg.h"
+#include "msg_storage.h"
+#include "msg_storage_types.h"
+#include "msg_transport.h"
+#include "msg_transport_types.h"
+#include "msg_types.h"
+
+#ifdef SUPPORT_EMAIL
+/*Email Header Files*/
+#include "email-types.h"
+#include "email-api-init.h"
+#include "email-api-account.h"
+#include "email-api-mailbox.h"
+#include "email-api-mail.h"
+#include "email-api-network.h"
+#endif
+
+#include <bluetooth_map_agent.h>
+
+#include <map_bmessage.h>
+
+#define OBEX_CLIENT_SERVICE "org.openobex.client"
+#define OBEX_CLIENT_INTERFACE "org.openobex.Client"
+#define OBEX_CLIENT_PATH "/"
+#define MNS_CLIENT_INTERFACE "org.openobex.MessageNotification"
+
+#define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", \
+               G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_INVALID))
+
+#define DBUS_STRUCT_MESSAGE_LIST (dbus_g_type_get_struct("GValueArray", \
+               G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_STRING, \
+               G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_STRING, \
+               G_TYPE_STRING, G_TYPE_STRING,   G_TYPE_BOOLEAN, G_TYPE_STRING, \
+               G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
+               G_TYPE_BOOLEAN, G_TYPE_STRING, \
+               G_TYPE_INVALID))
+
+static msg_handle_t g_msg_handle = NULL;
+
+#define BT_MAP_NEW_MESSAGE "NewMessage"
+#define BT_MAP_STATUS_CB "sent status callback"
+#define BT_MAP_MSG_CB "sms message callback"
+#define BT_MAP_EMAIL_DEFAULTACCOUNT "db/email/defaultaccount"
+#define BT_MNS_OBJECT_PATH "/org/bluez/mns"
+#define BT_MNS_INTERFACE "org.bluez.mns"
+#define BT_MAIL_TEMP_BODY "/tmp/bt_mail.txt"
+#define BT_MAP_SENT_FOLDER_NAME "SENT"
+#define BT_MAP_MSG_INFO_MAX 256
+#define BT_MAP_MSG_HANDLE_MAX 21
+#define BT_MAP_TIMESTAMP_MAX_LEN 16
+#define BT_MAP_SUBJECT_MAX_LEN 20
+#define BT_MAP_MSG_BODY_MAX 1024
+#define BT_MSG_UPDATE  0
+#define BT_MSG_DELETE  1
+#define BT_SMS 0
+#define BT_EMAIL 1
+#define BT_EMAIL_HANDLE_BASE (G_MAXUINT64 / 2)
+#define BT_MAIL_ID_MAX_LENGTH 50
+
+#define BEGIN_BMSEG "BEGIN:BMSG\r\n"
+#define END_BMSEG "END:BMSG\r\n"
+#define BMSEG_VERSION "VERSION:1.0\r\n"
+#define MSEG_STATUS "STATUS:%s\r\n"
+#define MSEG_TYPE "TYPE:%s\r\n"
+#define FOLDER_PATH "FOLDER:%s\r\n"
+#define VCARD "BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s\r\nTEL:%s\r\nEND:VCARD\r\n"
+#define BEGIN_BENV "BEGIN:BENV\r\n"
+#define END_BENV "END:BENV\r\n"
+#define BEGIN_BBODY "BEGIN:BBODY\r\n"
+#define END_BBODY "END:BBODY\r\n"
+#define ENCODING "ENCODING:%s\r\n"
+#define CHARSET "CHARSET:%s\r\n"
+#define LANGUAGE "LANGUAGE:%s\r\n"
+#define LENGTH "LENGTH:%d\r\n"
+#define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n"
+
+/* This has been added for testing purpose, will be removed when SMS APIs
+    are available. */
+#define TEST_PDU "06810000000000040681567777000021017101750261A05"\
+                "376BA0D8297E5F3B73BCC4ED3F3A030FB1ECECF41613A"\
+                "5D1E1ED3E7A0B2BD2CCF8362AEA4195407C941ECF77C9"\
+                "E769F41753968FC769BD3E4B27B5C0691EB6510FD0D7AD"\
+                "BCBF27B397D46D343A163990E42BFDB6590BCDC4E93D3"\
+                "E539889E86CF41F437485E26D7C765D0DB5E96DFCBE933"\
+                "9A1E9A36A72063900AA2BF41B5DBED760385E920E9DC357B35A9"
+
+GSList* id_list = NULL;
+guint64 current_push_map_id;
+
+struct id_info {
+       guint64 map_id;
+       int uid;
+};
+
+struct msg_send_option {
+       bool save_copy;
+       bool retry_send;
+       bool native;
+};
+
+struct message_info {
+       char *handle;
+       char *subject;
+       char *datetime;
+       char *sender_name;
+       char *sender_addressing;
+       char *recipient_name;
+       char *recipient_addressing;
+       char *type;
+       char *size;
+       char *reception_status;
+       char *attachment_size;
+       char *replyto_addressing;
+       gboolean text;
+       gboolean priority;
+       gboolean read;
+       gboolean sent;
+       gboolean protect;
+};
+
+typedef struct {
+       GObject parent;
+} BluetoothMapAgent;
+
+typedef struct {
+       GObjectClass parent;
+} BluetoothMapAgentClass;
+
+GType bluetooth_map_agent_get_type(void);
+
+#define BLUETOOTH_MAP_TYPE_AGENT (bluetooth_map_agent_get_type())
+
+#define BLUETOOTH_MAP_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_CAST((object), \
+       BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgent))
+#define BLUETOOTH_MAP_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST((klass), \
+       BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass))
+#define BLUETOOTH_MAP_IS_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+       BLUETOOTH_MAP_TYPE_AGENT))
+#define BLUETOOTH_MAP_IS_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE((klass), \
+       BLUETOOTH_MAP_TYPE_AGENT))
+#define BLUETOOTH_MAP_AGENT_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS((obj), \
+       BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass))
+
+G_DEFINE_TYPE(BluetoothMapAgent, bluetooth_map_agent, G_TYPE_OBJECT)
+
+GMainLoop *g_mainloop = NULL;
+static DBusGConnection *g_connection = NULL;
+static char *g_mns_path = NULL;
+static struct msg_send_option opt;
+
+static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
+                                       gchar *folder_name, guint16 max,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
+                                       gchar *message_name,
+                                       gboolean attach, gboolean transcode,
+                                       gboolean first_request,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
+                                       gboolean save_copy,
+                                       gboolean retry_send,
+                                       gboolean native,
+                                       gchar *folder_name,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
+                                       gchar *bmsg,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
+                                       gchar *handle, gboolean read_status,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
+                                       gchar *handle, gboolean delete_status,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
+                                       gchar *remote_addr,
+                                       gboolean status,
+                                       DBusGMethodInvocation *context);
+
+
+#include "bluetooth_map_agent_glue.h"
+
+static void bluetooth_map_agent_init(BluetoothMapAgent *obj)
+{
+       DBG("+\n");
+
+       g_assert(obj != NULL);
+}
+
+static void bluetooth_map_agent_finalize(GObject *obj)
+{
+       DBG("+\n");
+
+       G_OBJECT_CLASS(bluetooth_map_agent_parent_class)->finalize(obj);
+}
+
+static void bluetooth_map_agent_class_init(BluetoothMapAgentClass *klass)
+{
+       GObjectClass *object_class = (GObjectClass *) klass;
+
+       g_assert(klass != NULL);
+
+       object_class->finalize = bluetooth_map_agent_finalize;
+
+       dbus_g_object_type_install_info(BLUETOOTH_MAP_TYPE_AGENT,
+                                       &dbus_glib_bluetooth_map_object_info);
+}
+
+static GQuark __bt_map_agent_error_quark(void)
+{
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string("agent");
+
+       return quark;
+}
+
+static GError *__bt_map_agent_error(bt_map_agent_error_t error,
+                                    const char *err_msg)
+{
+       return g_error_new(BT_MAP_AGENT_ERROR, error, err_msg, NULL);
+}
+
+static guint64 _bt_validate_uid(int uid)
+{
+        DBG("Validate uid");
+        struct id_info *info;
+        int count;
+        int i;
+
+        count = g_slist_length(id_list);
+        for (i = 0; i < count; i++) {
+                info = (struct id_info *)g_slist_nth_data(id_list, i);
+               if (!info)
+                       break;
+
+                if (info->uid == uid) {
+                        printf("uid = %d\n", uid);
+                        return info->map_id;
+                }
+        }
+
+        return 0;
+}
+
+static guint64 __bt_add_id(int uid)
+{
+        DBG("Add id: %d\n", uid);
+        static guint64 map_id;
+        struct id_info *info;
+        guint64 test;
+
+        test = _bt_validate_uid(uid);
+        DBG("test: %llx\n", test);
+        if (test)
+                return test;
+
+        info = g_new0(struct id_info, 1);
+
+        map_id++;
+
+        info->map_id = map_id;
+        info->uid = uid;
+        DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid);
+
+        id_list = g_slist_append(id_list, info);
+
+        return map_id;
+}
+
+static int __bt_get_id(guint64 map_id)
+{
+        DBG("get id\n");
+        struct id_info *info;
+        int count;
+       int i;
+
+        count = g_slist_length(id_list);
+
+        for (i = 0; i < count; i++) {
+                info = (struct id_info *)g_slist_nth_data(id_list, i);
+
+                if (info->map_id == map_id)
+                        return info->uid;
+        }
+
+        return -1;
+}
+
+static int __bt_get_uid(gchar *handle)
+{
+       guint64 map_id;
+       int uid;
+
+       if (NULL == handle)
+               return -1;
+
+       map_id = g_ascii_strtoull(handle, NULL, 16);
+       if (!map_id)
+               return -1;
+
+       uid = __bt_get_id(map_id);
+
+       return uid;
+}
+
+static int __bt_update_id(guint64 map_id, int new_uid)
+{
+       DBG("update id\n");
+       struct id_info *info;
+       int i;
+       int count;
+
+       count = g_slist_length(id_list);
+
+       for (i = 0; i < count; i++) {
+               info = g_slist_nth_data(id_list, i);
+
+               if (info->map_id == map_id) {
+                       info->uid = new_uid;
+                       return map_id;
+               }
+       }
+
+        return -1;
+}
+
+static void __bt_remove_list(GSList *id_list)
+{
+       if (!id_list)
+               return;
+
+        DBG("Removing id list\n");
+        g_slist_free_full(id_list, g_free);
+}
+
+
+static gchar *__bt_get_folder_name(int id)
+{
+       int ret;
+       char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
+
+       msg_struct_list_s g_folderList;
+       msg_struct_t p_folder;
+
+       ret = msg_get_folder_list(g_msg_handle, &g_folderList);
+       if (ret != MSG_SUCCESS)
+               goto done;
+
+       p_folder = g_folderList.msg_struct_info[id];
+
+       ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       folder_name, BT_MAP_MSG_INFO_MAX);
+       if (ret != MSG_SUCCESS)
+               goto done;
+
+       return g_strdup_printf("TELECOM/MSG/%s", folder_name);
+
+done:
+       return g_strdup("TELECOM/MSG");
+}
+
+static void __get_msg_timestamp(time_t *ltime, char *timestamp)
+{
+       struct tm local_time;
+       int year;
+       int month;
+
+       if (!localtime_r(ltime, &local_time))
+               return;
+
+       year = local_time.tm_year + 1900; /* years since 1900 */
+       month = local_time.tm_mon + 1; /* months since January */
+       snprintf(timestamp, 16, "%04d%02d%02dT%02d%02d%02d", year, month,
+                                       local_time.tm_mday, local_time.tm_hour,
+                                       local_time.tm_min, local_time.tm_sec);
+
+       return;
+}
+
+static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
+                                                       gboolean transcode)
+{
+       int ret;
+       int m_type = MSG_TYPE_SMS;
+       int folder_id;
+       int count;
+       bool read_status = false;
+       char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
+       char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
+       char name_value[MAX_ADDRESS_VAL_LEN] = {0,};
+       gchar *folder_path;
+
+       msg_struct_list_s *addr_list = NULL;
+       GString *msg;
+
+       msg = g_string_new(BEGIN_BMSEG);
+       g_string_append(msg, BMSEG_VERSION);
+
+       ret = msg_get_bool_value(msg_info, MSG_MESSAGE_READ_BOOL, &read_status);
+       if (ret == MSG_SUCCESS) {
+               DBG("read_status %d\n", read_status);
+       }
+
+       if (read_status)
+               g_string_append_printf(msg, MSEG_STATUS, "READ");
+       else
+               g_string_append_printf(msg, MSEG_STATUS, "UNREAD");
+
+       ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type);
+       if (ret == MSG_SUCCESS) {
+               DBG("m_type %d\n", m_type);
+       }
+
+       switch (m_type) {
+       case MSG_TYPE_MMS:
+       case MSG_TYPE_MMS_JAVA:
+       case MSG_TYPE_MMS_NOTI:
+               g_string_append_printf(msg, MSEG_TYPE, "MMS");
+               break;
+
+       default:
+                g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM");
+               break;
+       }
+
+       ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
+                                                       &folder_id);
+       if (ret == MSG_SUCCESS) {
+               DBG("folder_id %d\n", folder_id);
+       }
+
+       folder_path = __bt_get_folder_name(folder_id);
+       g_string_append_printf(msg, FOLDER_PATH, folder_path);
+
+
+       ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_STRUCT,
+                                                       (void **)&addr_list);
+       if (ret == MSG_SUCCESS) {
+               count = addr_list->nCount;
+               DBG("count %d \n", count);
+               while (count > 0) {
+                       msg_struct_t addr_info = NULL;
+                       addr_info = addr_list->msg_struct_info[count - 1];
+
+                       msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                                       addr_value, MAX_ADDRESS_VAL_LEN);
+                       DBG("addr_value %s\n", addr_value);
+                       msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_DISPLAYNAME_STR,
+                                       name_value, MAX_ADDRESS_VAL_LEN);
+                       if (!strlen(name_value))
+                               g_stpcpy(name_value, addr_value);
+
+                       DBG("name_value %s\n", name_value);
+
+                       g_string_append_printf(msg, VCARD, name_value,
+                                                               addr_value);
+                       count--;
+               }
+       }
+
+       g_string_append(msg, BEGIN_BENV);
+       g_string_append(msg, BEGIN_BBODY);
+
+       if (transcode) {
+               g_string_append_printf(msg, CHARSET, "UTF-8");
+
+               if (m_type == MSG_TYPE_MMS)
+                       ret = msg_get_str_value(msg_info,
+                                               MSG_MESSAGE_MMS_TEXT_STR,
+                                               msg_body, BT_MAP_SUBJECT_MAX_LEN);
+               else
+                       ret = msg_get_str_value(msg_info,
+                                               MSG_MESSAGE_SMS_DATA_STR,
+                                               msg_body, BT_MAP_MSG_BODY_MAX);
+
+               if (ret == MSG_SUCCESS) {
+                       g_string_append_printf(msg, LENGTH, strlen(msg_body));
+                       g_string_append_printf(msg, MSG_BODY, msg_body);
+               }
+       } else {
+               gchar *msg_pdu;
+               g_string_append_printf(msg, ENCODING, "G-7BIT");
+               g_string_append_printf(msg, CHARSET, "native");
+               /* The below line has been added for testing purpose,
+                   will be removed when SMS APIs are available. */
+               msg_pdu = g_strdup(TEST_PDU);
+               g_string_append_printf(msg, LENGTH, strlen(msg_pdu));
+               g_string_append_printf(msg, MSG_BODY, msg_pdu);
+               g_free(msg_pdu);
+       }
+
+       g_string_append(msg, END_BBODY);
+       g_string_append(msg, END_BENV);
+       g_string_append(msg, END_BMSEG);
+
+       return g_string_free(msg, FALSE);
+}
+
+static void __bt_message_info_free(struct message_info msg_info)
+{
+       g_free(msg_info.handle);
+       g_free(msg_info.subject);
+       g_free(msg_info.datetime);
+       g_free(msg_info.sender_name);
+       g_free(msg_info.sender_addressing);
+       g_free(msg_info.replyto_addressing);
+       g_free(msg_info.recipient_name);
+       g_free(msg_info.recipient_addressing);
+       g_free(msg_info.type);
+       g_free(msg_info.reception_status);
+       g_free(msg_info.size);
+       g_free(msg_info.attachment_size);
+}
+
+static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
+{
+       struct message_info msg_info = {0,};
+       int ret;
+       int msg_id;
+       guint64 uid;
+       int dptime;
+       int m_type = 0;
+       int data_size;
+       int priority;
+       int direction_type;
+       bool protect_status = 0;
+       bool read_status = 0;
+
+       char msg_handle[BT_MAP_MSG_HANDLE_MAX] = {0,};
+       char msg_subject[BT_MAP_SUBJECT_MAX_LEN] = {0,};
+       char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,};
+       char msg_size[5] = {0,};
+       char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
+       char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
+       char name_value[MAX_ADDRESS_VAL_LEN] = {0,};
+
+       msg_info.text = FALSE;
+       msg_info.protect = FALSE;
+       msg_info.read = FALSE;
+       msg_info.priority = FALSE;
+
+       msg_struct_t msg = NULL;
+       msg_struct_t send_opt = NULL;
+       msg_struct_list_s *addr_list = NULL;
+       msg_struct_t addr_info = NULL;
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id);
+       if (ret == MSG_SUCCESS) {
+               uid = __bt_add_id(msg_id);
+               snprintf(msg_handle, sizeof(msg_handle), "%llx", uid);
+       }
+       msg_info.handle = g_strdup(msg_handle);
+
+       msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+
+       ret = msg_get_message(g_msg_handle,
+                                               (msg_message_id_t)msg_id,
+                                               msg, send_opt);
+       if (ret != MSG_SUCCESS) {
+               DBG("ret = %d\n", ret);
+               goto next;
+       }
+
+       ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_STRUCT,
+                                                       (void **)&addr_list);
+       if (ret != MSG_SUCCESS) {
+               DBG("ret = %d\n", ret);
+               goto next;
+       }
+
+       addr_info = addr_list->msg_struct_info[0];
+
+       ret = msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                               addr_value, MAX_ADDRESS_VAL_LEN);
+       if (ret == MSG_SUCCESS)
+               DBG("addr_value %s\n", addr_value);
+
+       ret = msg_get_str_value(addr_info, MSG_ADDRESS_INFO_DISPLAYNAME_STR,
+                       name_value, MAX_ADDRESS_VAL_LEN);
+       if (ret == MSG_SUCCESS)
+               DBG("name_value %s\n", name_value);
+
+       if (!strlen(name_value))
+               g_stpcpy(name_value, addr_value);
+
+       DBG("name_value %s\n", name_value);
+
+       ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT, &direction_type);
+       if (ret != MSG_SUCCESS)
+               goto next;
+
+       if (direction_type == MSG_DIRECTION_TYPE_MT) {
+               msg_info.sender_name = g_strdup(name_value);
+               msg_info.sender_addressing = g_strdup(addr_value);
+               msg_info.recipient_name = g_strdup("Unknown");
+               msg_info.recipient_addressing = g_strdup("0000");
+       } else {
+               msg_info.sender_name = g_strdup("Unknown");
+               msg_info.sender_addressing = g_strdup("0000");
+               msg_info.recipient_name = g_strdup(name_value);
+               msg_info.recipient_addressing = g_strdup(addr_value);
+       }
+
+next:
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
+       if (ret == MSG_SUCCESS) {
+               __get_msg_timestamp((time_t *)&dptime, msg_datetime);
+       }
+       msg_info.datetime = g_strdup(msg_datetime);
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT,
+                                                               &m_type);
+       if (ret == MSG_SUCCESS) {
+               DBG("m_type %d\n", m_type);
+       }
+
+       switch (m_type) {
+       case MSG_TYPE_MMS:
+       case MSG_TYPE_MMS_JAVA:
+       case MSG_TYPE_MMS_NOTI:
+               msg_info.type = g_strdup("MMS");
+               break;
+
+       default:
+               msg_info.type = g_strdup("SMS_GSM");
+               break;
+       }
+
+       if (m_type == MSG_TYPE_MMS) {
+               ret = msg_get_str_value(msg_struct_handle,
+                                       MSG_MESSAGE_SUBJECT_STR, msg_subject,
+                                       BT_MAP_SUBJECT_MAX_LEN);
+               if (ret == MSG_SUCCESS) {
+                       DBG("MMS subject %s", msg_subject);
+               }
+
+               msg_info.subject = g_strdup(msg_subject);
+
+               ret = msg_get_str_value(msg_struct_handle,
+                                       MSG_MESSAGE_MMS_TEXT_STR, msg_body,
+                                       BT_MAP_MSG_BODY_MAX);
+               if (ret == MSG_SUCCESS) {
+                       DBG("msg_body %s", msg_body);
+                       if (strlen(msg_body))
+                               msg_info.text = TRUE ;
+               }
+
+       } else if (m_type == MSG_TYPE_SMS) {
+               ret = msg_get_str_value(msg_struct_handle,
+                                       MSG_MESSAGE_SMS_DATA_STR, msg_body,
+                                       BT_MAP_MSG_BODY_MAX);
+               if (ret == MSG_SUCCESS) {
+                       DBG("SMS subject %s", msg_body);
+                       if (strlen(msg_body)) {
+                               msg_info.text = TRUE ;
+                               msg_info.subject = g_strndup(msg_body,
+                                                       BT_MAP_SUBJECT_MAX_LEN);
+                       }
+               }
+       }
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT,
+                                                               &data_size);
+       if (ret == MSG_SUCCESS)
+               snprintf(msg_size, sizeof(msg_size), "%d", data_size);
+
+       msg_info.size = g_strdup(msg_size);
+
+       msg_info.reception_status = g_strdup("complete");
+       msg_info.attachment_size = g_strdup("0");
+
+       ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL,
+                                                       &protect_status);
+       if (ret == MSG_SUCCESS) {
+               if (protect_status)
+                       msg_info.protect = TRUE;
+       }
+
+       ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL,
+                                                               &read_status);
+       if (ret == MSG_SUCCESS) {
+               if (read_status)
+                       msg_info.read = TRUE;
+       }
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT,
+                                                               &priority);
+       if (ret == MSG_SUCCESS) {
+               if (priority == MSG_MESSAGE_PRIORITY_HIGH)
+                       msg_info.priority = TRUE;
+       }
+
+       return msg_info;
+}
+
+static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle,
+                                                       msg_struct_t msg,
+                                                       void *user_param)
+{
+       DBusGProxy *mns_proxy;
+       GError *error = NULL;
+
+       int msg_id = 0;
+       int msg_type = 0;
+       int ret = MSG_SUCCESS;
+
+       char *message_type = NULL;
+
+       guint64 uid;
+
+       DBG("+\n");
+
+       ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
+       if (ret != MSG_SUCCESS)
+               return;;
+
+       uid = __bt_add_id(msg_id);
+
+       ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type);
+       if (ret != MSG_SUCCESS)
+               return;
+
+       switch (msg_type) {
+       case MSG_TYPE_SMS:
+               message_type = g_strdup("SMS_GSM");
+               break;
+       case MSG_TYPE_MMS:
+               message_type = g_strdup("MMS");
+               break;
+       default:
+               return;
+       }
+
+       mns_proxy = dbus_g_proxy_new_for_name(g_connection, OBEX_CLIENT_SERVICE,
+                                                       g_mns_path,
+                                                       MNS_CLIENT_INTERFACE);
+       if (mns_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               g_free(message_type);
+               return;
+       }
+
+       dbus_g_proxy_call(mns_proxy, "SendEvent", &error,
+               G_TYPE_STRING, "NewMessage",
+               G_TYPE_UINT64, uid,
+               G_TYPE_STRING, "TELECOM/MSG/INBOX",
+               G_TYPE_STRING, "",
+               G_TYPE_STRING, message_type,
+               G_TYPE_INVALID, G_TYPE_INVALID);
+       if (error) {
+               DBG("Error [%s]", error->message);
+               g_error_free(error);
+       }
+
+       DBG("-\n");
+       g_free(message_type);
+       g_object_unref(mns_proxy);
+       return;
+}
+
+static gboolean __bluetooth_map_start_service()
+{
+       msg_error_t err = MSG_SUCCESS;
+       gboolean msg_ret = TRUE;
+#ifdef SUPPORT_EMAIL
+       int email_err = EMAIL_ERROR_NONE;
+       gboolean email_ret = TRUE;
+#endif
+
+       err = msg_open_msg_handle(&g_msg_handle);
+       if (err != MSG_SUCCESS) {
+               ERR("msg_open_msg_handle error = %d\n", err);
+               msg_ret = FALSE;
+               goto done;
+       }
+
+       err = msg_reg_sms_message_callback(g_msg_handle,
+                                       __bluetooth_map_msg_incoming_status_cb,
+                                       0, (void *)BT_MAP_MSG_CB);
+       if (err != MSG_SUCCESS) {
+               ERR("msg_reg_sms_message_callback error  = %d\n", err);
+               msg_ret = FALSE;
+       }
+
+done:
+
+#ifdef SUPPORT_EMAIL
+
+       email_err = email_service_begin();
+       if (email_err != EMAIL_ERROR_NONE) {
+               ERR("email_service_begin fail  error = %d\n", email_err);
+               email_ret = FALSE;
+       }
+
+       if (msg_ret || email_ret)
+               return TRUE;
+       else
+               return FALSE;
+
+#else
+
+       return msg_ret;
+
+#endif
+}
+
+static void __bluetooth_map_stop_service()
+{
+       if (NULL != g_msg_handle)
+               msg_close_msg_handle(&g_msg_handle);
+
+       g_msg_handle = NULL;
+
+#ifdef SUPPORT_EMAIL
+       if (EMAIL_ERROR_NONE != email_service_end())
+               ERR("email_service_end fail \n");
+#endif
+       return;
+}
+
+#ifdef SUPPORT_EMAIL
+static int __bt_store_mail(email_mailbox_type_e type, char *subject,
+                                               char *body, char *recepients)
+{
+       int account_id;
+       int mail_id;
+       int err;
+       char from_address[BT_MAIL_ID_MAX_LENGTH] = { 0, };
+       FILE *body_file;
+       struct stat st_buf;
+
+       email_account_t *account_data = NULL;
+       email_mailbox_t *mailbox_data = NULL;
+       email_mail_data_t *mail_data = NULL;
+
+       err = email_load_default_account_id(&account_id);
+       if (EMAIL_ERROR_NONE != err)
+               goto fail;
+
+       err = email_get_account(account_id, GET_FULL_DATA_WITHOUT_PASSWORD,
+                                                               &account_data);
+       if (EMAIL_ERROR_NONE != err)
+               goto fail;
+
+       err = email_get_mailbox_by_mailbox_type(account_id, type,
+                                                               &mailbox_data);
+       if (EMAIL_ERROR_NONE != err)
+               goto fail;
+
+       snprintf(from_address, BT_MAIL_ID_MAX_LENGTH, "<%s>",
+                                       account_data->user_email_address);
+       email_free_account(&account_data, 1);
+
+       mail_data = calloc(1, sizeof(email_mail_data_t));
+       if (NULL == mail_data) {
+               email_free_mailbox(&mailbox_data, 1);
+               goto fail;
+       }
+
+       DBG("\n account_id %d\n", account_id);
+       mail_data->account_id = account_id;
+       mail_data->save_status = 1;
+       mail_data->body_download_status = 1;
+       /* mail_data->flags_draft_field = 1; */
+       mail_data->flags_seen_field = 1;
+       mail_data->file_path_plain = g_strdup(BT_MAIL_TEMP_BODY);
+
+       mail_data->mailbox_id = mailbox_data->mailbox_id;
+       mail_data->mailbox_type = mailbox_data->mailbox_type;
+       email_free_mailbox(&mailbox_data, 1);
+
+       mail_data->full_address_from = g_strdup(from_address);
+       mail_data->full_address_to = g_strdup(recepients);
+       mail_data->subject = g_strdup(subject);
+       mail_data->report_status = EMAIL_MAIL_REQUEST_DSN |
+                                                       EMAIL_MAIL_REQUEST_MDN;
+
+       body_file = fopen(BT_MAIL_TEMP_BODY, "w");
+       if (body_file == NULL) {
+               DBG("\n fopen [%s]failed\n", BT_MAIL_TEMP_BODY);
+               email_free_mail_data(&mail_data, 1);
+               goto fail;
+       }
+
+       fprintf(body_file, body);
+       fflush(body_file);
+       fclose(body_file);
+
+       err = email_add_mail(mail_data, NULL, 0, NULL, 0);
+       if (err != EMAIL_ERROR_NONE) {
+               DBG("email_add_mail failed. [%d]\n", err);
+               if (!stat(mail_data->file_path_plain, &st_buf))
+                       remove(mail_data->file_path_plain);
+
+               email_free_mail_data(&mail_data, 1);
+               goto fail;
+       }
+
+       DBG("saved mail id = [%d]\n", mail_data->mail_id);
+
+       mail_id = mail_data->mail_id;
+
+       email_free_mail_data(&mail_data, 1);
+
+       return mail_id;
+
+fail:
+       return 0;
+}
+
+static int __bt_email_send(char *subject, char *body, char* recepients)
+{
+       int err;
+       int mail_id;
+       int handle;
+
+       mail_id = __bt_store_mail(EMAIL_MAILBOX_TYPE_OUTBOX, subject,
+                                                       body, recepients);
+       if (mail_id) {
+               DBG("mail_id = %d\n", mail_id);
+               err = email_send_mail(mail_id, &handle);
+               if (err != EMAIL_ERROR_NONE)
+                       DBG("Sending failed[%d]\n", err);
+       }
+
+       return mail_id;
+}
+#endif
+
+static int __bt_get_folder_id(char *folder_path)
+{
+       int folder_id = -1;
+       int i;
+       char *folder;
+       msg_struct_list_s folder_list;
+       msg_error_t err;
+       msg_struct_t p_folder;
+       DBG("__bt_get_folder_id\n");
+
+       folder = strrchr(folder_path, '/');
+       if (NULL == folder)
+               return -1;
+
+       folder++;
+
+       DBG("folderName %s\n", folder);
+
+       err = msg_get_folder_list(g_msg_handle, &folder_list);
+       if (err != MSG_SUCCESS)
+               return -1;
+
+       for (i = 0; i < folder_list.nCount; i++) {
+               p_folder = folder_list.msg_struct_info[i];
+               char folder_name[BT_MAP_MSG_INFO_MAX] = {0, };
+
+               err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       folder_name, BT_MAP_MSG_INFO_MAX);
+               if (err != MSG_SUCCESS)
+                       continue;
+
+               DBG("folderName %s\n", folder_name);
+               if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) {
+                       err = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
+                                                               &folder_id);
+                       if (err != MSG_SUCCESS)
+                               return -1;
+
+                       break;
+               }
+       }
+
+       return folder_id;
+
+}
+
+msg_error_t __bt_send_sms(int msg_id, msg_struct_t pMsg, msg_struct_t pSendOpt)
+{
+       msg_error_t err;
+       msg_struct_t pReq;
+
+       pReq = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
+
+       msg_set_int_value(pMsg, MSG_MESSAGE_ID_INT, msg_id);
+       msg_set_struct_handle(pReq, MSG_REQUEST_MESSAGE_HND, pMsg);
+       msg_set_struct_handle(pReq, MSG_REQUEST_SENDOPT_HND, pSendOpt);
+
+       err = msg_sms_send_message(g_msg_handle, pReq);
+       if (err == MSG_SUCCESS)
+               DBG("Sending Message is successful!!!");
+       else
+               DBG("Sending Message is failed!!! %d", err);
+
+       msg_release_struct(&pReq);
+       return err;
+}
+
+static int __bt_push_sms(gboolean send, int folder_id, char *body,
+                                                       GSList *recepients)
+{
+       DBG("+ \n");
+       msg_struct_t msg_info = NULL;
+       msg_struct_t send_opt = NULL;
+       msg_struct_list_s *addr_list;
+       msg_error_t err;
+
+       int count = 0;
+       int i = 0;
+       int msg_id;
+       guint64 uid = -1;
+
+       msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       if (msg_info == NULL)
+               goto fail;
+
+       err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       if (body) {
+               err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, body,
+                                                                       strlen(body));
+               if (err != MSG_SUCCESS)
+                       goto fail;
+       } else {
+               err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
+                                                               NULL, 0);
+               if (err != MSG_SUCCESS)
+                       goto fail;
+       }
+
+       DBG("folder_id  %d\n", folder_id);
+       err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
+                                                               folder_id);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       if (recepients) {
+               count = g_slist_length(recepients);
+               DBG("Count = %d\n", count);
+               msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_STRUCT,
+                                                       (void**)&addr_list);
+
+               addr_list->nCount = count;
+               for (i = 0; i < count; i++) {
+                       char *address = (char *)g_slist_nth_data(recepients, i);
+                       if (address == NULL) {
+                               DBG("[ERROR] address is value NULL, skip");
+                               continue;
+                       }
+                       msg_set_int_value(addr_list->msg_struct_info[i],
+                                       MSG_ADDRESS_INFO_ADDRESS_TYPE_INT,
+                                       MSG_ADDRESS_TYPE_PLMN);
+
+                       msg_set_int_value(addr_list->msg_struct_info[i],
+                                       MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
+                                       MSG_RECIPIENTS_TYPE_TO);
+
+                       msg_set_str_value(addr_list->msg_struct_info[i],
+                                       MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                                       address, strlen(address));
+               }
+       }
+
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+
+       err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       /* Do not keep a copy */
+       err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL,
+                                                       opt.save_copy);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       msg_id = msg_add_message(g_msg_handle, msg_info, send_opt);
+       DBG("msg_id = %d\n", msg_id);
+       uid = __bt_add_id(msg_id);
+
+       if (send == TRUE) {
+               err = __bt_send_sms(msg_id, msg_info, send_opt);
+               if (err != MSG_SUCCESS) {
+                       uid = -1;
+                       goto fail;
+               }
+       }
+
+fail:
+       msg_release_struct(&msg_info);
+       msg_release_struct(&send_opt);
+       DBG("-\n");
+       return uid;
+}
+
+static gboolean __bt_msg_is_mms(int msg_type)
+{
+       gboolean result = FALSE;
+
+       switch (msg_type) {
+       case MSG_TYPE_MMS_NOTI:
+       case MSG_TYPE_MMS_JAVA:
+       case MSG_TYPE_MMS:
+               result = TRUE;
+               break;
+       default:
+               break;
+       }
+
+       return result;
+}
+
+static void __bt_mns_client_connect(char *address)
+{
+       DBusGProxy *mns_proxy;
+       GHashTable *hash;
+       GValue *addr_value;
+       GValue *tgt_value;
+       GError *error = NULL;
+       const char *session_path = NULL;
+
+       DBG("+ address %s\n", address);
+
+       mns_proxy = dbus_g_proxy_new_for_name(g_connection, OBEX_CLIENT_SERVICE,
+                                               OBEX_CLIENT_PATH,
+                                               OBEX_CLIENT_INTERFACE);
+       if (mns_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                    NULL, (GDestroyNotify)g_free);
+
+       addr_value = g_new0(GValue, 1);
+       g_value_init(addr_value, G_TYPE_STRING);
+       g_value_set_string(addr_value, address);
+       g_hash_table_insert(hash, "Destination", addr_value);
+
+       tgt_value = g_new0(GValue, 1);
+       g_value_init(tgt_value, G_TYPE_STRING);
+       g_value_set_string(tgt_value, "MNS");
+       g_hash_table_insert(hash, "Target", tgt_value);
+
+       dbus_g_proxy_call(mns_proxy, "CreateSession", &error,
+               dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+               hash, G_TYPE_INVALID,
+               DBUS_TYPE_G_OBJECT_PATH, &session_path,
+               G_TYPE_INVALID);
+       if (error) {
+               DBG("Error [%s]", error->message);
+               g_error_free(error);
+               g_hash_table_destroy(hash);
+               g_object_unref(mns_proxy);
+               return;
+       }
+
+       g_mns_path = g_strdup(session_path);
+       DBG("g_mns_path = %s\n", g_mns_path);
+
+       g_hash_table_destroy(hash);
+       g_object_unref(mns_proxy);
+
+       DBG("-\n");
+       return;
+}
+
+static void __bt_mns_client_disconnect()
+{
+       DBusGProxy *mns_proxy;
+       GError *error = NULL;
+
+       if (!g_mns_path)
+               return;
+
+       mns_proxy = dbus_g_proxy_new_for_name(g_connection, OBEX_CLIENT_SERVICE,
+                                               OBEX_CLIENT_PATH,
+                                               OBEX_CLIENT_INTERFACE);
+       if (mns_proxy == NULL) {
+               DBG("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       dbus_g_proxy_call(mns_proxy, "RemoveSession", &error,
+               DBUS_TYPE_G_OBJECT_PATH, g_mns_path,
+               G_TYPE_INVALID, G_TYPE_INVALID);
+       if (error) {
+               DBG("Error [%s]", error->message);
+               g_error_free(error);
+               g_object_unref(mns_proxy);
+               return;
+       }
+
+       g_free(g_mns_path);
+       g_mns_path = NULL;
+
+       g_object_unref(mns_proxy);
+
+       DBG("-\n");
+       return;
+}
+
+static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
+                                               DBusGMethodInvocation *context)
+{
+       GPtrArray *array = g_ptr_array_new();
+       GValue value;
+       GError *error = NULL;
+
+       char name[BT_MAP_MSG_INFO_MAX] = {0,};
+       char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
+       int i;
+       int ret;
+       gboolean msg_ret = TRUE;
+
+       msg_struct_list_s g_folderList;
+       msg_struct_t p_folder;
+
+#ifdef SUPPORT_EMAIL
+       int j;
+       int account_id = 0;
+       int mailbox_count = 0;
+       gboolean flag = FALSE;
+       email_mailbox_t *mailbox_list = NULL;
+#endif
+
+       if (g_msg_handle == NULL) {
+               msg_ret = FALSE;
+               goto done;
+       }
+
+       if (msg_get_folder_list(g_msg_handle, &g_folderList) != MSG_SUCCESS) {
+               msg_ret = FALSE;
+               goto done;
+       }
+
+       for (i = 0; i < g_folderList.nCount; i++) {
+               p_folder = g_folderList.msg_struct_info[i];
+               memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
+
+               ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       folder_name, BT_MAP_MSG_INFO_MAX);
+               if (ret != MSG_SUCCESS)
+                       continue;
+
+               if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME,
+                                       strlen(BT_MAP_SENT_FOLDER_NAME))) {
+                       memset(folder_name, 0, sizeof(folder_name));
+                       g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME,
+                                                       sizeof(folder_name));
+               }
+
+               g_strlcpy(name, folder_name, sizeof(name));
+               memset(&value, 0, sizeof(GValue));
+               g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
+               g_value_take_boxed(&value, dbus_g_type_specialized_construct(
+                                       DBUS_STRUCT_STRING_STRING_UINT));
+               dbus_g_type_struct_set(&value, 0, name, G_MAXUINT);
+               g_ptr_array_add(array, g_value_get_boxed(&value));
+       }
+
+#ifdef SUPPORT_EMAIL
+email:
+       if (EMAIL_ERROR_NONE != email_load_default_account_id(&account_id))
+               goto done;
+
+       if (EMAIL_ERROR_NONE != email_get_mailbox_list(account_id,
+                                                       EMAIL_MAILBOX_ALL,
+                                                       &mailbox_list,
+                                                       &mailbox_count)) {
+               goto done;
+       }
+
+       msg_ret = TRUE;
+
+       for (i = 0; i < mailbox_count; i++) {
+               flag = FALSE;
+               for (j = 0; j < g_folderList.nCount; j++) {
+
+                       p_folder = g_folderList.msg_struct_info[j];
+                       memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
+
+                       ret = msg_get_str_value(p_folder,
+                                               MSG_FOLDER_INFO_NAME_STR,
+                                               folder_name,
+                                               BT_MAP_MSG_INFO_MAX);
+                       if (ret != MSG_SUCCESS)
+                               continue;
+
+                       if (!g_ascii_strncasecmp(mailbox_list[i].alias,
+                               folder_name, strlen(mailbox_list[i].alias))) {
+                               flag = TRUE;
+                               break;
+                       }
+               }
+
+               if (!flag) {
+                       g_strlcpy(name, mailbox_list[i].alias, sizeof(name));
+
+                       if (!g_ascii_strncasecmp(name, BT_MAP_SENT_FOLDER_NAME,
+                                       strlen(BT_MAP_SENT_FOLDER_NAME)))
+                               continue;
+
+                       memset(&value, 0, sizeof(GValue));
+                       g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
+                       g_value_take_boxed(&value,
+                               dbus_g_type_specialized_construct(
+                               DBUS_STRUCT_STRING_STRING_UINT));
+                       dbus_g_type_struct_set(&value, 0, name, G_MAXUINT);
+                       g_ptr_array_add(array, g_value_get_boxed(&value));
+               }
+       }
+
+       if (mailbox_list != NULL)
+                email_free_mailbox(&mailbox_list, mailbox_count);
+#endif
+
+done:
+
+       if (msg_ret == FALSE) {
+               g_ptr_array_free(array, TRUE);
+
+               error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                               "InternalError");
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       } else {
+               dbus_g_method_return(context, array);
+               g_ptr_array_free(array, TRUE);
+               return TRUE;
+       }
+}
+
+static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
+                                               gchar *folder_name, guint16 max,
+                                               DBusGMethodInvocation *context)
+{
+       GPtrArray *array = g_ptr_array_new();
+       GValue value;
+       GError *error = NULL;
+
+       char *folder = NULL;
+       int i = 0;
+       int ret = 0;
+       int folder_id = 0;
+       int unread_cnt;
+       guint64 count;
+       gboolean newmsg;
+
+       msg_struct_list_s g_folderList;
+       msg_struct_list_s msg_list;
+       msg_struct_t count_info;
+
+#ifdef SUPPORT_EMAIL
+       int total = 0;
+       int account_id = 0;
+       int mailbox_count = 0;
+       int mail_count = 0;
+       char *type = NULL;
+       char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,};
+       email_mailbox_t *mailbox_list = NULL;
+       email_mail_list_item_t *mail_list = NULL;
+       email_list_filter_t *filter_list = NULL;
+       email_list_sorting_rule_t *sorting_rule_list = NULL;
+#endif
+
+       if (g_msg_handle == NULL)
+               goto fail;
+
+       folder = strrchr(folder_name, '/');
+       if (NULL == folder)
+               folder = folder_name;
+       else
+               folder++;
+
+       ret = msg_get_folder_list(g_msg_handle, &g_folderList);
+       if (ret != MSG_SUCCESS)
+               goto fail;
+
+       for (i = 0; i < g_folderList.nCount; i++) {
+               msg_struct_t pFolder = g_folderList.msg_struct_info[i];
+               char folderName[BT_MAP_MSG_INFO_MAX] = {0, };
+
+               ret = msg_get_str_value(pFolder, MSG_FOLDER_INFO_NAME_STR,
+                                       folderName, BT_MAP_MSG_INFO_MAX);
+               if (ret  != MSG_SUCCESS)
+                       continue;
+
+               if (!g_ascii_strncasecmp(folderName, folder, strlen(folder))) {
+                       ret = msg_get_int_value(pFolder, MSG_FOLDER_INFO_ID_INT,
+                                                               &folder_id);
+                       if (ret != MSG_SUCCESS)
+                               goto fail;
+                       else
+                               DBG("folder_id %d \n", folder_id);
+
+                       break;
+               }
+       }
+
+       ret = msg_get_folder_view_list(g_msg_handle, folder_id,
+                                                       NULL, &msg_list);
+       if (ret  != MSG_SUCCESS)
+               goto fail;
+
+       count = msg_list.nCount;
+
+       count_info = msg_create_struct(MSG_STRUCT_COUNT_INFO);
+       ret = msg_count_message(g_msg_handle, folder_id, count_info);
+       if (ret != MSG_SUCCESS) {
+               msg_release_struct(&count_info);
+               goto fail;
+       }
+
+       ret = msg_get_int_value(count_info, MSG_COUNT_INFO_UNREAD_INT,
+                                                               &unread_cnt);
+       if (ret != MSG_SUCCESS) {
+               msg_release_struct(&count_info);
+               goto fail;
+       }
+
+       if (unread_cnt != 0)
+               newmsg = TRUE;
+       else
+               newmsg = FALSE;
+
+       msg_release_struct(&count_info);
+
+       DBG("MaxlistCount %d \n", max);
+       if (max == 0)
+               goto done;
+
+       for (i = 0; i < msg_list.nCount; i++) {
+
+               struct message_info msg_info;
+
+               memset(&value, 0, sizeof(GValue));
+               g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST);
+               g_value_take_boxed(&value, dbus_g_type_specialized_construct(
+                                               DBUS_STRUCT_MESSAGE_LIST));
+
+               msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]);
+
+/* Keeping the bleow debug till stabilization is done. */
+
+/*
+       DBG("msg_info.handle = %s\n", msg_info.handle);
+       DBG("msg_info.subject = %s\n", msg_info.subject);
+       DBG("msg_info.datetime = %s\n", msg_info.datetime);
+       DBG("msg_info.sender_name = %s\n", msg_info.sender_name);
+       DBG("msg_info.sender_addressing = %s\n", msg_info.sender_addressing);
+       DBG("msg_info.replyto_addressing = %s\n", msg_info.replyto_addressing);
+       DBG("msg_info.recipient_name = %s\n", msg_info.recipient_name);
+       DBG("msg_info.recipient_addressing = %s\n",
+                                       msg_info.recipient_addressing);
+       DBG("msg_info.type = %s\n", msg_info.type);
+       DBG("msg_info.reception_status = %s\n", msg_info.reception_status);
+       DBG("msg_info.size = %s\n", msg_info.size);
+       DBG("msg_info.attachment_size = %s\n", msg_info.attachment_size);
+       DBG("msg_info.text = %d\n", msg_info.text);
+       DBG("msg_info.read = %d\n", msg_info.read);
+       DBG("msg_info.sent = %d\n", msg_info.sent);
+       DBG("msg_info.protect = %d\n", msg_info.protect);
+       DBG("msg_info.priority = %d\n", msg_info.priority);
+*/
+
+               dbus_g_type_struct_set(&value, 0, msg_info.handle,
+                                       1, msg_info.subject,
+                                       2, msg_info.datetime,
+                                       3, msg_info.sender_name,
+                                       4, msg_info.sender_addressing,
+                                       5, msg_info.recipient_name,
+                                       6, msg_info.recipient_addressing,
+                                       7, msg_info.type,
+                                       8, msg_info.size,
+                                       9, msg_info.reception_status,
+                                       10, msg_info.text,
+                                       11, msg_info.attachment_size,
+                                       12, msg_info.priority,
+                                       13, msg_info.read,
+                                       14, msg_info.sent,
+                                       15, msg_info.protect,
+                                       16, msg_info.replyto_addressing, G_MAXUINT);
+               g_ptr_array_add(array, g_value_get_boxed(&value));
+
+               __bt_message_info_free(msg_info);
+       }
+
+#ifdef SUPPORT_EMAIL
+email:
+       if (EMAIL_ERROR_NONE != email_load_default_account_id(&account_id)) {
+               if (!msg_ret)
+                       goto fail;
+       }
+
+       if (EMAIL_ERROR_NONE != email_get_mailbox_list(account_id,
+                                                       EMAIL_MAILBOX_ALL,
+                                                       &mailbox_list,
+                                                       &mailbox_count)) {
+               if (!msg_ret)
+                       goto fail;
+       }
+
+       if (mailbox_list == NULL)
+               goto fail;
+
+       for (i = 0; i < mailbox_count; i++) {
+               DBG("mailbox alias = %s \n", mailbox_list[i].alias);
+               if (!g_ascii_strncasecmp(mailbox_list[i].alias, folder,
+                       strlen(folder))) {
+                       total = mailbox_list[i].total_mail_count_on_server;
+                       DBG("Total mail on sever:%d\n", total);
+                       DBG("mailbox name:%s\n", mailbox_list[i].mailbox_name);
+
+                       break;
+               }
+
+               if (!msg_ret)
+                       goto fail;
+               else
+                       goto done;
+       }
+
+       /* Need to modify the filter code, have to make it dynamic
+          based on remote device request Also to check whether it needs
+          to be done in agent or in obexd */
+
+       filter_list = g_new0(email_list_filter_t, 3);
+       filter_list[0].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
+       filter_list[0].list_filter_item.rule.target_attribute =
+                                               EMAIL_MAIL_ATTRIBUTE_ACCOUNT_ID;
+       filter_list[0].list_filter_item.rule.rule_type =
+                                               EMAIL_LIST_FILTER_RULE_EQUAL;
+       filter_list[0].list_filter_item.rule.key_value.integer_type_value =
+                                                               account_id;
+
+       filter_list[1].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR;
+       filter_list[1].list_filter_item.operator_type =
+                                               EMAIL_LIST_FILTER_OPERATOR_AND;
+
+       filter_list[2].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
+       filter_list[2].list_filter_item.rule.target_attribute =
+                                       EMAIL_MAIL_ATTRIBUTE_MAILBOX_NAME;
+       filter_list[2].list_filter_item.rule.rule_type =
+                                               EMAIL_LIST_FILTER_RULE_EQUAL;
+       type = g_strdup(mailbox_list[i].mailbox_name);
+       filter_list[2].list_filter_item.rule.key_value.string_type_value = type;
+       filter_list[2].list_filter_item.rule.case_sensitivity = true;
+
+       sorting_rule_list = g_new0(email_list_sorting_rule_t, 1);
+       sorting_rule_list->target_attribute = EMAIL_MAIL_ATTRIBUTE_DATE_TIME;
+       sorting_rule_list->sort_order = EMAIL_SORT_ORDER_ASCEND;
+
+       ret = email_get_mail_list_ex(filter_list, 3,
+                                       sorting_rule_list, 1, 0, total - 1,
+                                       &mail_list, &mail_count);
+
+       DBG("email API ret %d  \n", ret);
+       if (ret != EMAIL_ERROR_NONE) {
+               if (!msg_ret) {
+                       g_free(type);
+                       g_free(filter_list);
+                       g_free(sorting_rule_list);
+                       goto fail;
+               } else
+                       goto done;
+       }
+
+       for (i = 0; i < mail_count; ++i) {
+               time_t time = {0,};
+               memset(&value, 0, sizeof(GValue));
+               g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST);
+               g_value_take_boxed(&value, dbus_g_type_specialized_construct(
+                                       DBUS_STRUCT_MESSAGE_LIST));
+
+               uid = __bt_add_id(mail_list[i].mail_id);
+               snprintf(msg_handle, sizeof(msg_handle), "%llx", uid);
+
+               g_strlcpy(msg_type,  "EMAIL", sizeof(msg_type));
+
+               time = mail_list[i].date_time;
+               __get_msg_timestamp(&time, msg_datetime);
+
+               dbus_g_type_struct_set(&value, 0, msg_handle, 1, msg_type,
+                                       2, msg_datetime, G_MAXUINT);
+               g_ptr_array_add(array, g_value_get_boxed(&value));
+       }
+
+       if (mailbox_list != NULL)
+                email_free_mailbox(&mailbox_list, mailbox_count);
+       if (mail_list != NULL)
+               g_free(mail_list);
+
+       g_free(filter_list);
+       g_free(sorting_rule_list);
+       g_free(type);
+#endif
+
+done:
+       DBG("Request completed \n");
+       dbus_g_method_return(context, newmsg, count, array);
+       g_ptr_array_free(array, TRUE);
+       DBG("Request completed successfully \n");
+       return TRUE;
+
+fail:
+       g_ptr_array_free(array, TRUE);
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                         "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
+                                               gchar *message_name,
+                                               gboolean attach,
+                                               gboolean transcode,
+                                               gboolean first_request,
+                                               DBusGMethodInvocation *context)
+{
+       DBG("+ \n");
+       char *buf = NULL;
+       int message_id = 0;
+       int msg_type = BT_SMS;
+
+       GError *error = NULL;
+
+       msg_struct_t msg = NULL;
+       msg_struct_t send_opt = NULL;
+#ifdef SUPPORT_EMAIL
+       email_mail_data_t *mail_data = NULL;
+#endif
+       message_id = __bt_get_uid(message_name);
+       if (message_id == -1)
+               goto fail;
+
+       DBG("message_id %d \n", message_id);
+       DBG("msg_type %d \n", msg_type);
+       DBG("attach %d \n", attach);
+       DBG("transcode %d \n", transcode);
+       DBG("first_request %d \n", first_request);
+
+       if (msg_type == BT_SMS) {
+               if (g_msg_handle == NULL)
+                       goto fail;
+
+               msg_error_t msg_err;
+
+               msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+               send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+
+               msg_err = msg_get_message(g_msg_handle,
+                                               (msg_message_id_t)message_id,
+                                               msg, send_opt);
+               if (msg_err != MSG_SUCCESS)
+                       goto fail;
+
+               buf = __bt_prepare_msg_bmseg(msg, attach, transcode);
+
+               msg_release_struct(&msg);
+               msg_release_struct(&send_opt);
+#ifdef SUPPORT_EMAIL
+       } else if (msg_type == BT_EMAIL) {
+
+               FILE *body_file;
+               int account_id;
+               long read_size;
+               long email_size;
+
+               if (EMAIL_ERROR_NONE !=
+                               email_load_default_account_id(&account_id))
+                       goto fail;
+
+               if (EMAIL_ERROR_NONE !=
+                               email_get_mail_data(message_id, &mail_data))
+                       goto fail;
+
+               body_file = fopen(mail_data->file_path_plain, "r");
+               if (body_file == NULL)
+                       body_file = fopen(mail_data->file_path_html, "rb");
+
+               if (body_file != NULL) {
+                       fseek(body_file , 0, SEEK_END);
+                       email_size = ftell(body_file);
+                       rewind(body_file);
+
+                       buf = (char *)g_malloc0(sizeof(char) * email_size);
+
+                       read_size = fread(buf, 1, email_size, body_file);
+
+                       fclose(body_file);
+
+                       if (read_size != email_size)
+                               goto fail;
+               } else
+                       buf = (char *)g_strdup("");
+
+               email_free_mail_data(&mail_data, 1);
+#endif
+       } else {
+               DBG("msg_type not supported %d \n", msg_type);
+               goto fail;
+       }
+
+       dbus_g_method_return(context, FALSE, buf);
+       g_free(buf);
+
+       DBG("- \n");
+       return TRUE;
+
+fail:
+       g_free(buf);
+
+       if (msg)
+               msg_release_struct(&msg);
+
+       if (send_opt)
+               msg_release_struct(&send_opt);
+
+#ifdef SUPPORT_EMAIL
+       if (mail_data)
+               email_free_mail_data(&mail_data, 1);
+#endif
+
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
+                                       gboolean save_copy,
+                                       gboolean retry_send,
+                                       gboolean native,
+                                       gchar *folder_name,
+                                       DBusGMethodInvocation *context)
+{
+       DBG("+\n");
+       GError *error = NULL;
+       guint64 handle = 0;
+       int folder_id;
+
+       DBG("folder_name = %s\n", folder_name);
+
+       folder_id = __bt_get_folder_id(folder_name);
+       if (folder_id == -1)
+               goto fail;
+
+       handle = __bt_add_id(-1);
+       current_push_map_id = handle;
+
+       /* FALSE : Keep messages in Sent folder */
+       /* TRUE : don't keep messages in sent folder */
+       opt.save_copy = save_copy;
+       DBG("opt.save_copy = %d\n", opt.save_copy);
+
+       /* FALSE : don't retry */
+       /* TRUE  : retry */
+       opt.retry_send = retry_send;
+       DBG("opt.retry_send = %d\n", opt.retry_send);
+
+       /* FALSE : native */
+       /* TRUE : UTF-8 */
+       opt.native = native;
+       DBG("opt.native = %d\n", opt.native);
+
+       dbus_g_method_return(context, handle);
+       DBG("-\n");
+       return TRUE;
+fail:
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                               "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+
+       return FALSE;
+}
+
+static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
+                                       gchar *bmsg,
+                                       DBusGMethodInvocation *context)
+{
+       DBG("+\n");
+       int id = -1;
+       int folder_id;
+       char *folder = NULL;
+       char *body = NULL;
+       GSList *recepients = NULL;
+       gboolean send = FALSE;
+
+       GError *error = NULL;
+
+       DBG("BMSG is \n %s", bmsg);
+
+       struct bmsg_data *bmsg_info = NULL;
+
+       bmsg_info = bmsg_parse(bmsg);
+       if (!bmsg_info)
+               goto done;
+
+       folder = bmsg_get_msg_folder(bmsg_info);
+       if (folder == NULL)
+               goto done;
+
+       folder_id = __bt_get_folder_id(bmsg_info->folder);
+       if (folder_id == -1)
+               goto done;
+
+       if (MSG_OUTBOX_ID == folder_id)
+               send = TRUE;
+
+       body = bmsg_get_msg_body(bmsg_info);
+       if (body == NULL)
+               goto done;
+
+       recepients = bmsg_get_msg_recepients(bmsg_info);
+
+       id = __bt_push_sms(send, folder_id, body, recepients);
+       if (id == -1)
+               goto done;
+
+       __bt_update_id(current_push_map_id, id);
+
+done:
+       g_free(folder);
+       g_free(body);
+       g_slist_free(recepients);
+       g_free(bmsg_info);
+
+       if (id == -1) {
+               error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               DBG("-\n");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       DBG("-\n");
+       return TRUE;
+}
+
+static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
+                                               DBusGMethodInvocation *context)
+{
+       int err = TRUE;
+#ifdef SUPPORT_EMAIL
+       int handle;
+       err = email_sync_header_for_all_account(&handle);
+
+       if (err == EMAIL_ERROR_NONE) {
+               DBG("Handle to stop download = %d \n", handle);
+       } else {
+               ERR("Message Update failed \n");
+       }
+
+       dbus_g_method_return(context, err);
+       return (err == EMAIL_ERROR_NONE) ? TRUE : FALSE;
+#else
+       dbus_g_method_return(context, err);
+       return TRUE;
+#endif
+}
+
+static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
+                                               gchar *handle,
+                                               gboolean read_status,
+                                               DBusGMethodInvocation *context)
+{
+       int message_id = 0;
+       int msg_type = BT_SMS;
+#ifdef SUPPORT_EMAIL
+       email_mail_data_t *mail_data = NULL;
+#endif
+       GError *error = NULL;
+
+       DBG("+\n");
+
+       message_id = __bt_get_uid(handle);
+       if (message_id == -1)
+               goto fail;
+
+       DBG("message_id = %d,  read_status = %d\n", message_id, read_status);
+
+       if (msg_type == BT_SMS) {
+               msg_error_t msg_err;
+               msg_struct_t msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+               msg_struct_t send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+               int msg_type = 0;
+
+               msg_err = msg_get_message(g_msg_handle,
+                                               (msg_message_id_t)message_id,
+                                               msg, send_opt);
+               if (msg_err != MSG_SUCCESS) {
+                       msg_release_struct(&msg);
+                       msg_release_struct(&send_opt);
+                       goto fail;
+               }
+
+               msg_err = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT,
+                                                               &msg_type);
+               if (msg_err != MSG_SUCCESS) {
+                       msg_release_struct(&msg);
+                       msg_release_struct(&send_opt);
+                       goto fail;
+               }
+
+               msg_err = msg_update_read_status(g_msg_handle, message_id,
+                                                               read_status);
+               if (msg_err != MSG_SUCCESS) {
+                       msg_release_struct(&msg);
+                       msg_release_struct(&send_opt);
+                       goto fail;
+               }
+
+               if (__bt_msg_is_mms(msg_type)) {
+                       if (read_status == TRUE)
+                               msg_err = msg_mms_send_read_report(g_msg_handle,
+                                               message_id,
+                                               MSG_READ_REPORT_IS_READ);
+                       else
+                               msg_err = msg_mms_send_read_report(g_msg_handle,
+                                               message_id,
+                                               MSG_READ_REPORT_NONE);
+               }
+
+               msg_release_struct(&msg);
+               msg_release_struct(&send_opt);
+
+               if (msg_err != MSG_SUCCESS)
+                       goto fail;
+#ifdef SUPPORT_EMAIL
+       } else if (msg_type == BT_EMAIL) {
+
+               if (email_get_mail_data(message_id, &mail_data) !=
+                                                       EMAIL_ERROR_NONE) {
+                       ERR("email_get_mail_data failed\n");
+                       goto fail;
+               }
+
+               if (email_set_flags_field(mail_data->account_id, &message_id, 1,
+                       EMAIL_FLAGS_SEEN_FIELD, read_status, 0) !=
+                                                       EMAIL_ERROR_NONE) {
+                       email_free_mail_data(&mail_data, 1);
+                       goto fail;
+               }
+
+               email_free_mail_data(&mail_data, 1);
+       } else {
+               goto fail;
+       }
+#else
+       }
+#endif
+
+       dbus_g_method_return(context);
+       DBG("-\n");
+       return TRUE;
+
+fail:
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+
+       return FALSE;
+}
+
+static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
+                                               gchar *handle,
+                                               gboolean delete_status,
+                                               DBusGMethodInvocation *context)
+{
+       int message_id = 0;
+       int msg_type = BT_SMS;
+#ifdef SUPPORT_EMAIL
+       email_mail_data_t *mail_data = NULL;
+#endif
+       GError *error = NULL;
+
+       DBG("+\n");
+
+       message_id = __bt_get_uid(handle);
+       if (message_id == -1)
+               goto fail;
+
+       DBG("message_id = %d, delete_status = %d\n", message_id, delete_status);
+
+       if (msg_type == BT_SMS) {
+               if (msg_delete_message(g_msg_handle, message_id) !=
+                                                               MSG_SUCCESS) {
+                       goto fail;
+               }
+#ifdef SUPPORT_EMAIL
+       } else if (msg_type == BT_EMAIL) {
+
+               if (email_get_mail_data(message_id, &mail_data) !=
+                                                       EMAIL_ERROR_NONE)
+                       goto fail;
+
+               if (email_delete_mail(mail_data->mailbox_id, &message_id,
+                                               1, 1) != EMAIL_ERROR_NONE) {
+                       email_free_mail_data(&mail_data, 1);
+                       goto fail;
+               }
+
+               email_free_mail_data(&mail_data, 1);
+       } else {
+               goto fail;
+       }
+#else
+       }
+#endif
+
+       dbus_g_method_return(context);
+       DBG("-\n");
+       return TRUE;
+
+fail:
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
+                                               gchar *remote_addr,
+                                               gboolean status,
+                                               DBusGMethodInvocation *context)
+{
+       DBG("remote_addr = %s \n", remote_addr);
+
+       if (status == TRUE)
+               __bt_mns_client_connect(remote_addr);
+       else
+               __bt_mns_client_disconnect();
+
+       return TRUE;
+}
+
+int main(int argc, char **argv)
+{
+       BluetoothMapAgent *bluetooth_map_obj = NULL;
+       DBusGProxy *bus_proxy = NULL;
+       guint result = 0;
+       GError *error = NULL;
+
+       g_type_init();
+
+       g_mainloop = g_main_loop_new(NULL, FALSE);
+
+       if (g_mainloop == NULL) {
+               ERR("Couldn't create GMainLoop\n");
+               return EXIT_FAILURE;
+       }
+
+       g_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+
+       if (error != NULL) {
+               ERR("Couldn't connect to system bus[%s]\n", error->message);
+               g_error_free(error);
+               return EXIT_FAILURE;
+       }
+
+       bus_proxy = dbus_g_proxy_new_for_name(g_connection, DBUS_SERVICE_DBUS,
+                                               DBUS_PATH_DBUS,
+                                               DBUS_INTERFACE_DBUS);
+       if (bus_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               goto failure;
+       }
+
+       if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
+                                       BT_MAP_SERVICE_NAME, G_TYPE_UINT, 0,
+                                       G_TYPE_INVALID, G_TYPE_UINT, &result,
+                                       G_TYPE_INVALID)) {
+               if (error != NULL) {
+                       ERR("RequestName RPC failed[%s]\n", error->message);
+                       g_error_free(error);
+               }
+               goto failure;
+       }
+       DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+               ERR("Failed to get the primary well-known name.\n");
+               goto failure;
+       }
+
+       g_object_unref(bus_proxy);
+       bus_proxy = NULL;
+
+       bluetooth_map_obj = g_object_new(BLUETOOTH_MAP_TYPE_AGENT, NULL);
+       if (bluetooth_map_obj == NULL) {
+               ERR("Failed to create one BluetoothMapAgent instance.\n");
+               goto failure;
+       }
+
+       /* Registering it on the D-Bus */
+       dbus_g_connection_register_g_object(g_connection,
+                                               BT_MAP_SERVICE_OBJECT_PATH,
+                                               G_OBJECT(bluetooth_map_obj));
+
+       if (__bluetooth_map_start_service() == FALSE)
+               goto failure;
+
+       g_main_loop_run(g_mainloop);
+
+ failure:
+       DBG("Terminate the bluetooth-map-agent\n");
+
+       __bt_remove_list(id_list);
+
+       if (g_mns_path)
+               __bt_mns_client_disconnect();
+       if (bus_proxy)
+               g_object_unref(bus_proxy);
+       if (bluetooth_map_obj)
+               g_object_unref(bluetooth_map_obj);
+       if (g_connection)
+               dbus_g_connection_unref(g_connection);
+
+
+       __bluetooth_map_stop_service();
+       return EXIT_FAILURE;
+}
diff --git a/mobile/map-agent/bluetooth_map_agent.h b/mobile/map-agent/bluetooth_map_agent.h
new file mode 100644 (file)
index 0000000..14ab97c
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_PB_AGENT_H_
+#define __DEF_BT_PB_AGENT_H_
+
+#include <unistd.h>
+#include <dlog.h>
+
+#include <stdio.h>
+
+#include <dbus/dbus-glib.h>
+
+#define BT_MAP_AGENT_ERROR (__bt_map_agent_error_quark())
+
+typedef enum {
+       BT_MAP_AGENT_ERROR_INTERNAL,
+       BT_MAP_AGENT_ERROR_CANCEL,
+} bt_map_agent_error_t;
+
+#define BT_MAP_SERVICE_OBJECT_PATH "/org/bluez/map_agent"
+#define BT_MAP_SERVICE_NAME "org.bluez.map_agent"
+#define BT_MAP_SERVICE_INTERFACE "org.bluez.MapAgent"
+
+#undef LOG_TAG
+#define LOG_TAG "BLUETOOTH_AGENT_MESSAGE"
+
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#endif /* __DEF_BT_AGENT_H_ */
diff --git a/mobile/map-agent/bluetooth_map_agent.xml b/mobile/map-agent/bluetooth_map_agent.xml
new file mode 100644 (file)
index 0000000..fea0177
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<node name="/">
+       <interface name="org.bluez.MapAgent">
+               <method name="GetFolderTree">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="a(s)" name="folder_list" direction="out"/>
+               </method>
+               <method name="GetMessageList">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="folder_name"/>
+                       <arg type="q" name="max"/>
+                       <arg type="b" name="newmessage" direction="out"/>
+                       <arg type="t" name="count" direction="out"/>
+                       <arg type="a(ssssssssssbsbbbbs)" name="msg_list" direction="out"/>
+               </method>
+               <method name="GetMessage">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="messgae_name"/>
+                       <arg type="b" name="attach"/>
+                       <arg type="b" name="transcode"/>
+                       <arg type="b" name="first_request"/>
+                       <arg type="b" name="fraction_deliver" direction="out"/>
+                       <arg type="s" name="msg_body" direction="out"/>
+               </method>
+               <method name="PushMessage">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="b" name="save_copy"/>
+                       <arg type="b" name="retry_send"/>
+                       <arg type="b" name="native"/>
+                       <arg type="s" name="folder_name"/>
+                       <arg type="t" name="handle" direction="out"/>
+               </method>
+               <method name="PushMessageData">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="bmsg"/>
+               </method>
+               <method name="UpdateMessage">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+               <method name="SetReadStatus">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="handle"/>
+                       <arg type="b" name="read_status"/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+               <method name="SetDeleteStatus">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="handle"/>
+                       <arg type="b" name="delete_status"/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+               <method name="NotiRegistration">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="remote_addr"/>
+                       <arg type="b" name="status"/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+       </interface>
+</node>
diff --git a/mobile/map-agent/map_bmessage.c b/mobile/map-agent/map_bmessage.c
new file mode 100644 (file)
index 0000000..febfe03
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include <map_bmessage.h>
+
+#include <bluetooth_map_agent.h>
+
+#define CRLF_LEN 2
+
+#define BMSG_TAG "BEGIN:BMSG\r\n"
+#define VER_TAG "VERSION:"
+#define STATUS_TAG "STATUS:"
+#define TYPE_TAG "TYPE:"
+#define FOLDER_TAG "FOLDER:"
+#define VCARD_BEGIN_TAG "BEGIN:VCARD\r\n"
+#define VCARD_END_TAG "END:VCARD\r\n"
+#define VCARD_N_TAG "N:"
+#define VCARD_FN_TAG "FN:"
+#define VCARD_TEL_TAG "TEL:"
+#define VCARD_EMAIL_TAG "EMAIL:"
+#define BENV_TAG "BEGIN:BENV\r\n"
+#define BBODY_TAG "BEGIN:BBODY\r\n"
+#define MSG_TAG "BEGIN:MSG\r\n"
+#define PARTID_TAG "PARTID:"
+#define ENCODING_TAG "ENCODING:"
+#define CHARSET_TAG "CHARSET:"
+#define LANGUAGE_TAG "LANGUAGE:"
+#define LENGTH_TAG "LENGTH:"
+
+
+void print_bmsg(struct bmsg_data *bmsg)
+{
+       if (bmsg == NULL)
+               return;
+
+       struct benv_data *env_data = NULL;
+
+       DBG("bmsg->version = %s", bmsg->version);
+       DBG("bmsg->status = %s", bmsg->status);
+       DBG("bmsg->type = %s", bmsg->type);
+       DBG("bmsg->folder = %s", bmsg->folder);
+       DBG("bmsg->originator_vcard_data->version = %s",
+                                       bmsg->originator_vcard_data->version);
+       DBG("bmsg->originator_vcard_data->n = %s",
+                                       bmsg->originator_vcard_data->n);
+
+       int i = 0;
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       while (env_data != NULL) {
+
+               DBG("env_data = %d", env_data->encapsulation_level);
+               int k = 0;
+               struct bmsg_vcard *rvcard;
+
+               rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+
+               while (rvcard != NULL) {
+                       k++;
+
+                       if (rvcard->version != NULL)
+                               DBG("vcard->version = %s\n", rvcard->version);
+                       if (rvcard->n != NULL)
+                               DBG("vcard->n = %s\n", rvcard->n);
+                       if (rvcard->fn != NULL)
+                               DBG("vcard->fn = %s\n", rvcard->fn);
+                       if (rvcard->tel != NULL)
+                               DBG("vcard->tel = %s\n", rvcard->tel);
+                       if (rvcard->email != NULL)
+                               DBG("vcard->email = %s\n", rvcard->email);
+
+                       rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               }
+
+               if (env_data->body_content != NULL) {
+                       DBG("env_data->body_content->length = %"
+                                               G_GUINT64_FORMAT "\n",
+                                               env_data->body_content->length);
+                       DBG("env_data->body_content->msg = %s\n",
+                                               env_data->body_content->msg);
+               }
+
+               i++;
+
+               if (i > 2)
+                       break;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+}
+
+char *bmsg_get_msg_folder(struct bmsg_data *bmsg)
+{
+       return g_strdup(bmsg->folder);
+}
+
+char *bmsg_get_msg_body(struct bmsg_data *bmsg)
+{
+       struct benv_data *env_data;
+       int i = 0;
+
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+
+       while (env_data != NULL) {
+               if (env_data->body_content != NULL) {
+                       DBG("env_data->body_content->msg = %s\n",
+                                               env_data->body_content->msg);
+                       DBG("env_data->body_content->length = %"
+                                               G_GUINT64_FORMAT "\n",
+                                               env_data->body_content->length);
+                       return g_strndup(env_data->body_content->msg,
+                                                               env_data->body_content->length);
+               }
+
+               i++;
+               if (i > 2)
+                       break;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+
+       return NULL;
+}
+
+GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg)
+{
+       struct benv_data *env_data;
+       GSList *receiver = NULL;
+       int i = 0;
+
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+
+       while (env_data != NULL) {
+
+               DBG("env_data = %d", env_data->encapsulation_level);
+               int k = 0;
+               struct bmsg_vcard *rvcard;
+
+               rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               while (rvcard != NULL) {
+                       k++;
+
+                       if (rvcard->tel != NULL) {
+                               DBG("vcard->tel = %s\n", rvcard->tel);
+                               receiver = g_slist_append(receiver, rvcard->tel);
+                       }
+
+                       rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               }
+
+               i++;
+               if (i > 2)
+                       break;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+
+       return receiver;
+}
+
+void bmsg_free_vcard_data(struct bmsg_vcard *vcard_data)
+{
+       if (vcard_data == NULL)
+               return;
+
+       g_free(vcard_data->version);
+       g_free(vcard_data->n);
+       g_free(vcard_data->fn);
+       g_free(vcard_data->tel);
+       g_free(vcard_data->email);
+       g_free(vcard_data);
+
+       return;
+}
+
+void bmsg_free_bmsg(struct bmsg_data *bmsg)
+{
+       struct benv_data *env_data;
+       int i = 0;
+
+       if (bmsg == NULL)
+               return;
+
+       g_free(bmsg->version);
+       g_free(bmsg->status);
+       g_free(bmsg->type);
+       g_free(bmsg->folder);
+       bmsg_free_vcard_data(bmsg->originator_vcard_data);
+
+       if (bmsg->envelope_data == NULL)
+               goto done;
+
+       if (bmsg->envelope_data->env_data == NULL)
+               goto done;
+
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       while (env_data != NULL) {
+
+               DBG("env_data = %d", env_data->encapsulation_level);
+               int k = 0;
+               struct bmsg_vcard *rvcard;
+
+               rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+
+               while (rvcard != NULL) {
+                       k++;
+                       bmsg_free_vcard_data(rvcard);
+                       rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               }
+
+               if (env_data->body_content != NULL) {
+                       g_free(env_data->body_content->encoding);
+                       g_free(env_data->body_content->charset);
+                       g_free(env_data->body_content->language);
+                       g_free(env_data->body_content->msg);
+                       g_free(env_data->body_content);
+               }
+
+               g_free(env_data);
+               i++;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+
+done:
+       g_free(bmsg);
+}
+
+gchar *bmsg_get_parse_sub_block(char **sub_block_data, char *element)
+{
+       gchar *start;
+       gchar *end;
+       gchar *block_start;
+       gchar *block_end;
+       gchar *sub_block = NULL;
+       size_t offset;
+       size_t len;
+
+       DBG("");
+
+       start = g_strdup_printf("BEGIN:%s\r\n", element);
+       end = g_strdup_printf("END:%s\r\n", element);
+       offset = strlen(start);
+
+       block_start = g_strstr_len(*sub_block_data, offset, start);
+       if (block_start == NULL)
+               goto done;
+
+       if (!g_strcmp0(start, VCARD_BEGIN_TAG))
+               block_end = g_strstr_len(*sub_block_data, -1,  end);
+       else
+               block_end = g_strrstr(*sub_block_data, end);
+
+       if (block_end == NULL)
+               goto done;
+
+       len = block_end - block_start - offset;
+       sub_block = g_strndup(block_start + offset, len);
+       *sub_block_data = *sub_block_data + strlen(sub_block) + strlen(start) +
+                                                                strlen(end);
+done:
+       g_free(start);
+       g_free(end);
+       return sub_block;
+}
+
+gchar *bmsg_get_tag_data(char **block_data, char *element)
+{
+       gchar *end = "\r\n";
+       gchar *block_start;
+       gchar *block_end;
+       gchar *sub_block;
+       size_t offset;
+       size_t len;
+
+       DBG("");
+
+       if (*block_data == NULL || element == NULL)
+               return NULL;
+
+       block_start = g_strstr_len(*block_data, -1, element);
+       if (block_start == NULL)
+               return NULL;
+
+       offset = strlen(element);
+
+       block_end = g_strstr_len(block_start+offset, -1, end);
+       if (block_end == NULL)
+               return NULL;
+
+       len = block_end - block_start - offset;
+       sub_block = g_strndup(block_start + offset, len);
+       *block_data = *block_data + offset + len + CRLF_LEN;
+
+       return sub_block;
+}
+
+struct bmsg_bbody *bmsg_get_bbody_data(gchar *block_data)
+{
+       gchar *bbody_block_data_start;
+       gchar *temp;
+       struct bmsg_bbody *bbody;
+       DBG("");
+
+       bbody_block_data_start = block_data;
+
+       bbody = g_new0(struct bmsg_bbody, 1);
+
+       temp = bmsg_get_tag_data(&block_data, PARTID_TAG);
+       if (temp != NULL) {
+               bbody->part_id = (guint16)g_ascii_strtoull(temp, NULL, 10);
+               g_free(temp);
+       }
+
+       bbody->encoding = bmsg_get_tag_data(&block_data, ENCODING_TAG);
+       bbody->charset = bmsg_get_tag_data(&block_data, CHARSET_TAG);
+       bbody->language = bmsg_get_tag_data(&block_data, LANGUAGE_TAG);
+
+       temp = bmsg_get_tag_data(&block_data, LENGTH_TAG);
+
+       if (temp != NULL) {
+               bbody->length = g_ascii_strtoull(temp, NULL, 10);
+               g_free(temp);
+       }
+
+       bbody->msg = bmsg_get_parse_sub_block(&block_data, "MSG");
+
+       g_free(bbody_block_data_start);
+
+       return bbody;
+}
+
+struct bmsg_vcard *bmsg_get_vcard_data(gchar *sub_block_data)
+{
+       gchar *vcard_block_data_start;
+       struct bmsg_vcard *vcard;
+       DBG("");
+
+       vcard_block_data_start = sub_block_data;
+
+       vcard = g_new0(struct bmsg_vcard, 1);
+
+       vcard->version = bmsg_get_tag_data(&sub_block_data, VER_TAG);
+       vcard->n = bmsg_get_tag_data(&sub_block_data, VCARD_N_TAG);
+       vcard->fn = bmsg_get_tag_data(&sub_block_data, VCARD_FN_TAG);
+       vcard->tel = bmsg_get_tag_data(&sub_block_data, VCARD_TEL_TAG);
+       vcard->email = bmsg_get_tag_data(&sub_block_data, VCARD_EMAIL_TAG);
+
+       g_free(vcard_block_data_start);
+
+       return vcard;
+}
+
+struct benv_data *bmsg_get_env_encapsulation_data(gchar **sub_block_data)
+{
+       gchar *is_valid;
+       gchar *bbody_data = NULL;
+       static guint8 lvl = 1;
+
+       is_valid = g_strstr_len(*sub_block_data, strlen(VCARD_BEGIN_TAG),
+                                                       VCARD_BEGIN_TAG);
+       if (is_valid == NULL)
+               return NULL;
+
+       if (lvl > 3)
+               return NULL;
+
+       struct benv_data *rec_data = g_new0(struct benv_data, 1);
+
+       rec_data->encapsulation_level = lvl;
+       lvl++;
+
+       while (is_valid != NULL) {
+               gchar *vcard_data = NULL;
+               struct bmsg_vcard *vcard;
+
+               vcard_data = bmsg_get_parse_sub_block(sub_block_data, "VCARD");
+               if (vcard_data == NULL) {
+                       DBG("parse error\n");
+                       g_free(rec_data);
+                       return NULL;
+               }
+               vcard = bmsg_get_vcard_data(vcard_data);
+
+               rec_data->recipient_vcard = g_slist_append(
+                                               rec_data->recipient_vcard,
+                                               vcard);
+
+               is_valid = g_strstr_len(*sub_block_data,
+                                               strlen(VCARD_BEGIN_TAG),
+                                               VCARD_BEGIN_TAG);
+       }
+
+       is_valid = g_strstr_len(*sub_block_data, strlen(BBODY_TAG), BBODY_TAG);
+
+       if (!is_valid)
+               return rec_data;
+
+       bbody_data = bmsg_get_parse_sub_block(sub_block_data, "BBODY");
+       if (bbody_data == NULL) {
+               DBG("parse error\n");
+               return rec_data;
+       }
+
+       rec_data->body_content = bmsg_get_bbody_data(bbody_data);
+
+       return rec_data;
+}
+
+struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data)
+{
+       gchar *env_block_data_start;
+       gchar *sub_block_data;
+       struct bmsg_envelope *envelope_data;
+       struct benv_data *rec_data;
+
+       env_block_data_start = *block_data;
+
+       envelope_data = g_new0(struct bmsg_envelope, 1);
+
+       sub_block_data = bmsg_get_parse_sub_block(block_data, "BENV");
+
+       while (sub_block_data) {
+
+               rec_data = bmsg_get_env_encapsulation_data(&sub_block_data);
+
+               while (rec_data) {
+                       envelope_data->env_data = g_slist_append(
+                                                       envelope_data->env_data,
+                                                       rec_data);
+
+                       rec_data = bmsg_get_env_encapsulation_data(
+                                                       &sub_block_data);
+               }
+               sub_block_data = bmsg_get_parse_sub_block(&sub_block_data,
+                                                                       "BENV");
+       }
+       g_free(sub_block_data);
+
+       return envelope_data;
+}
+
+struct bmsg_data * bmsg_parse(gchar *buf)
+{
+       gchar *block_data;
+       gchar *sub_block_data;
+       gchar *block_data_start;
+       struct bmsg_data *bmsg;
+
+       DBG("");
+
+       block_data = bmsg_get_parse_sub_block(&buf, "BMSG");
+       if (block_data == NULL)
+               return NULL;
+
+       block_data_start = block_data;
+
+       bmsg = g_new0(struct bmsg_data, 1);
+
+       bmsg->version = bmsg_get_tag_data(&block_data, VER_TAG);
+       if (bmsg->version == NULL)
+               goto parse_fail;
+
+       bmsg->status = bmsg_get_tag_data(&block_data, STATUS_TAG);
+       if (bmsg->status == NULL)
+               goto parse_fail;
+
+       bmsg->type = bmsg_get_tag_data(&block_data, TYPE_TAG);
+       if (bmsg->type == NULL)
+               goto parse_fail;
+
+       bmsg->folder = bmsg_get_tag_data(&block_data, FOLDER_TAG);
+       if (bmsg->folder == NULL)
+               goto parse_fail;
+
+       sub_block_data = bmsg_get_parse_sub_block(&block_data, "VCARD");
+       if (sub_block_data == NULL)
+               goto parse_fail;
+
+       bmsg->originator_vcard_data = bmsg_get_vcard_data(sub_block_data);
+       if (bmsg->originator_vcard_data == NULL)
+               goto parse_fail;
+
+       bmsg->envelope_data = bmsg_get_envelope_data(&block_data);
+       if (bmsg->envelope_data == NULL)
+               goto parse_fail;
+
+       g_free(block_data_start);
+
+       DBG("Parse done");
+       print_bmsg(bmsg);
+
+       return bmsg;
+
+parse_fail:
+       DBG("Parse fail");
+       bmsg_free_bmsg(bmsg);
+
+       return NULL;
+}
+
diff --git a/mobile/map-agent/map_bmessage.h b/mobile/map-agent/map_bmessage.h
new file mode 100644 (file)
index 0000000..4cdadf7
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ #ifndef __BMSG_H
+#define __BMSG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bmsg_vcard {
+       gchar *version;
+       gchar *n;
+       gchar *fn;
+       gchar *tel;
+       gchar *email;
+};
+
+struct bmsg_bbody {
+       guint16 part_id;
+       gchar *encoding;
+       gchar *charset;
+       gchar *language;
+       guint64 length;
+       gchar *msg;
+};
+
+struct benv_data {
+       guint8 encapsulation_level;
+       GSList *recipient_vcard;
+       struct bmsg_bbody *body_content;
+};
+
+struct bmsg_envelope {
+       GSList *env_data;       /* Add benv_data here*/
+};
+
+struct bmsg_data {
+       gchar *version;
+       gchar *status;
+       gchar *type;
+       gchar *folder;
+       struct bmsg_vcard *originator_vcard_data;
+       struct bmsg_envelope *envelope_data;
+};
+
+struct bmsg_data * bmsg_parse(gchar *buf);
+char *bmsg_get_msg_folder(struct bmsg_data *bmsg);
+char *bmsg_get_msg_body(struct bmsg_data *bmsg);
+GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BMSG_H */
diff --git a/mobile/map-agent/org.bluez.map_agent.service b/mobile/map-agent/org.bluez.map_agent.service
new file mode 100644 (file)
index 0000000..b299104
--- /dev/null
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.bluez.map_agent
+Exec=/usr/bin/bluetooth-map-agent
+User=root
diff --git a/mobile/pb-agent/CMakeLists.txt b/mobile/pb-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..73ae41c
--- /dev/null
@@ -0,0 +1,30 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-pb-agent C)
+
+SET(SRCS bluetooth_pb_agent.c bluetooth_pb_vcard.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_pb_agent
+               REQUIRED
+               dbus-glib-1 dlog contacts-service2 tapi vconf capi-media-image-util libexif)
+
+FOREACH(flag ${pkgs_pb_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
+               ARGS "--prefix=bluetooth_pb \\
+               ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_pb_agent.xml \\
+               --mode=glib-server \\
+               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_pb_agent_glue.h")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_pb_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.pb_agent.service
+               DESTINATION share/dbus-1/services)
diff --git a/mobile/pb-agent/bluetooth_pb_agent.c b/mobile/pb-agent/bluetooth_pb_agent.c
new file mode 100644 (file)
index 0000000..926dd10
--- /dev/null
@@ -0,0 +1,2106 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <contacts.h>
+
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+
+#include "bluetooth_pb_agent.h"
+#include "bluetooth_pb_vcard.h"
+
+#define BLUETOOTH_PB_AGENT_TIMEOUT 600
+
+static gchar *bluetooth_pb_agent_folder_list[] = {
+       "/telecom/pb",
+       "/telecom/ich",
+       "/telecom/och",
+       "/telecom/mch",
+       "/telecom/cch",
+       NULL
+};
+
+typedef enum {
+       TELECOM_PB = 0,
+       TELECOM_ICH,
+       TELECOM_OCH,
+       TELECOM_MCH,
+       TELECOM_CCH,
+       TELECOM_NONE
+} PhoneBookType;
+
+typedef struct {
+       GObject parent;
+
+       DBusGConnection *bus;
+       DBusGProxy *proxy;
+
+       TapiHandle *tapi_handle;
+       gchar *tel_number;
+       guint timeout_id;
+
+       PhoneBookType pb_type;
+} BluetoothPbAgent;
+
+typedef struct {
+       GObjectClass parent;
+
+       void (*clear) (BluetoothPbAgent *agent);
+} BluetoothPbAgentClass;
+
+enum {
+       CLEAR,
+       LAST_SIGNAL
+};
+
+GType bluetooth_pb_agent_get_type(void);
+
+#define BLUETOOTH_PB_TYPE_AGENT (bluetooth_pb_agent_get_type())
+
+#define BLUETOOTH_PB_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_CAST((object), \
+       BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgent))
+#define BLUETOOTH_PB_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST((klass), \
+       BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgentClass))
+#define BLUETOOTH_IS_PB_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+       BLUETOOTH_PB_TYPE_AGENT))
+#define BLUETOOTH_IS_PB_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE((klass), \
+       BLUETOOTH_PB_TYPE_AGENT))
+#define BLUETOOTH_PB_AGENT_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS((obj), \
+       BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgentClass))
+
+G_DEFINE_TYPE(BluetoothPbAgent, bluetooth_pb_agent, G_TYPE_OBJECT)
+
+#define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", G_TYPE_STRING, \
+                                                       G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID))
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GMainLoop *mainloop = NULL;
+
+static void bluetooth_pb_agent_finalize(GObject *obj);
+
+static void bluetooth_pb_agent_clear(BluetoothPbAgent *agent);
+
+/* Dbus messages */
+static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
+                                               const gchar ***folder_list,
+                                               GError **error);
+
+static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
+                                       const char *name,
+                                       guint64 filter,
+                                       guint8 format,
+                                       guint16 max_list_count,
+                                       guint16 list_start_offset,
+                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
+                                               const gchar *folder,
+                                               const gchar *id,
+                                               guint64 filter,
+                                               guint8 format,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       gint32 start_index,
+                                       gint32 end_index,
+                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *agent,
+                                                       const gchar *command,
+                                                       const gchar *find_text,
+                                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
+                                               gchar *path,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_add_contact (BluetoothPbAgent *agent,
+                                       const char *filename,
+                                       GError **error);
+
+static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
+                                       DBusGMethodInvocation *context);
+
+static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
+                                       gint code,
+                                       const gchar *message);
+
+static PhoneBookType __bluetooth_pb_get_pb_type(const char *name);
+
+static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name);
+
+static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
+                                               gint *match,
+                                               gint size);
+
+static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
+                                               gint size);
+
+static contacts_query_h __bluetooth_pb_query_person(void);
+
+static contacts_query_h __bluetooth_pb_query_person_number(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_missed(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_combined(void);
+
+static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
+                               guint *count);
+
+static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count);
+
+static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record);
+
+static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               guint64 filter,
+                               guint8 format,
+                               guint16 max_list_count,
+                               guint16 list_start_offset,
+                               GPtrArray *vcards);
+
+static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
+                                       PhoneBookType pb_type,
+                                       const gchar *find_text,
+                                       GPtrArray *ptr_array);
+
+static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
+                                               const gchar *name,
+                                               const gchar *number,
+                                               gint handle);
+
+static void __bluetooth_pb_list_ptr_array_free(gpointer data);
+
+static void __bluetooth_pb_agent_signal_handler(int signum);
+
+static void __bluetooth_pb_contact_changed(const gchar *view_uri,
+                                       void *user_data);
+
+static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent);
+
+static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data);
+
+static void __bluetooth_pb_tel_callback(TapiHandle *handle,
+                                       int result,
+                                       void *data,
+                                       void *user_data);
+
+static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent);
+
+#include "bluetooth_pb_agent_glue.h"
+
+static void bluetooth_pb_agent_init(BluetoothPbAgent *agent)
+{
+       agent->bus = NULL;
+       agent->proxy = NULL;
+       agent->tapi_handle = NULL;
+       agent->tel_number = NULL;
+       agent->timeout_id = 0;
+       agent->pb_type = TELECOM_NONE;
+}
+
+static void bluetooth_pb_agent_class_init(BluetoothPbAgentClass *klass)
+{
+       GObjectClass *object_class = (GObjectClass *) klass;
+
+       klass->clear = bluetooth_pb_agent_clear;
+
+       object_class->finalize = bluetooth_pb_agent_finalize;
+
+       signals[CLEAR] = g_signal_new("clear",
+                       G_TYPE_FROM_CLASS(klass),
+                       G_SIGNAL_RUN_LAST,
+                       G_STRUCT_OFFSET(BluetoothPbAgentClass, clear),
+                       NULL, NULL,
+                       g_cclosure_marshal_VOID__VOID,
+                       G_TYPE_NONE, 0);
+
+       dbus_g_object_type_install_info(BLUETOOTH_PB_TYPE_AGENT,
+                                       &dbus_glib_bluetooth_pb_object_info);
+}
+
+static void bluetooth_pb_agent_finalize(GObject *obj)
+{
+       BluetoothPbAgent *agent  = BLUETOOTH_PB_AGENT(obj);
+
+       DBG("+\n");
+
+       if (agent->tapi_handle) {
+               tel_deinit(agent->tapi_handle);
+               agent->tapi_handle = NULL;
+       }
+
+       if (agent->tel_number) {
+               g_free(agent->tel_number);
+               agent->tel_number = NULL;
+       }
+
+       if(agent->timeout_id) {
+               g_source_remove(agent->timeout_id);
+               agent->timeout_id = 0;
+       }
+
+       if (agent->proxy) {
+               g_object_unref(agent->proxy);
+               agent->proxy = NULL;
+       }
+
+       if (agent->bus) {
+               dbus_g_connection_unref(agent->bus);
+               agent->bus = NULL;
+       }
+
+
+       G_OBJECT_CLASS(bluetooth_pb_agent_parent_class)->finalize(obj);
+}
+
+static void bluetooth_pb_agent_clear(BluetoothPbAgent *agent)
+{
+       DBG("+\n");
+
+       agent->pb_type = TELECOM_NONE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
+                                               const gchar ***folder_list,
+                                               GError **error)
+{
+       gint size;
+       gint i;
+       gchar **folder;
+
+       size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list);
+       folder = g_new0(gchar *, size);
+
+       for (i = 0; i < size; i++)
+               folder[i] = g_strdup(bluetooth_pb_agent_folder_list[i]);
+
+       *folder_list = (const gchar **)folder;
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
+                                       const char *name,
+                                       guint64 filter,
+                                       guint8 format,
+                                       guint16 max_list_count,
+                                       guint16 list_start_offset,
+                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+       GPtrArray *vcards = NULL;
+       gchar **vcards_str = NULL;
+
+       guint new_missed_call = 0;
+
+       DBG_SECURE("name: %s filter: %lld format: %d max_list_count: %d list_start_offset: %d\n",
+                       name, filter, format, max_list_count, list_start_offset);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_pb_type(name);
+
+       if (pb_type == TELECOM_NONE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       vcards = g_ptr_array_new();
+
+       if (max_list_count > 0) {
+               __bluetooth_pb_get_vcards(agent, pb_type,
+                               filter, format,
+                               max_list_count, list_start_offset,
+                               vcards);
+
+       }
+
+       g_ptr_array_add(vcards, NULL);
+
+       vcards_str = (gchar **) g_ptr_array_free(vcards, FALSE);
+
+       dbus_g_method_return(context, vcards_str, new_missed_call);
+
+       g_strfreev(vcards_str);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       guint new_missed_call = 0;
+       guint count = 0;
+
+       DBG_SECURE("name: %s\n", name);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_pb_type(name);
+
+       if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       /* for owner */
+       if (pb_type == TELECOM_PB)
+               count++;
+
+       __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
+
+       dbus_g_method_return(context, count, new_missed_call);
+
+       return TRUE;
+}
+
+
+static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       GPtrArray *ptr_array;
+
+       DBG_SECURE("name: %s\n", name);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_pb_type(name);
+
+       if (pb_type == TELECOM_NONE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
+
+       __bluetooth_pb_get_list(agent, pb_type, ptr_array);
+
+       dbus_g_method_return(context, ptr_array);
+
+       if (ptr_array)
+               g_ptr_array_free(ptr_array, TRUE);
+
+       return TRUE;
+}
+
+
+static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
+                                               const gchar *folder,
+                                               const gchar *id,
+                                               guint64 filter,
+                                               guint8 format,
+                                               DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       gint handle = 0;
+       gchar *str = NULL;
+
+       const gchar *attr = NULL;
+
+       DBG_SECURE("folder: %s id: %s filter: %ld format: %d\n",
+                       folder, id, filter, format);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       if (!g_str_has_suffix(id, ".vcf")) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "invalid vcf file");
+               return FALSE;
+       }
+
+       handle = (gint)g_ascii_strtoll(id, NULL, 10);
+
+       pb_type = __bluetooth_pb_get_pb_type(folder);
+
+       if (pb_type == TELECOM_NONE) {
+               __bluetooth_pb_dbus_return_error(context,
+                               G_FILE_ERROR_INVAL,
+                               "unsupported name defined");
+               return FALSE;
+       }
+
+       /* create index cache */
+       __bluetooth_pb_get_list(agent, pb_type, NULL);
+
+       switch(pb_type) {
+       case TELECOM_PB:
+               if (handle == 0) {
+                       str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
+                                                               filter, format);
+               } else {
+                       str = _bluetooth_pb_vcard_contact(handle, filter, format);
+               }
+               break;
+       case TELECOM_ICH:
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "RECEIVED");
+               break;
+       case TELECOM_OCH:
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "DIALED");
+               break;
+       case TELECOM_MCH:
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "MISSED");
+               break;
+       case TELECOM_CCH: {
+               contacts_record_h record = NULL;
+
+               gint status;
+
+               status = contacts_db_get_record(_contacts_phone_log._uri,
+                               handle, &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       break;
+
+               attr = __bluetooth_pb_phone_log_get_log_type(record);
+               str = _bluetooth_pb_vcard_call(handle, filter, format, attr);
+
+               contacts_record_destroy(record, TRUE);
+               break;
+       }
+       default:
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context, str);
+       g_free(str);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+       guint count = 0;
+
+       DBG("command: %s\n", command);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(command);
+
+       if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context, count);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       gint start_index,
+                                       gint end_index,
+                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       GPtrArray *ptr_array = NULL;
+
+       DBG("command: %s, start_index: %d, end_index: %d\n",
+                       command, start_index, end_index);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(command);
+
+       if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
+
+       __bluetooth_pb_get_list_number(agent, pb_type,
+                       start_index, end_index,
+                       ptr_array);
+
+       dbus_g_method_return(context, ptr_array);
+
+       if (ptr_array)
+               g_ptr_array_free(ptr_array, TRUE);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *agent,
+                                                       const gchar *command,
+                                                       const gchar *find_text,
+                                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       GPtrArray *ptr_array = NULL;
+
+       DBG("command: %s, find text: %s\n", command, find_text);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(command);
+
+       if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
+
+       __bluetooth_pb_get_list_name(agent, pb_type,
+                       find_text, ptr_array);
+
+       dbus_g_method_return(context, ptr_array);
+
+       if (ptr_array)
+               g_ptr_array_free(ptr_array, TRUE);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
+                                       gchar *path, DBusGMethodInvocation *context)
+{
+       guint count = 0;
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       DBG("%s() %d\n", __FUNCTION__, __LINE__);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(path);
+
+       if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context, count);
+
+       DBG("%s() %d\n", __FUNCTION__, __LINE__);
+
+       return TRUE;
+}
+
+
+#if 0
+static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
+{
+       FILE *fp = NULL;
+       int read_len = -1;
+       int received_file_size = 0;
+       struct stat file_attr;
+
+       if (file_path == NULL || stream == NULL) {
+               DBG("Invalid data \n");
+               return -1;
+       }
+
+       DBG_SECURE("file_path = %s\n", file_path);
+
+       if ((fp = fopen(file_path, "r+")) == NULL) {
+               ERR_SECURE("Cannot open %s\n", file_path);
+               return -1;
+       }
+
+       if (fstat(fileno(fp), &file_attr) == 0) {
+               received_file_size = file_attr.st_size;
+               DBG("file_attr.st_size = %d, size = %d\n", file_attr.st_size, received_file_size);
+
+               if (received_file_size <= 0) {
+                       ERR_SECURE("Some problem in the file size [%s]  \n", file_path);
+                       fclose(fp);
+                       fp = NULL;
+                       return -1;
+               }
+
+               *stream = (char *)malloc(sizeof(char) * received_file_size);
+               if (NULL == *stream) {
+                       fclose(fp);
+                       fp = NULL;
+                       return -1;
+               }
+       } else {
+               ERR_SECURE("Some problem in the file [%s]  \n", file_path);
+               fclose(fp);
+               fp = NULL;
+               return -1;
+       }
+
+       read_len = fread(*stream, 1, received_file_size, fp);
+
+       if (read_len == 0) {
+               if (fp != NULL) {
+                       fclose(fp);
+                       fp = NULL;
+               }
+               DBG_SECURE("Cannot open %s\n", file_path);
+               return -1;
+       }
+
+       if (fp != NULL) {
+               fclose(fp);
+               fp = NULL;
+       }
+       return 0;
+}
+#endif
+
+static gboolean bluetooth_pb_add_contact(BluetoothPbAgent *agent, const char *filename,
+                                        GError **error)
+{
+       /* Contact API is changed, Temporary blocked */
+#if 0
+       CTSstruct *contact_record = NULL;
+       GSList *numbers_list = NULL, *cursor;
+       int is_success = 0;
+       int is_duplicated = 0;
+       int err = 0;
+       char *stream = NULL;
+
+       DBG_SECURE("file_path = %s\n", filename);
+
+       err = contacts_svc_connect();
+       DBG("contact_db_service_connect fucntion call [error] = %d \n", err);
+
+       err = __bluetooth_pb_agent_read_file(filename, &stream);
+
+       if (err != 0) {
+               contacts_svc_disconnect();
+               DBG("contacts_svc_disconnect fucntion call [error] = %d \n", err);
+
+               if (NULL != stream) {
+                       free(stream);
+                       stream = NULL;
+               }
+               return FALSE;
+       }
+
+       is_success = contacts_svc_get_contact_from_vcard((const void *)stream, &contact_record);
+
+       DBG("contacts_svc_get_contact_from_vcard fucntion call [is_success] = %d \n", is_success);
+
+       if (0 == is_success) {
+               contacts_svc_struct_get_list(contact_record, CTS_CF_NUMBER_LIST, &numbers_list);
+               cursor = numbers_list;
+
+               for (; cursor; cursor = g_slist_next(cursor)) {
+                       if (contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER,
+                                                       contacts_svc_value_get_str(cursor->data,
+                                                               CTS_NUM_VAL_NUMBER_STR)) > 0) {
+                               DBG("is_duplicated\n");
+                               is_duplicated = TRUE;
+                       }
+               }
+
+               if (is_duplicated == FALSE) {
+                       contacts_svc_insert_contact(0, contact_record);
+               }
+       } else {
+               DBG("Fail \n");
+       }
+
+       err = contacts_svc_disconnect();
+       DBG("contacts_svc_disconnect fucntion call [error] = %d \n", err);
+
+       if (NULL != stream) {
+               free(stream);
+               stream = NULL;
+       }
+#endif
+
+       return TRUE;
+}
+
+static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
+                                       gint code,
+                                       const gchar *message)
+{
+       GQuark quark;
+       GError *error = NULL;
+
+       quark = g_type_qname(bluetooth_pb_agent_get_type());
+       error = g_error_new_literal(quark, code, message);
+
+       DBG("%s\n", message);
+
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+}
+
+static PhoneBookType __bluetooth_pb_get_pb_type(const char *name)
+{
+       gchar *suffix = ".vcf";
+       gint len;
+       gint size;
+       gint i;
+
+       if (name == NULL)
+               return TELECOM_NONE;
+
+       len = strlen(name);
+
+       if (g_str_has_suffix(name, suffix))
+               len -= strlen(suffix);
+
+       size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list) - 1;
+       for (i = 0; i < size; i++) {
+               if (strncmp(name, bluetooth_pb_agent_folder_list[i], len) == 0)
+                       return i;
+       }
+
+       return TELECOM_NONE;
+}
+
+static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
+{
+       if (name == NULL)
+               return TELECOM_NONE;
+
+       if (g_strcmp0(name, "\"ME\"") == 0 )
+               return TELECOM_PB;
+
+       if (g_strcmp0(name, "\"RC\"") == 0)
+               return TELECOM_ICH;
+
+       if (g_strcmp0(name, "\"DC\"") == 0)
+               return TELECOM_OCH;
+
+       if (g_strcmp0(name, "\"MC\"") == 0)
+               return TELECOM_MCH;
+
+       return TELECOM_NONE;
+}
+
+static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
+                                               gint *match,
+                                               gint size)
+{
+       gint i;
+       gint status;
+
+       for (i = 0; i < size; i++) {
+
+               if ( i > 0) {
+                       status = contacts_filter_add_operator(filter,
+                                       CONTACTS_FILTER_OPERATOR_OR);
+
+                       if (status != CONTACTS_ERROR_NONE)
+                               return status;
+               }
+
+               status = contacts_filter_add_int(filter,
+                               _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               match[i]);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return status;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
+                                               gint size)
+{
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_phone_log._uri,
+                               &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = __bluetooth_pb_phone_log_filter_append(filter, match, size);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = contacts_query_set_filter(query, filter);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = contacts_query_set_sort(query,
+                       _contacts_phone_log.log_time,
+                       false);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       contacts_filter_destroy(filter);
+
+       return query;
+}
+
+static contacts_query_h __bluetooth_pb_query_person(void)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_person._uri,
+                       &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       return query;
+}
+
+static contacts_query_h __bluetooth_pb_query_person_number(void)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_person_number._uri,
+                               &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       return query;
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void)
+{
+       gint size = 2;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void)
+{
+       gint size = 2;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
+               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_missed(void)
+{
+       gint size = 4;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_combined(void)
+{
+       gint size = 8;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
+               CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
+               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
+                               guint *count)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+       gint signed_count;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person();
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               break;
+       default:
+               return FALSE;
+       }
+
+       if (query == NULL)
+               return FALSE;
+
+       status = contacts_db_get_count_with_query(query, &signed_count);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return FALSE;
+       }
+
+       contacts_query_destroy(query);
+
+       if (signed_count < 0)
+               signed_count = 0;
+
+       *count = (gint) signed_count;
+
+       return TRUE;
+}
+
+static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+       gint signed_count;
+
+       gint size = 2;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN
+       };
+
+       query = __bluetooth_pb_query_phone_log(match, size);
+
+       if (query == NULL)
+               return FALSE;
+
+       status = contacts_db_get_count_with_query(query, &signed_count);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return FALSE;
+       }
+
+       contacts_query_destroy(query);
+
+       if (signed_count < 0)
+               signed_count = 0;
+
+       *count = (guint)signed_count;
+
+       return TRUE;
+}
+
+static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record)
+{
+       gint status;
+       gint log_type;
+
+       status = contacts_record_get_int(record,
+                       _contacts_phone_log.log_type,
+                       &log_type);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       switch (log_type) {
+       case CONTACTS_PLOG_TYPE_VOICE_INCOMMING:
+       case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING:
+               return "RECEIVED";
+       case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
+       case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
+               return "DIALED";
+       case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN:
+       case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN:
+       case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN:
+       case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN:
+               return "MISSED";
+       default:
+               return NULL;
+       }
+}
+
+static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               guint64 filter,
+                               guint8 format,
+                               guint16 max_list_count,
+                               guint16 list_start_offset,
+                               GPtrArray *vcards)
+{
+       contacts_list_h record_list = NULL;
+       contacts_query_h query = NULL;
+
+       gint status;
+
+       gint limit;
+       gint offset;
+
+       guint property_id = 0;
+
+       const char *attr = NULL;
+
+       gboolean get_log = FALSE;
+
+       /* contact offset is n - 1 of PBAP */
+       offset = (gint)list_start_offset - 1;
+
+       if ( max_list_count >= 65535)
+               limit = -1;     /* contact limit -1 means unrestricted */
+       else
+               limit = (gint)max_list_count;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               /* for owner */
+               if (list_start_offset == 0) {
+                       char *vcard;
+
+                       vcard = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
+                                                               filter, format);
+                       if (vcard)
+                               g_ptr_array_add(vcards, vcard);
+
+                       offset = 0;
+
+                       if (limit > 0)
+                               limit--;
+               }
+
+               query = __bluetooth_pb_query_person();
+               property_id = _contacts_person.id;
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               property_id = _contacts_phone_log.id;
+               attr = "RECEIVED";
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               property_id = _contacts_phone_log.id;
+               attr = "DIALED";
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               property_id = _contacts_phone_log.id;
+               attr = "MISSED";
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               property_id = _contacts_phone_log.id;
+               get_log = TRUE;
+               break;
+       default:
+               return;
+       }
+
+       status = contacts_db_get_records_with_query(query, offset, limit, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               contacts_query_destroy(query);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               contacts_query_destroy(query);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gint id;
+
+               gchar *vcard = NULL;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list, &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+               id = 0;
+               status = contacts_record_get_int(record, property_id, &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (property_id == _contacts_person.id)
+                       vcard = _bluetooth_pb_vcard_contact(id, filter, format);
+               else {
+                       if (get_log)
+                               attr = __bluetooth_pb_phone_log_get_log_type(record);
+
+                       vcard = _bluetooth_pb_vcard_call(id, filter, format, attr);
+               }
+
+               if (vcard)
+                       g_ptr_array_add(vcards, vcard);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+       contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       /* Add owner */
+       if (ptr_array) {
+               gchar *tmp;
+               gchar *name;
+
+               tmp = _bluetooth_pb_owner_name();
+               name = g_strdup_printf("%s;;;;", tmp);
+               g_free(tmp);
+
+               __bluetooth_pb_list_ptr_array_add(ptr_array,
+                               name, agent->tel_number, 0);
+
+               g_free(name);
+       }
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gint id;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_person.id,
+                               &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               /* create list */
+               if (ptr_array) {
+                       gchar *name;
+                       gchar *number;
+
+                       name = _bluetooth_pb_name_from_person_id(id);
+                       number = _bluetooth_pb_number_from_person_id(id);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       name, number, id);
+
+                       g_free(name);
+                       g_free(number);
+               }
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gint id;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_phone_log.id,
+                               &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               /* create list */
+               if (ptr_array) {
+                       gchar *name;
+                       gchar *number;
+
+                       name = _bluetooth_pb_name_from_phonelog_id(id);
+
+                       number = NULL;
+                       contacts_record_get_str_p(record,
+                                       _contacts_phone_log.address,
+                                       &number);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       name, number, id);
+
+                       g_free(name);
+               }
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+
+static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               GPtrArray *ptr_array)
+{
+       contacts_query_h query;
+
+       /* no requires refresh cache */
+       if (ptr_array == NULL && agent->pb_type == pb_type)
+               return;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person();
+               __bluetooth_pb_get_contact_list(agent, query, ptr_array);
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       default:
+               return;
+       }
+
+       agent->pb_type = pb_type;
+
+       if (query)
+               contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       gint i;
+
+       gint from;
+       gint to;
+       gint offset;
+
+       from = start_index;
+       to = end_index;
+
+       if (from < 1)
+               from = 1;
+
+       if (to < 1)
+               to = 1;
+
+       offset = to - from + 1;
+       if (offset <= 0)
+               return;
+
+       i = from;
+
+       status = contacts_db_get_records_with_query(query,
+                       from - 1 , offset,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gchar *display_name;
+               gchar *number;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               display_name = NULL;
+               number = NULL;
+
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.display_name,
+                               &display_name);
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.number,
+                               &number);
+
+               __bluetooth_pb_list_ptr_array_add(ptr_array,
+                               display_name, number, i);
+
+               i++;
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       gint i;
+
+       gint from;
+       gint to;
+       gint offset;
+
+       from = start_index;
+       to = end_index;
+
+       if (from < 1)
+               from = 1;
+
+       if (to < 1)
+               to = 1;
+
+       offset = to - from + 1;
+       if (offset <= 0)
+               return;
+
+       i = from;
+
+       status = contacts_db_get_records_with_query(query,
+                       from - 1 , offset,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record = NULL;
+
+               gint id;
+
+               gchar *display_name;
+               gchar *number;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_phone_log.id,
+                               &id);
+
+               display_name = _bluetooth_pb_fn_from_phonelog_id(id);
+
+               number = NULL;
+               contacts_record_get_str_p(record,
+                               _contacts_phone_log.address,
+                               &number);
+
+
+               __bluetooth_pb_list_ptr_array_add(ptr_array,
+                               display_name, number, i);
+
+               i++;
+
+               g_free(display_name);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array)
+{
+       contacts_query_h query;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person_number();
+               __bluetooth_pb_get_contact_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       default:
+               return;
+       }
+
+       if (query)
+               contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+       gint i = 1;
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gchar *display_name;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               display_name = NULL;
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.display_name,
+                               &display_name);
+
+               if (g_str_has_prefix(display_name, find_text)) {
+                       gchar *number;
+
+                       number = NULL;
+                       contacts_record_get_str_p(record,
+                                       _contacts_person_number.number,
+                                       &number);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       display_name, number, i);
+               }
+
+               i++;
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       gint i = 1;
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record = NULL;
+
+               gint id;
+
+               gchar *display_name;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_phone_log.id,
+                               &id);
+
+               display_name = _bluetooth_pb_fn_from_phonelog_id(id);
+
+               if (g_str_has_prefix(display_name, find_text)) {
+                       gchar *number = NULL;
+
+                       number = NULL;
+                       contacts_record_get_str_p(record,
+                                       _contacts_phone_log.address,
+                                       &number);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       display_name, number, i);
+               }
+
+               i++;
+
+               g_free(display_name);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
+                                       PhoneBookType pb_type,
+                                       const gchar *find_text,
+                                       GPtrArray *ptr_array)
+{
+       contacts_query_h query;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person_number();
+               __bluetooth_pb_get_contact_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       default:
+               return;
+       }
+
+       if (query)
+               contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
+                                               const gchar *name,
+                                               const gchar *number,
+                                               gint handle)
+{
+       GValue value = { 0, };
+
+       g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
+       g_value_take_boxed(&value,
+                       dbus_g_type_specialized_construct(DBUS_STRUCT_STRING_STRING_UINT));
+
+       dbus_g_type_struct_set(&value,
+                               0, g_strdup(name),
+                               1, g_strdup(number),
+                               2, handle,
+                               G_MAXUINT);
+
+       g_ptr_array_add(ptr_array, g_value_get_boxed(&value));
+}
+
+static void __bluetooth_pb_list_ptr_array_free(gpointer data)
+{
+       GValue value = { 0, };
+
+       gchar *name = NULL;
+       gchar *number = NULL;
+
+       if(data == NULL)
+               return;
+
+       g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
+       g_value_set_boxed(&value, data);
+
+       dbus_g_type_struct_get(&value,
+                       0, &name,
+                       1, &number,
+                       G_MAXUINT);
+
+       g_free(name);
+       g_free(number);
+}
+
+static void __bluetooth_pb_agent_signal_handler(int signum)
+{
+       if (mainloop) {
+               g_main_loop_quit(mainloop);
+       } else {
+               DBG("Terminate Bluetooth PBAP agent");
+               exit(0);
+       }
+}
+
+
+static void __bluetooth_pb_contact_changed(const gchar *view_uri,
+                                       void *user_data)
+{
+       BluetoothPbAgent *agent;
+
+       g_return_if_fail(BLUETOOTH_IS_PB_AGENT(user_data));
+       agent = BLUETOOTH_PB_AGENT(user_data);
+
+       g_signal_emit(agent, signals[CLEAR], 0);
+       g_object_unref(agent);
+}
+
+static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent)
+{
+       g_return_if_fail(BLUETOOTH_IS_PB_AGENT(agent));
+
+       if(agent->timeout_id)
+               g_source_remove(agent->timeout_id);
+
+       agent->timeout_id = g_timeout_add_seconds(BLUETOOTH_PB_AGENT_TIMEOUT,
+                               __bluetooth_pb_agent_timeout_calback,
+                               agent);
+}
+
+static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data)
+{
+       BluetoothPbAgent *agent;
+
+       g_return_val_if_fail(BLUETOOTH_IS_PB_AGENT(user_data), FALSE);
+
+       agent = BLUETOOTH_PB_AGENT(user_data);
+       agent->timeout_id = 0;
+
+       if (mainloop)
+               g_main_loop_quit(mainloop);
+
+       return FALSE;
+}
+
+static void __bluetooth_pb_tel_callback(TapiHandle *handle,
+                                       int result,
+                                       void *data,
+                                       void *user_data)
+{
+       BluetoothPbAgent *agent;
+       TelSimMsisdnList_t *number;
+
+       g_return_if_fail(BLUETOOTH_IS_PB_AGENT(user_data));
+
+       agent = BLUETOOTH_PB_AGENT(user_data);
+
+       __bluetooth_pb_agent_dbus_init(agent);
+
+       if (data != NULL) {
+               number = (TelSimMsisdnList_t *)data;
+               agent->tel_number = g_strdup(number->list[0].num);
+       }
+
+       tel_deinit(agent->tapi_handle);
+       agent->tapi_handle = NULL;
+}
+
+static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
+{
+       guint result = 0;
+       GError *error = NULL;
+
+       agent->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+
+       if (error != NULL) {
+               DBG("Couldn't connect to system bus[%s]\n", error->message);
+               g_error_free(error);
+               return;
+       }
+
+       agent->proxy = dbus_g_proxy_new_for_name(agent->bus,
+                       DBUS_SERVICE_DBUS,
+                       DBUS_PATH_DBUS,
+                       DBUS_INTERFACE_DBUS);
+
+       if (agent->proxy == NULL) {
+               DBG("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       if (!dbus_g_proxy_call(agent->proxy,
+                               "RequestName", &error,
+                               G_TYPE_STRING, BT_PB_SERVICE_NAME,
+                               G_TYPE_UINT, 0,
+                               G_TYPE_INVALID,
+                               G_TYPE_UINT, &result,
+                               G_TYPE_INVALID)) {
+               if (error != NULL) {
+                       DBG("RequestName RPC failed[%s]\n", error->message);
+                       g_error_free(error);
+               }
+
+               g_object_unref(agent->proxy);
+               agent->proxy = NULL;
+
+               return;
+       }
+       DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+               DBG("Failed to get the primary well-known name.\n");
+
+               g_object_unref(agent->proxy);
+               agent->proxy = NULL;
+
+               return;
+       }
+
+       g_object_unref(agent->proxy);
+       agent->proxy = NULL;
+
+       dbus_g_connection_register_g_object(agent->bus,
+                       BT_PB_SERVICE_OBJECT_PATH,
+                       G_OBJECT(agent));
+}
+
+static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
+                                       DBusGMethodInvocation *context)
+{
+       g_main_loop_quit(mainloop);
+       return TRUE;
+}
+
+int main(void)
+{
+       BluetoothPbAgent *agent;
+
+       gint ret = EXIT_SUCCESS;
+       gint tapi_result;
+
+       struct sigaction sa;
+       DBG("Starting Bluetooth PBAP agent");
+
+       g_type_init();
+
+       mainloop = g_main_loop_new(NULL, FALSE);
+       if (mainloop == NULL) {
+               DBG("Couldn't create GMainLoop\n");
+               return EXIT_FAILURE;
+       }
+
+       agent = g_object_new(BLUETOOTH_PB_TYPE_AGENT, NULL);
+
+       /* connect contact */
+       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
+               DBG("Can not connect contacts server\n");
+               g_object_unref(agent);
+               return EXIT_FAILURE;
+       }
+
+       if (contacts_db_add_changed_cb(_contacts_event._uri,
+                       __bluetooth_pb_contact_changed,
+                       g_object_ref(agent)) != CONTACTS_ERROR_NONE) {
+               DBG("Can not add changed callback");
+       }
+
+       /* set signal */
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_handler = __bluetooth_pb_agent_signal_handler;
+       sigaction(SIGTERM, &sa, NULL);
+       sigaction(SIGINT, &sa, NULL);
+
+       /* init tapi */
+       agent->tapi_handle = tel_init(NULL);
+       tapi_result = tel_get_sim_msisdn(agent->tapi_handle,
+                       __bluetooth_pb_tel_callback, agent);
+
+       if (tapi_result != TAPI_API_SUCCESS) {
+               __bluetooth_pb_agent_dbus_init(agent);
+       }
+
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       g_main_loop_run(mainloop);
+
+       if (contacts_db_remove_changed_cb(_contacts_event._uri,
+                       __bluetooth_pb_contact_changed,
+                       g_object_ref(agent)) != CONTACTS_ERROR_NONE) {
+               DBG("Cannot remove changed callback");
+       }
+
+       g_object_unref(agent);
+
+       if (contacts_disconnect2() != CONTACTS_ERROR_NONE)
+               DBG("contacts_disconnect2 failed \n");
+
+       g_signal_emit(agent, signals[CLEAR], 0);
+
+       g_object_unref(agent);
+
+       DBG("Terminate Bluetooth PBAP agent");
+       return ret;
+}
diff --git a/mobile/pb-agent/bluetooth_pb_agent.h b/mobile/pb-agent/bluetooth_pb_agent.h
new file mode 100644 (file)
index 0000000..53e4086
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_PB_AGENT_H_
+#define __DEF_BT_PB_AGENT_H_
+
+#include <unistd.h>
+#include <dlog.h>
+
+#include <stdio.h>
+
+#include <dbus/dbus-glib.h>
+
+#define BT_PB_SERVICE_OBJECT_PATH      "/org/bluez/pb_agent"
+#define BT_PB_SERVICE_NAME             "org.bluez.pb_agent"
+#define BT_PB_SERVICE_INTERFACE                "org.bluez.PbAgent"
+
+#undef LOG_TAG
+#define LOG_TAG "BT_PB_AGENT"
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#endif                         /* __DEF_BT_AGENT_H_ */
diff --git a/mobile/pb-agent/bluetooth_pb_agent.xml b/mobile/pb-agent/bluetooth_pb_agent.xml
new file mode 100644 (file)
index 0000000..e9f758b
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+       <interface name="org.bluez.PbAgent">
+               <method name="GetPhonebookFolderList">
+                       <arg type="as" name="folder_list" direction="out"/>
+               </method>
+
+               <method name="GetPhonebook">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="name"/>
+                       <arg type="t" name="filter"/>
+                       <arg type="y" name="format"/>
+                       <arg type="q" name="max_list_count"/>
+                       <arg type="q" name="list_start_offset"/>
+                       <arg type="as" name="phonebook" direction="out"/>
+                       <arg type="u" name="new_missed_call" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookSize">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="name"/>
+                       <arg type="u" name="phonebook_size" direction="out"/>
+                       <arg type="u" name="new_missed_call" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookList">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="name"/>
+                       <arg type="a(ssu)" name="phonebook_list" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookEntry">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="folder"/>
+                       <arg type="s" name="id"/>
+                       <arg type="t" name="filter"/>
+                       <arg type="y" name="format"/>
+                       <arg type="s" name="phonebook_entry" direction="out"/>
+               </method>
+
+               <method name="GetTotalObjectCount">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="path"/>
+                       <arg type="u" name="phonebook_size" direction="out"/>
+               </method>
+
+               <method name="AddContact">
+                       <arg type="s" name="filename"/>
+               </method>
+
+               <method name="DestroyAgent">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+               </method>
+
+               <signal name="clear"/>
+
+       </interface>
+
+       <interface name="org.bluez.PbAgent.At">
+               <method name="GetPhonebookSizeAt">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="command"/>
+                       <arg type="u" name="phonebook_size" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookEntriesAt">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="command"/>
+                       <arg type="i" name="start_index"/>
+                       <arg type="i" name="end_index"/>
+                       <arg type="a(ssu)" name="phonebook_entries" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookEntriesFindAt">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="command"/>
+                       <arg type="s" name="find_text" />
+                       <arg type="a(ssu)" name="phonebook_entries" direction="out"/>
+               </method>
+       </interface>
+</node>
diff --git a/mobile/pb-agent/bluetooth_pb_vcard.c b/mobile/pb-agent/bluetooth_pb_vcard.c
new file mode 100644 (file)
index 0000000..3445160
--- /dev/null
@@ -0,0 +1,2779 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <time.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <vconf.h>
+#include <dlog.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <contacts.h>
+#include <image_util.h>
+#include <libexif/exif-data.h>
+#include <unistd.h>
+
+#include "bluetooth_pb_vcard.h"
+
+#define BT_PB_AGENT "BT_PB_AGENT"
+#define DBG(fmt, args...) SLOG(LOG_DEBUG, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
+#define ERR(fmt, args...) SLOG(LOG_ERROR, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
+
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#define VCARD_FORMAT_2_1 0x0
+#define VCARD_FORMAT_3_0 0x1
+
+#define VCARD_VERSION  (0x1)
+#define VCARD_FN       (0x1 << 1)
+#define VCARD_N                (0x1 << 2)
+#define VCARD_PHOTO    (0x1 << 3)
+#define VCARD_BDAY     (0x1 << 4)
+#define VCARD_ADR      (0x1 << 5)
+#define VCARD_LABEL    (0x1 << 6)      /* not supported */
+#define VCARD_TEL      (0x1 << 7)
+#define VCARD_EMAIL    (0x1 << 8)
+#define VCARD_MAILER   (0x1 << 9)      /* not supported */
+#define VCARD_TZ       (0x1 << 10)     /* not supported */
+#define VCARD_GEO      (0x1 << 11)     /* not supported */
+#define VCARD_TITLE    (0x1 << 12)
+#define VCARD_ROLE     (0x1 << 13)
+#define VCARD_LOGO     (0x1 << 14)     /* not supported */
+#define VCARD_AGENT    (0x1 << 15)     /* not supported */
+#define VCARD_ORG      (0x1 << 16)
+#define VCARD_NOTE     (0x1 << 17)
+#define VCARD_REV      (0x1 << 18)
+#define VCARD_SOUND    (0x1 << 19)     /* not supported */
+#define VCARD_URL      (0x1 << 20)
+#define VCARD_UID      (0x1 << 21)
+#define VCARD_KEY      (0x1 << 22)     /* not supported */
+#define VCARD_NICKNAME (0x1 << 23)
+#define VCARD_CATEGORIES       (0x1 << 24)     /* not supported */
+#define VCARD_PROID    (0x1 << 25)     /* not supported */
+#define VCARD_CLASS    (0x1 << 26)     /* not supported */
+#define VCARD_SORT_STRING      (0x1 << 27)     /* not supported */
+#define VCARD_X_IRMC_CALL_DATETIME     (0x1 << 28)
+
+#define QP_ENC_LEN     3
+#define LINEBREAK_LEN  75
+
+typedef struct {
+       const char *src;
+       const char *dest;
+       int ret;
+       contacts_record_h person;
+       GString *string;
+} bt_image_info_t;
+
+gchar dest_thumb_path[255];
+#define PBAP_IMAGE_THUMB_SIZE 48
+#define PBAP_THMB_PATH "_thumb"
+#define PBAP_THUMB_FILE_SIZE 4096
+#define PBAP_IMAGE_ENCODE_QUALITY      90
+#define PBAP_SECURITY_FILE_GROUP 6005
+#define PBAP_SECURITY_DEFAULT_PERMISSION 0660
+#define PBAP_SECURITY_DIR_DEFAULT_PERMISSION 0770
+#define PBAP_SECURITY_IMAGE_PERMISSION 0440
+
+static gchar *__bluetooth_pb_vcard_escape(const gchar *str);
+
+static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
+                                       const gchar *delimeter);
+
+static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str);
+
+static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
+                                               gint len);
+
+static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
+                                                       const gchar *str,
+                                                       gint len,
+                                                       gint *line_pos);
+
+static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
+                                                       gchar ch,
+                                                       gint *line_pos);
+
+static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
+                                               const gchar *str,
+                                               gint len,
+                                               gint *line_pos);
+
+static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str);
+
+static void __bluetooth_pb_vcard_append_param_v21(GString *string,
+                                                const gchar *param);
+
+static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
+                                       const gchar *name,
+                                       const gchar *param,
+                                       const gchar *value);
+
+static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
+                                                       const gchar *name,
+                                                       const gchar *param,
+                                                       const gchar *value,
+                                                       gsize len,
+                                                       gboolean folding);
+
+static void __bluetooth_pb_vcard_append_n_v21(GString *string,
+                                       contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
+                                       contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
+                                               contacts_record_h conatct);
+
+static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
+                                       contacts_record_h person);
+
+static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
+                                               contacts_record_h person);
+
+static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_email_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_title_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_role_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_org_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_note_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_url_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_v30(GString *string,
+                                       const gchar *name,
+                                       const gchar *param,
+                                       const gchar *value);
+
+static void __bluetooth_pb_vcard_remove_v30(GString *string,
+                                       const gchar *property_name);
+
+static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
+                                       guint64 filter);
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args);
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args);
+
+static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       guint8 format,
+                                                       const gchar *first_name,
+                                                       ...);
+
+static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
+                                               guint filter,
+                                               const gchar *attr);
+
+static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
+                                               guint filter,
+                                               const gchar *attr);
+
+static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
+                                       guint filter,
+                                       guint8 format,
+                                       const gchar *attr);
+
+static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
+                                               int *field,
+                                               gint field_size);
+
+static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number);
+
+static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename);
+
+static gchar **__bluetooth_pb_contact_addr(contacts_record_h address);
+
+static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address);
+
+static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id);
+
+static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
+
+static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact);
+
+static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
+
+static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
+
+
+static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
+{
+       GString *escaped;
+
+       gchar *st = NULL;
+       gchar *pos = NULL;
+
+       if (str == NULL)
+               return NULL;
+
+       escaped = g_string_new(NULL);
+
+       st = (gchar *)str;
+       pos = st;
+
+       while (*pos != '\0') {
+               if (*pos == ';') {
+                       g_string_append_len(escaped, st, (pos - st));
+                       g_string_append(escaped, "\\;");
+
+                       pos++;
+                       st = pos;
+               } else {
+                       pos++;
+               }
+       }
+
+       g_string_append_len(escaped, st, (pos - st));
+       return g_string_free(escaped, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
+                                       const gchar *separator)
+{
+       GString *string = g_string_new(NULL);
+       gint i;
+
+       for (i = 0; strv[i] != NULL; i++) {
+               if (i > 0)
+                       g_string_append(string, ";");
+
+               g_string_append(string, strv[i]);
+       }
+
+       return g_string_free(string, FALSE);
+}
+
+static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
+{
+       gchar *pos = NULL;
+
+       if (str == NULL)
+               return FALSE;
+
+       pos = (gchar *)str;
+       while (*pos != '\0') {
+               /* ascii code ' ' : 32, '~' : 126 */
+               if ((guchar)*pos < ' ' || (guchar)*pos > '~')
+                       return TRUE;
+
+               pos++;
+       }
+       return FALSE;
+}
+
+/* get string length, which convert to quoted-printable encoding */
+static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
+                                               gint len)
+{
+       gchar *pos;
+
+       gint count = 0;
+       gint length = len;
+
+       if (str == NULL)
+               return 0;
+
+       if (strlen(str) < len)
+               length = -1;
+
+       pos = (gchar *)str;
+
+       while (*pos != '\0' && (((pos - str) < length) || length < 0)) {
+               if ((guchar)*pos == '\t') {
+                       count++;
+                       pos++;
+                       continue;
+               }
+
+               if ((guchar)*pos < ' ' || (guchar)*pos == '=') {
+                       count += QP_ENC_LEN;
+                       pos++;
+                       continue;
+               }
+
+               /* check no-ascii utf-8 character */
+               if ((guchar)*pos > '~') {
+
+                       gchar *next;
+
+                       next = g_utf8_next_char(pos);
+
+                       count += QP_ENC_LEN * (next - pos);
+                       pos = next;
+                       continue;
+               }
+
+               pos++;
+               count++;
+       }
+
+       return count;
+}
+
+/* convert to quoted printable code */
+static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
+                                                       const gchar *str,
+                                                       gint len,
+                                                       gint *line_pos)
+{
+       int i;
+
+       if (str == NULL || len == 0)
+               return;
+
+       /* add soft linebreak when it exceed */
+       if ((*line_pos + (QP_ENC_LEN * len) > LINEBREAK_LEN)) {
+               g_string_append(string, "=\r\n");
+               *line_pos = 0;
+       }
+
+       for (i = 0; i < len; i++) {
+               g_string_append_printf(string, "=%02X", (guchar)*(str+i));
+               *line_pos += QP_ENC_LEN;
+       }
+}
+
+/* append plain visiable ascii character */
+static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
+                                                       gchar ch,
+                                                       gint *line_pos)
+{
+       /* add soft linebreak when it exceed */
+       if (*line_pos + 1 > LINEBREAK_LEN) {
+               g_string_append(string, "=\r\n");
+               *line_pos = 0;
+       }
+       g_string_append_c(string, ch);
+       (*line_pos)++;
+}
+
+static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
+                                               const gchar *str,
+                                               gint len,
+                                               gint *line_pos)
+{
+       gint length;
+       gint encode_len;
+
+       gint i = 0;
+
+       if (string == NULL)
+               return;
+
+       encode_len = __bluetooth_pb_vcard_qp_encode_strlen(str, len);
+
+       /* add soft linebreak when it exceed */
+       if (((*line_pos + encode_len) > LINEBREAK_LEN) && (*line_pos > 1)) {
+               g_string_append(string, "=\r\n");
+               *line_pos = 0;
+       }
+
+       length = strlen(str);
+       if (length > len)
+               length = len;
+
+       while (i < len) {
+               gchar *pos;
+
+               pos = ((gchar *)str) + i;
+
+               /* converts invisiable character and escape character '='
+                       to quoted-printable */
+               if ((guchar)*pos != '\t' &&
+                               ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
+                                                       pos, 1, line_pos);
+                       i++;
+
+                       continue;
+               }
+
+               /* converts non-ascii utf-8 character to quoted-printable */
+               if ((guchar)*pos > '~') {
+                       gchar *next;
+                       int ch_len;
+
+                       next = g_utf8_next_char(pos);
+
+                       ch_len = next - pos;
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
+                                                       pos, ch_len, line_pos);
+                       i += ch_len;
+
+                       continue;
+               }
+
+               __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos,
+                                                               line_pos);
+               i++;
+       }
+}
+
+static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str)
+{
+       GString *enc;
+
+       gchar *st_pos;
+       gchar *pos;
+
+       gint line_pos = 0;
+
+       if (str == NULL)
+               return NULL;
+
+       enc = g_string_new(NULL);
+
+       st_pos = (gchar *)str;
+       pos = (gchar *)str;
+
+       while (*pos != '\0') {
+               /* split string with given delimeter ' ' or '\t' */
+               if (*pos == ' ' || *pos == '\t') {
+                       __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
+                                       (pos - st_pos), &line_pos);
+
+                       st_pos = pos;
+                       pos++;
+
+                       continue;
+               }
+
+               /* split string with given delimeter '\r', '\n' or
+                       '\r\n' - newline */
+               if (*pos == '\r' || *pos == '\n') {
+                       __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
+                                       (pos - st_pos), &line_pos);
+
+                       /* converts newline to qp_encode with soft linebreak
+                        for example, converts \r\n to =0D=0A=\r\n */
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(enc,
+                                                       "\r\n", 2, &line_pos);
+                       g_string_append(enc, "=\r\n ");
+
+                       line_pos = 1;
+
+                       if (*pos == '\r' && *(pos + 1) == '\n')
+                               pos += 2;
+                       else
+                               pos++;
+
+                       st_pos = pos;
+
+                       continue;
+               }
+
+               pos++;
+       }
+
+       __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
+                       (pos - st_pos), &line_pos);
+
+       return g_string_free(enc, FALSE);
+}
+
+static void __bluetooth_pb_vcard_append_param_v21(GString *string,
+                                                const gchar *param)
+{
+       gchar *pos = NULL;
+
+       if (param == NULL)
+               return;
+
+       pos = (gchar *)param;
+
+       /* trim ';' on first */
+       while (*pos != '\0') {
+               if (*pos != ';')
+                       break;
+
+               pos++;
+       }
+
+       if (*pos != '\0')
+               g_string_append_printf(string, ";%s", pos);
+}
+
+static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
+                                               const gchar *name,
+                                               const gchar *param,
+                                               const gchar *value)
+{
+       GString *property = NULL;
+
+       if (name == NULL)
+               return;
+
+       property = g_string_new(name);
+       __bluetooth_pb_vcard_append_param_v21(property, param);
+
+       if (__bluetooth_pb_vcard_qp_encode_check(value)) {
+               gchar *enc = NULL;
+
+               __bluetooth_pb_vcard_append_param_v21(property,
+                               "CHARSET=UTF-8");
+               __bluetooth_pb_vcard_append_param_v21(property,
+                               "ENCODING=QUOTED-PRINTABLE");
+               g_string_append(property, ":");
+
+               enc = __bluetooth_pb_vcard_qp_encode(value);
+
+               if (enc) {
+                       g_string_append(property, enc);
+                       g_free(enc);
+               }
+       } else {
+               g_string_append(property, ":");
+               if (value)
+                       g_string_append(property , value);
+       }
+
+       g_string_append_printf(string, "%s\r\n", property->str);
+
+       g_string_free(property, TRUE);
+}
+
+
+static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
+                                                       const gchar *name,
+                                                       const gchar *param,
+                                                       const gchar *value,
+                                                       gsize len,
+                                                       gboolean folding)
+{
+       gchar *enc = NULL;
+
+       if (name == NULL)
+               return;
+       DBG("base 64 encoding\n");
+
+       g_string_append(string, name);
+
+       __bluetooth_pb_vcard_append_param_v21(string, param);
+       __bluetooth_pb_vcard_append_param_v21(string, "ENCODING=BASE64");
+
+       g_string_append(string, ":");
+
+       if (value == NULL)
+               return;
+
+       enc = g_base64_encode((const guchar *)value, len);
+
+       if (folding == FALSE) {
+               g_string_append(string, enc);
+       } else {
+               gint enc_len = strlen(enc);
+               gint i = 0;
+
+               /* count ' ' size for folding */
+               gint fline_len = LINEBREAK_LEN - 1;
+
+               for (i = 0; (i * fline_len) < enc_len; i++) {
+                       g_string_append(string, "\r\n ");
+                       if ((i * fline_len) + fline_len > enc_len)
+                               g_string_append(string, enc + (i * fline_len));
+                       else
+                               g_string_append_len(string, enc +
+                                               (i * fline_len), fline_len);
+               }
+
+               /* some application requires more \r\n */
+               g_string_append(string, "\r\n");
+       }
+       g_string_append(string, "\r\n");
+       DBG("base 64 encoding\n");
+
+       g_free(enc);
+}
+
+static void __bluetooth_pb_vcard_append_n_v21(GString *string,
+                                       contacts_record_h contact)
+{
+       gchar *str;
+
+       str = __bluetooth_pb_name_from_contact(contact);
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
+
+       g_free(str);
+}
+
+static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
+                                       contacts_record_h contact)
+{
+       gchar *str;
+
+       str = __bluetooth_pb_phonetic_name_from_contact(contact);
+
+       if (str != NULL) {
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "SOUND", "X-IRMC-N", str);
+               g_free(str);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint i;
+       gint status;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.number,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h number = NULL;
+
+               gchar **paramv = NULL;
+               gchar *param = NULL;
+
+               gchar *tel = NULL;
+               gchar *escaped = NULL;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, i, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tel);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tel);
+
+               paramv = __bluetooth_pb_contact_tel_param(number);
+               param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
+
+               g_strfreev(paramv);
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param,
+                                                               escaped);
+
+               g_free(escaped);
+               g_free(param);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
+                                       contacts_record_h person)
+{
+       gint status;
+
+       gchar *fn = NULL;
+       gchar *tmp = NULL;
+
+       status = contacts_record_get_str_p(person,
+                       _contacts_person.display_name,
+                       &tmp);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       fn = __bluetooth_pb_vcard_escape(tmp);
+
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "FN", NULL, fn);
+
+       g_free(fn);
+}
+
+static image_util_rotation_e __bt_pbap_get_rotation_info(const char *path)
+{
+       ExifData *ed = NULL;
+       ExifEntry *entry;
+       image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+       int orientation = 0;
+
+       ed = exif_data_new_from_file(path);
+       if (ed == NULL) {
+               DBG("exif_data_new_from_file : ExifData is NULL");
+               return IMAGE_UTIL_ROTATION_NONE;
+       }
+
+       entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
+       if (entry) {
+               ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
+               orientation = (int)exif_get_short(entry->data, mByteOrder);
+               if (orientation < 0 || orientation > 8)
+                       orientation = 0;
+       }
+
+       exif_data_unref(ed);
+
+       switch (orientation) {
+       case 1: /* Top-left */
+               rotation = IMAGE_UTIL_ROTATION_NONE;
+               break;
+       case 2: /* Top-right */
+               rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
+               break;
+       case 3: /* Bottom-right */
+               rotation = IMAGE_UTIL_ROTATION_180;
+               break;
+       case 4: /* Bottom-left */
+               rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
+               break;
+       case 6: /* Right-top */
+               rotation = IMAGE_UTIL_ROTATION_90;
+               break;
+       case 8: /* Left-bottom */
+               rotation = IMAGE_UTIL_ROTATION_270;
+               break;
+       case 5: /* Left-top */
+       case 7: /* Right-bottom */
+       case 0:
+       default:
+               break;
+       };
+
+       return rotation;
+}
+
+
+static bool __bt_pbap_image_util_supported_jpeg_colorspace_cb(
+                       image_util_colorspace_e colorspace, void *user_data)
+{
+       unsigned char *img_target = 0;
+       unsigned char *img_source = 0;
+       gchar *type = NULL;
+       gchar *param = NULL;
+       gchar *contents = NULL;
+       int width = 0;
+       int height = 0;
+       int resized_width = 0;
+       int resized_height = 0;
+       int dest_fd = 0;
+       unsigned int size_decode = 0;
+       image_util_rotation_e rotation;
+       image_util_error_e ret = 0;
+       gsize len = 0;
+
+       bt_image_info_t *info = (bt_image_info_t *)user_data;
+       rotation = __bt_pbap_get_rotation_info(info->src);
+       ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width,
+                                                       &height, &size_decode);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               ERR("Can not decode");
+               memset(info, 0x00, sizeof(bt_image_info_t));
+               return true;
+       }
+
+       DBG("decoding completed width = %d, height = %d, size = %d\n", width,
+                                                       height, size_decode);
+       if (width > PBAP_IMAGE_THUMB_SIZE  || height > PBAP_IMAGE_THUMB_SIZE) {
+               if (width <= 0 || height <= 0) {
+                       free(img_source);
+                       ERR("image size error(%d)", PBAP_IMAGE_THUMB_SIZE);
+                       memset(info, 0x00, sizeof(bt_image_info_t));
+                       return false;
+               }
+
+               if (width > height) {
+                       resized_width = PBAP_IMAGE_THUMB_SIZE ;
+                       resized_height = height * PBAP_IMAGE_THUMB_SIZE / width;
+               } else {
+                       resized_height = PBAP_IMAGE_THUMB_SIZE;
+                       resized_width = width * PBAP_IMAGE_THUMB_SIZE / height;
+               }
+
+               if (resized_height % 8)
+                       resized_height += 8 - (resized_height % 8);
+               if (resized_width % 8)
+                       resized_width += 8 - (resized_width % 8);
+
+               DBG("original size[%d, %d] changed to resize[%d,%d]", width,
+                                       height, resized_width, resized_height);
+
+               ret = image_util_calculate_buffer_size(resized_width,
+                                                       resized_height,
+                                                       colorspace ,
+                                                       &size_decode);
+
+               img_target = g_malloc0(size_decode);
+
+               /* do resize */
+               ret = image_util_resize(img_target, &resized_width,
+                                       &resized_height, img_source, width,
+                                       height, colorspace);
+               if (ret != IMAGE_UTIL_ERROR_NONE) {
+                       ERR("image_util_resize failed(%d)", ret);
+                       g_free(img_target);
+                       free(img_source);
+                       memset(info, 0x00, sizeof(bt_image_info_t));
+                       return false;
+               }
+               free(img_source);
+       } else {
+               resized_width = width;
+               resized_height = height;
+               img_target = img_source;
+       }
+       DBG("Resized w = %d, ht = %d, size = %d\n", width, height, size_decode);
+
+       if (IMAGE_UTIL_ROTATION_NONE != rotation) {
+               int rotated_width, rotated_height;
+               unsigned char *img_rotate = 0;
+               img_rotate = g_malloc0(size_decode);
+               image_util_rotate(img_rotate, &rotated_width, &rotated_height,
+                                       rotation, img_target, resized_width,
+                                       resized_height, colorspace);
+               resized_width = rotated_width;
+               resized_height = rotated_height;
+               g_free(img_target);
+               img_target = img_rotate;
+       }
+
+       /* image encode */
+       ret = image_util_encode_jpeg(img_target, resized_width, resized_height,
+                                       colorspace, PBAP_IMAGE_ENCODE_QUALITY,
+                                       info->dest);
+       g_free(img_target);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               ERR("image_util_encode_jpeg failed(%d)", ret);
+               info->ret = CONTACTS_ERROR_INTERNAL;
+               goto done;
+       }
+       DBG("Encoding done\n");
+
+       dest_fd = open(info->dest, O_RDONLY);
+       if (dest_fd < 0) {
+               ERR("System : Open Failed(%d)", errno);
+               ERR_SECURE("Open : dest path(%s)", info->dest);
+               goto done;
+       }
+
+       ret = fchown(dest_fd, getuid(), PBAP_SECURITY_FILE_GROUP);
+       if (0 != ret) {
+               DBG("fchown Failed(%d)", errno);
+               DBG_SECURE("fchown : dest path(%s)", info->dest);
+               close(dest_fd);
+               goto done;
+       }
+
+       ret = fchmod(dest_fd, PBAP_SECURITY_IMAGE_PERMISSION);
+       if (0 != ret) {
+               ERR("fchmod Failed(%d)", errno);
+               ERR_SECURE("fchmod : dest path(%s)", info->dest);
+               close(dest_fd);
+               goto done;
+       }
+       close(dest_fd);
+
+       info->ret = CONTACTS_ERROR_NONE;
+       type = __bluetooth_pb_contact_photo_type(info->dest);
+       DBG("Cintact image thumb type is = %s\n", type);
+
+       if (type) {
+               param = g_strdup_printf("TYPE=%s", type);
+               g_free(type);
+       }
+
+       if (g_file_get_contents(info->dest, &contents, &len, NULL) == FALSE) {
+               ERR("can not read file contents:%s\n", info->dest);
+               goto done;
+       }
+
+       __bluetooth_pb_vcard_append_base64_encode_v21(info->string,
+                       "PHOTO", param, contents, len, TRUE);
+
+done:
+       g_free(param);
+       g_free(contents);
+       remove(info->dest);
+       memset(info, 0x00, sizeof(bt_image_info_t));
+       DBG("Cintact image thumb created successfuly\n");
+       return false;
+}
+
+static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
+                                               contacts_record_h person)
+{
+       gint status;
+       gchar *filename = NULL;
+       int res = 0;
+       bt_image_info_t img_info;
+       struct stat stat_info;
+       gchar *type = NULL;
+       gchar *param = NULL;
+       gchar *contents = NULL;
+       gsize len = 0;
+       char *ptr = NULL;
+
+       DBG("PBAP +\n");
+
+       status = contacts_record_get_str_p(person,
+                       _contacts_person.image_thumbnail_path,
+                       &filename);
+
+       if (status != CONTACTS_ERROR_NONE || NULL == filename)
+               return;
+
+       stat_info.st_size = 0;
+
+       if (0 > stat(filename, &stat_info)) {
+               ERR("fstat failed, file does not exist %s", filename);
+       }
+
+       if (PBAP_THUMB_FILE_SIZE > stat_info.st_size) {
+               DBG_SECURE("File size small, so use thubnail %s\n", filename);
+
+               type = __bluetooth_pb_contact_photo_type(filename);
+               if (type) {
+                       param = g_strdup_printf("TYPE=%s", type);
+                       g_free(type);
+               }
+
+               if (g_file_get_contents(filename, &contents, &len, NULL) ==
+                                                                       FALSE) {
+                       ERR("can not read file contents:%s\n", filename);
+                       g_free(param);
+                       return;
+               }
+               DBG("Retrieved the contents of the file \n");
+               __bluetooth_pb_vcard_append_base64_encode_v21(string,
+                               "PHOTO", param, contents, len, TRUE);
+
+               g_free(param);
+               g_free(contents);
+               return;
+       }
+
+       ptr = strrchr(filename, '.');
+       if (NULL != ptr) {
+               memset(dest_thumb_path, 0x00, sizeof(dest_thumb_path));
+               g_strlcpy(dest_thumb_path, filename, ptr - filename);
+               g_strlcat(dest_thumb_path, PBAP_THMB_PATH,
+                                               sizeof(dest_thumb_path));
+               g_strlcat(dest_thumb_path, ptr, sizeof(dest_thumb_path));
+               DBG("Thumbnail path is = %s", dest_thumb_path);
+       }
+       DBG_SECURE("filename = %s Thumbnail path is = %s", filename, dest_thumb_path);
+       img_info.src = filename;
+       img_info.dest = dest_thumb_path;
+       img_info.ret = CONTACTS_ERROR_INTERNAL;
+       img_info.person = person;
+       img_info.string = string;
+
+       res = image_util_foreach_supported_jpeg_colorspace(
+               __bt_pbap_image_util_supported_jpeg_colorspace_cb, &img_info);
+       if (res != IMAGE_UTIL_ERROR_NONE) {
+               ERR("Image resizing is failed");
+       }
+       DBG("PBAP -\n");
+       return;
+}
+
+static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.event, &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h event = NULL;
+
+               gint date;
+
+               gchar *bday;
+
+               contacts_event_type_e type;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.event, i, &event);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_int(event,
+                               _contacts_event.type,
+                               (gint *) &type);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (type != CONTACTS_EVENT_TYPE_BIRTH)
+                       continue;
+
+               status = contacts_record_get_int(event,
+                               _contacts_event.date,
+                               &date);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (date <= 0)
+                       continue;
+
+               bday = g_strdup_printf("%04d-%02d-%02d",
+                               (date/10000), (date/100)%100, date%100);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "BDAY",
+                               NULL, bday);
+               g_free(bday);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.address,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h address = NULL;
+
+               gchar **addrv;
+               gchar **paramv;
+
+               gchar *addr;
+               gchar *param;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.address, i, &address);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               addrv = __bluetooth_pb_contact_addr(address);
+
+               if (addrv == NULL)
+                       continue;
+
+               addr = __bluetooth_pb_vcard_strv_concat(addrv, ";");
+               g_strfreev(addrv);
+
+               paramv = __bluetooth_pb_contact_addr_param(address);
+               param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
+               g_strfreev(paramv);
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
+                               param, addr);
+
+               g_free(param);
+               g_free(addr);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_email_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.email,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h email = NULL;
+
+               gchar *tmp = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.email, i, &email);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(email,
+                               _contacts_email.email,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tmp);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_title_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.company,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h company = NULL;
+
+               char *title = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                                       _contacts_contact.company, i, &company);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(company,
+                               _contacts_company.job_title,
+                               &title);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(title);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_role_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.company,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h company = NULL;
+
+               char *role = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.company, i, &company);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(company,
+                               _contacts_company.role,
+                               &role);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(role);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_org_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.company,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h company = NULL;
+
+               GString *str;
+
+               gchar *name = NULL;
+               gchar *department = NULL;
+
+               gint name_status;
+               gint department_status;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.company, i, &company);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+
+               name_status = contacts_record_get_str_p(company,
+                               _contacts_company.name,
+                               &name);
+
+               department_status = contacts_record_get_str_p(company,
+                               _contacts_company.department,
+                               &department);
+
+               if ((name_status != CONTACTS_ERROR_NONE) &&
+                               (department_status != CONTACTS_ERROR_NONE))
+                       continue;
+
+               str = g_string_new(NULL);
+
+               if (name) {
+                       gchar *escaped;
+
+                       escaped = __bluetooth_pb_vcard_escape(name);
+                       g_string_append(str, escaped);
+                       g_free(escaped);
+               }
+
+               g_string_append(str, ";");
+
+               if (department) {
+                       gchar *escaped;
+
+                       escaped = __bluetooth_pb_vcard_escape(department);
+                       g_string_append(str, escaped);
+                       g_free(escaped);
+               }
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL,
+                                                               str->str);
+
+               g_string_free(str, TRUE);
+
+       }
+}
+
+static void __bluetooth_pb_vcard_append_note_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.note,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h note = NULL;
+
+               char *tmp = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.note, i, &note);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(note,
+                               _contacts_note.note,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tmp);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       gint time = 0;
+       gint status;
+
+       gchar *rev;
+       struct tm result;
+
+       status = contacts_record_get_int(contact,
+                       _contacts_contact.changed_time,
+                       &time);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       if (time <= 0)
+               return;
+
+       gmtime_r((const time_t *)(&time), &result);
+
+       rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
+                       (1900 + result.tm_year), (1 + result.tm_mon),
+                       result.tm_mday, result.tm_hour, result.tm_min,
+                       result.tm_sec);
+
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
+
+       g_free(rev);
+}
+
+static void __bluetooth_pb_vcard_append_url_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint i;
+       gint status;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.url,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h url = NULL;
+
+               gchar *tmp = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.url, i, &url);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return;
+
+               if (url == NULL)
+                       continue;
+
+               status = contacts_record_get_str_p(url,
+                               _contacts_url.url,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tmp);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       int status;
+
+       gchar *uid = NULL;
+       gchar *escaped;
+
+       status = contacts_record_get_str_p(contact,
+                       _contacts_contact.uid,
+                       &uid);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       escaped = __bluetooth_pb_vcard_escape(uid);
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
+
+       g_free(escaped);
+}
+
+static void __bluetooth_pb_vcard_append_v30(GString *string,
+                                       const gchar *name,
+                                       const gchar *param,
+                                       const gchar *value)
+{
+       if (string == NULL)
+               return;
+       if (name == NULL)
+               return;
+
+       g_string_append(string, name);
+
+       if (param)
+               g_string_append_printf(string, ";%s", param);
+
+       g_string_append(string, ":");
+
+       if (value)
+               g_string_append(string, value);
+
+       g_string_append(string, "\r\n");
+}
+
+static void __bluetooth_pb_vcard_remove_v30(GString *string,
+                                       const gchar *property_name)
+{
+       gchar *pos = NULL;
+       gchar *st_pos = NULL;
+
+       gboolean matched = FALSE;
+
+       if (string == NULL || property_name == NULL)
+               return;
+
+       pos = string->str;
+
+       while (*pos != '\0') {
+               if (matched == FALSE) {
+                       if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
+                               gint attrlen = 0;
+
+                               st_pos = pos;
+                               pos += 2;
+
+                               attrlen = strlen(property_name);
+                               if (g_ascii_strncasecmp(pos, property_name,
+                                                               attrlen) == 0) {
+                                       pos += attrlen;
+
+                                       if (*pos == ':' || *pos == ';') {
+                                               matched = TRUE;
+                                               pos++;
+                                       }
+                               }
+                               continue;
+                       }
+               } else {
+                       if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
+                               pos += 2;
+
+                               if (*pos != ' ' && *pos != '\t') {
+                                       /* +2 means move over \r\n */
+                                       g_string_erase(string,
+                                               (st_pos+2)-(string->str),
+                                               pos-(st_pos+2));
+
+                                       pos = st_pos;
+                                       matched = FALSE;
+                               }
+                               continue;
+                       }
+               }
+
+               pos++;
+       }
+}
+
+static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
+                                       guint64 filter)
+{
+       GString *string = NULL;
+
+       if (vcard == NULL)
+               return NULL;
+
+       string = g_string_new(vcard);
+
+       if ((filter & VCARD_PHOTO) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "PHOTO");
+
+       if ((filter & VCARD_BDAY) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "BDAY");
+
+       if ((filter & VCARD_ADR) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "ADR");
+
+       if ((filter & VCARD_EMAIL) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
+
+       if ((filter & VCARD_TITLE) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "TITLE");
+
+       if ((filter & VCARD_ROLE) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "ROLE");
+
+       if ((filter & VCARD_ORG) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "ORG");
+
+       if ((filter & VCARD_NOTE) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "NOTE");
+
+       if ((filter & VCARD_REV) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "REV");
+
+       if ((filter & VCARD_URL) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "URL");
+
+       if ((filter & VCARD_UID) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "UID");
+
+       if ((filter & VCARD_NICKNAME) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
+
+       return g_string_free(string, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args)
+{
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       GString *str = NULL;
+
+       gint contact_id = 0;
+       gint status;
+
+       guint64 f = filter;
+
+       const gchar *name = first_name;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;;
+       }
+
+       if (f == 0)
+               f = ~f;
+
+       DBG("filter[%x]\n", filter);
+
+       str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
+
+       /* N, TEL is default */
+       __bluetooth_pb_vcard_append_n_v21(str, contact);
+
+       if (phonelog_id > 0) {
+               gchar *number;
+
+               number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0",
+                                                                       number);
+               g_free(number);
+
+
+       } else {
+               __bluetooth_pb_vcard_append_tel_v21(str, contact);
+       }
+
+       if (f & VCARD_FN)
+               __bluetooth_pb_vcard_append_fn_v21(str, person);
+/*     Need to check filter
+       if (f & VCARD_SOUND)*/
+               __bluetooth_pb_vcard_append_phonetic_first_v21(str, contact);
+       if (f & VCARD_PHOTO)
+               __bluetooth_pb_vcard_append_photo_v21(str, person);
+       if (f & VCARD_BDAY)
+               __bluetooth_pb_vcard_append_bday_v21(str, contact);
+       if (f & VCARD_ADR)
+               __bluetooth_pb_vcard_append_adr_v21(str, contact);
+       if (f & VCARD_EMAIL)
+               __bluetooth_pb_vcard_append_email_v21(str, contact);
+       if (f & VCARD_TITLE)
+               __bluetooth_pb_vcard_append_title_v21(str, contact);
+       if (f & VCARD_ROLE)
+               __bluetooth_pb_vcard_append_role_v21(str, contact);
+       if (f & VCARD_ORG)
+               __bluetooth_pb_vcard_append_org_v21(str, contact);
+       if (f & VCARD_NOTE)
+               __bluetooth_pb_vcard_append_note_v21(str, contact);
+       if (f & VCARD_REV)
+               __bluetooth_pb_vcard_append_rev_v21(str, contact);
+       if (f & VCARD_URL)
+               __bluetooth_pb_vcard_append_url_v21(str, contact);
+       if (f & VCARD_UID)
+               __bluetooth_pb_vcard_append_uid_v21(str, contact);
+
+       while (name) {
+               const gchar *param = va_arg(args, const gchar *);
+               const gchar *value = va_arg(args, const gchar *);
+
+               if (value) {
+                       gchar *escaped = NULL;
+
+                       escaped = __bluetooth_pb_vcard_escape(value);
+                       __bluetooth_pb_vcard_append_qp_encode_v21(str, name,
+                                                               param, escaped);
+
+                       g_free(escaped);
+               }
+
+               name = va_arg(args, const gchar *);
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       return g_string_free(str, FALSE);
+}
+
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args)
+{
+       contacts_record_h person = NULL;
+
+       GString *str = NULL;
+
+       gint status;
+
+       const gchar *name = first_name;
+       gchar *vcard = NULL;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_vcard_make_from_person(person, &vcard);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_destroy(person, TRUE);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       str = g_string_new(vcard);
+       g_free(vcard);
+
+       /* append contents on vcard */
+       while (name) {
+               const gchar *param = va_arg(args, const gchar *);
+               const gchar *value = va_arg(args, const gchar *);
+
+               __bluetooth_pb_vcard_append_v30(str, name, param, value);
+
+               name = va_arg(args, const gchar *);
+       }
+
+       /* if phonelog_id exist, we shall show only the phone number, which was
+          used for that phone log */
+       if (phonelog_id > 0) {
+               gchar *number;
+
+               __bluetooth_pb_vcard_remove_v30(str, "TEL");
+
+               number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+               __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
+               g_free(number);
+       }
+
+       vcard = g_string_free(str, FALSE);
+
+       /* temporary fixed for some application crash */
+       if (filter == 0)
+               filter = ~VCARD_NOTE;
+
+       if (filter) {
+               gchar *new_vcard = NULL;
+
+               new_vcard = __bluetooth_pb_vcard_filter_v30(vcard, filter);
+
+               if (new_vcard) {
+                       g_free(vcard);
+                       vcard = new_vcard;
+               }
+       }
+
+       return vcard;
+}
+
+
+static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       guint8 format,
+                                                       const gchar *first_name,
+                                                       ...)
+{
+       DBG(" format [%d]\n", format);
+       gchar *vcard = NULL;
+       va_list args;
+
+       va_start(args, first_name);
+
+       switch (format) {
+       case VCARD_FORMAT_3_0:
+               vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
+                               phonelog_id, filter,
+                               first_name, args);
+               break;
+       case VCARD_FORMAT_2_1:
+       default:
+               vcard = __bluetooth_pb_vcard_real_contact_valist_v21(person_id,
+                               phonelog_id, filter,
+                               first_name, args);
+               break;
+       }
+
+       va_end(args);
+
+       return vcard;
+}
+
+static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
+                                               guint filter,
+                                               const char *attr)
+{
+       GString *str;
+       gchar *number;
+
+       str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
+
+       __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, NULL);
+
+       number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+       __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
+       g_free(number);
+
+       if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
+                       && attr) {
+               gchar *datetime = NULL;
+
+               datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
+               __bluetooth_pb_vcard_append_qp_encode_v21(str,
+                                                       "X-IRMC-CALL-DATETIME",
+                                                       attr, datetime);
+               g_free(datetime);
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       return g_string_free(str, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
+                                               guint filter,
+                                               const gchar *attr)
+{
+       GString *str;
+       gchar *number;
+
+       str = g_string_new("BEGIN:VCARD\r\nVERSION:3.0\r\n");
+
+       __bluetooth_pb_vcard_append_v30(str, "N", NULL, NULL);
+       __bluetooth_pb_vcard_append_v30(str, "FN", NULL, NULL);
+
+       number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+       __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
+       g_free(number);
+
+       if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
+                       && attr) {
+               gchar *datetime = NULL;
+
+               datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
+               __bluetooth_pb_vcard_append_v30(str,
+                               "X-IRMC-CALL-DATETIME", attr, datetime);
+               g_free(datetime);
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       return g_string_free(str, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
+                                       guint filter,
+                                       guint8 format,
+                                       const gchar *attr)
+{
+       DBG("\n");
+       gchar *vcard = NULL;
+
+       switch (format) {
+       case VCARD_FORMAT_3_0:
+               vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
+                               filter, attr);
+               break;
+       case VCARD_FORMAT_2_1:
+       default:
+               vcard = __bluetooth_pb_vcard_real_call_v21(phonelog_id,
+                               filter, attr);
+               break;
+       }
+
+       return vcard;
+}
+
+static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
+                                               int *field,
+                                               gint field_size)
+{
+       gchar **strv;
+
+       gint status;
+       gint i;
+
+       gboolean valid = FALSE;
+
+       /* check empty field */
+       for (i = 0; i < field_size; i++) {
+               gchar *tmp = NULL;
+
+               status = contacts_record_get_str_p(record, field[i], &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (tmp) {
+                       valid = TRUE;
+                       break;
+               }
+       }
+
+       if (valid == FALSE)
+               return NULL;
+
+       strv = g_new0(gchar *, field_size + 1);
+
+       for (i = 0; i < field_size; i++) {
+               gchar *tmp;
+
+               status = contacts_record_get_str_p(record, field[i], &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (tmp == NULL)
+                       strv[i] = g_strdup("");
+               else
+                       strv[i] = __bluetooth_pb_vcard_escape(tmp);
+       }
+
+       return strv;
+}
+
+static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
+{
+       gchar **strv = NULL;
+
+       const gint TEL_PARAM_LEN = 13;
+
+       gint status;
+       gint i = 0;
+
+       contacts_number_type_e type;
+
+       bool is_default = false;
+
+       status = contacts_record_get_bool(number, _contacts_number.is_default,
+                       &is_default);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       strv = g_new0(char *, TEL_PARAM_LEN + 1);/* tel param max size is 13 */
+
+       if (is_default) {
+               strv[i] = g_strdup("PREF");
+               i++;
+       }
+
+       status = contacts_record_get_int(number,
+                       _contacts_number.type,
+                       (gint *)&type);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       if (type & CONTACTS_NUMBER_TYPE_HOME) {
+               strv[i] = g_strdup("HOME");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_WORK) {
+               strv[i] = g_strdup("WORK");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_VOICE) {
+               strv[i] = g_strdup("VOICE");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_FAX) {
+               strv[i] = g_strdup("FAX");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_MSG) {
+               strv[i] = g_strdup("MSG");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_CELL) {
+               strv[i] = g_strdup("CELL");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_PAGER) {
+               strv[i] = g_strdup("PAGER");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_BBS) {
+               strv[i] = g_strdup("BBS");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_MODEM) {
+               strv[i] = g_strdup("MODEM");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_CAR) {
+               strv[i] = g_strdup("CAR");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_ISDN) {
+               strv[i] = g_strdup("ISDN");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_VIDEO) {
+               strv[i] = g_strdup("VIDEO");
+               i++;
+       }
+
+       /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
+       return strv;
+}
+
+
+static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
+{
+       gchar *filetype = NULL;
+       gchar *ext = NULL;
+
+       if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
+               ERR_SECURE("file does not regular:%s\n", filename);
+               return NULL;
+       }
+
+       ext = strrchr(filename, '.');
+       if (ext == NULL) {
+               ERR("file doesn't have extension\n");
+               return NULL;
+       }
+
+       ext++;
+
+       if (g_ascii_strcasecmp(ext, "gif") == 0)
+               filetype = "GIF";
+       else if (g_ascii_strcasecmp(ext, "cgm") == 0)
+               filetype = "CGM";
+       else if (g_ascii_strcasecmp(ext, "wmf") == 0)
+               filetype = "WMF";
+       else if (g_ascii_strcasecmp(ext, "bmp") == 0)
+               filetype = "BMP";
+       else if (g_ascii_strcasecmp(ext, "met") == 0)
+               filetype = "MET";
+       else if (g_ascii_strcasecmp(ext, "dib") == 0)
+               filetype = "DIB";
+       else if (g_ascii_strcasecmp(ext, "pict") == 0 ||
+                       g_ascii_strcasecmp(ext, "pct") == 0 ||
+                       g_ascii_strcasecmp(ext, "pic") == 0)
+               filetype = "PICT";
+       else if (g_ascii_strcasecmp(ext, "tiff") == 0 ||
+                       g_ascii_strcasecmp(ext, "tif") == 0)
+               filetype = "TIFF";
+       else if (g_ascii_strcasecmp(ext, "ps") == 0)
+               filetype = "PS";
+       else if (g_ascii_strcasecmp(ext, "pdf") == 0)
+               filetype = "PDF";
+       else if (g_ascii_strcasecmp(ext, "jpeg") == 0 ||
+                       g_ascii_strcasecmp(ext, "jpg") == 0 ||
+                       g_ascii_strcasecmp(ext, "jpe") == 0)
+               filetype = "JPEG";
+       else if (g_ascii_strcasecmp(ext, "mpeg") == 0 ||
+                       g_ascii_strcasecmp(ext, "mpg") == 0)
+               filetype = "MPEG";
+       else if (g_ascii_strcasecmp(ext, "m2v") == 0)
+               filetype = "MPEG2";
+       else if (g_ascii_strcasecmp(ext, "avi") == 0)
+               filetype = "AVI";
+       else if (g_ascii_strcasecmp(ext, "mov") == 0)
+               filetype = "QTIME";
+       else if (g_ascii_strcasecmp(ext, "png") == 0)
+               filetype = "PNG";
+
+       return g_strdup(filetype);
+}
+
+static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
+{
+       const gint ADDR_LEN = 7;
+
+       gchar **strv = NULL;
+
+       gint addr[] = { _contacts_address.postbox,
+                       _contacts_address.extended,
+                       _contacts_address.street,
+                       _contacts_address.locality,
+                       _contacts_address.region,
+                       _contacts_address.postal_code,
+                       _contacts_address.country };
+
+       strv = __bluetooth_pb_contact_add_field_str(address,
+                       addr, ADDR_LEN);
+       return strv;
+}
+
+static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
+{
+
+       contacts_address_type_e type;
+
+       gint status;
+       gint i = 0;
+
+       gchar **strv = NULL;
+
+       status = contacts_record_get_int(address,
+                       _contacts_address.type,
+                       (gint *)&type);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       strv = g_new0(gchar *, 7);      /* ADDR param max size is 6 */
+
+       if (type & CONTACTS_ADDRESS_TYPE_HOME) {
+               strv[i] = g_strdup("HOME");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_WORK) {
+               strv[i] = g_strdup("WORK");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_DOM) {
+               strv[i] = g_strdup("DOM");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_INTL) {
+               strv[i] = g_strdup("INTL");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_POSTAL) {
+               strv[i] = g_strdup("POSTAL");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_PARCEL) {
+               strv[i] = g_strdup("PARCEL");
+               i++;
+       }
+       return strv;
+}
+
+static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
+{
+       contacts_record_h phone_log;
+
+       char time_str[32] = {0,};
+
+       gint status;
+       gint time = 0;
+
+       struct tm time_info;
+
+       status = contacts_db_get_record(_contacts_phone_log._uri,
+                       phonelog_id,
+                       &phone_log);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_int(phone_log,
+                       _contacts_phone_log.log_time,
+                       &time);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       if (time <= 0)
+               return NULL;
+
+       localtime_r((time_t *)&time, &time_info);
+
+       strftime(time_str, sizeof(time_str),
+                       "%Y%m%dT%H%M%S", &time_info);
+
+       contacts_record_destroy(phone_log, TRUE);
+
+       return g_strdup(time_str);
+}
+
+static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
+{
+       contacts_record_h name = NULL;
+
+       GString *str = g_string_new(NULL);
+
+       gint status;
+       gint i;
+
+       gint name_size = 5;
+       gint name_val[] = { _contacts_name.last,
+                       _contacts_name.first,
+                       _contacts_name.addition,
+                       _contacts_name.prefix,
+                       _contacts_name.suffix };
+
+
+       status = contacts_record_get_child_record_at_p(contact,
+                       _contacts_contact.name, 0, &name);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       for (i = 0; i < name_size; i++) {
+               gchar *tmp = NULL;
+               gchar *escape = NULL;
+
+               if (i > 0)
+                       g_string_append_c(str, ';');
+
+               status = contacts_record_get_str_p(name, name_val[i], &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escape = __bluetooth_pb_vcard_escape(tmp);
+               g_string_append(str, escape);
+
+               g_free(escape);
+       }
+
+       return g_string_free(str, FALSE);
+}
+
+static gchar *__bluetooth_pb_phonetic_name_from_contact(contacts_record_h contact)
+{
+       contacts_record_h name = NULL;
+
+       GString *str = g_string_new(NULL);
+
+       gint status;
+
+       gchar *phonetic_first = NULL;
+       gchar *phonetic_last = NULL;
+       gchar *escape = NULL;
+
+       status = contacts_record_get_child_record_at_p(contact,
+                       _contacts_contact.name, 0, &name);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_str_p(name, _contacts_name.phonetic_first, &phonetic_first);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       if (phonetic_first == NULL)
+               return NULL;
+
+       status = contacts_record_get_str_p(name, _contacts_name.phonetic_last, &phonetic_last);
+
+       if ((status == CONTACTS_ERROR_NONE) && (phonetic_last != NULL)) {
+               escape = __bluetooth_pb_vcard_escape(phonetic_last);
+               g_string_append(str, escape);
+               g_free(escape);
+               g_string_append_c(str, ' ');
+       }
+
+       escape = __bluetooth_pb_vcard_escape(phonetic_first);
+       g_string_append(str, escape);
+
+       g_free(escape);
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+
+       return g_string_free(str, FALSE);
+}
+
+
+static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       gchar *str = NULL;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.number,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h number = NULL;
+
+               gchar *tmp = NULL;
+
+               bool is_default = false;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, i, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_bool(number,
+                               _contacts_number.is_default,
+                               &is_default);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (is_default == FALSE)
+                       continue;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (tmp) {
+                       str = g_strdup(tmp);
+                       break;
+               }
+       }
+
+       /* get first number */
+       if (str == NULL) {
+               gchar *tmp = NULL;
+
+               contacts_record_h number = NULL;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, 0, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return NULL;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return NULL;
+
+               str = g_strdup(tmp);
+       }
+
+       return str;
+}
+
+static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
+{
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_list_h record_list = NULL;
+
+       contacts_record_h phone_log = NULL;
+       contacts_record_h record = NULL;
+
+       gint status;
+       gint person_id = 0;
+
+       status = contacts_db_get_record(_contacts_phone_log._uri,
+                       phonelog_id,
+                       &phone_log);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return 0;
+
+       status = contacts_record_get_int(phone_log,
+                       _contacts_phone_log.person_id,
+                       &person_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(phone_log, TRUE);
+               return 0;
+       }
+
+       contacts_record_destroy(phone_log, TRUE);
+
+       if (person_id)
+               return person_id;
+
+       status = contacts_filter_create(_contacts_person_phone_log._uri,
+                       &filter);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return 0;
+
+
+       status = contacts_filter_add_int(filter,
+                       _contacts_person_phone_log.log_id,
+                       CONTACTS_MATCH_EQUAL,
+                       phonelog_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_query_create(_contacts_person_phone_log._uri, &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_query_set_filter(query, filter);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_db_get_records_with_query(query, -1, -1,
+                                                               &record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_list_get_current_record_p(record_list, &record);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_record_get_int(record,
+                       _contacts_person_phone_log.person_id,
+                       &person_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+done:
+       if (record_list != NULL)
+               contacts_list_destroy(record_list, TRUE);
+
+       contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       return person_id;
+}
+
+/* API for vcard */
+gchar *_bluetooth_pb_vcard_contact(gint person_id,
+                               guint64 filter,
+                               guint8 format)
+{
+       gchar *str = NULL;
+
+       if (person_id <= 0)
+               return NULL;
+
+       str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
+                       filter, format,
+                       NULL);
+       return str;
+}
+
+gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
+                                       guint64 filter,
+                                       guint8 format)
+{
+       GString *str = g_string_new("BEGIN:VCARD\r\n");
+       gchar *fn;
+       gchar *name;
+
+       fn = _bluetooth_pb_owner_name();
+       name = g_strdup_printf("%s;;;;", fn);
+
+       switch (format) {
+       case VCARD_FORMAT_3_0:
+               g_string_append(str, "VERSION:3.0\r\n");
+
+               __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
+               __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
+               __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL",
+                                                                       number);
+               break;
+       case VCARD_FORMAT_2_1:
+       default:
+               g_string_append(str, "VERSION:2.1\r\n");
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
+
+               if (filter == 0 || (filter & VCARD_FN))
+                       __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN",
+                                                               NULL, fn);
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL",
+                                                                       number);
+               break;
+
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       g_free(fn);
+       g_free(name);
+
+       return g_string_free(str, FALSE);
+}
+
+gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
+                               guint64 filter,
+                               guint8 format,
+                               const gchar *attr)
+{
+       gint person_id = 0;
+
+       gchar *str = NULL;
+
+       if (attr == NULL) {
+               DBG("Unknown attribute type ignored\n");
+               return NULL;
+       }
+
+       person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
+
+       DBG("person_id %d\n", person_id);
+
+       if (person_id) {
+               if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
+                       gchar *datetime = NULL;
+
+                       datetime = __bluetooth_pb_phonelog_datetime(
+                                                               phonelog_id);
+
+                       str = __bluetooth_pb_vcard_real_contact_with_properties(
+                                       person_id,
+                                       phonelog_id,
+                                       filter, format,
+                                       "X-IRMC-CALL-DATETIME", attr, datetime,
+                                       NULL);
+
+                       if (datetime)
+                               g_free(datetime);
+               } else {
+                       str = __bluetooth_pb_vcard_real_contact_with_properties(
+                                       person_id,
+                                       phonelog_id,
+                                       filter, format,
+                                       NULL);
+               }
+       } else
+               str = __bluetooth_pb_vcard_real_call(phonelog_id, filter,
+                                                               format, attr);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
+{
+       contacts_record_h person = NULL;
+
+       gint status;
+
+       gchar *str = NULL;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_str(person,
+                       _contacts_person.display_name,
+                       &str);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       contacts_record_destroy(person, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_name_from_person_id(gint person_id)
+{
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       gint status;
+       gint contact_id = 0;
+
+       gchar *str;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       str = __bluetooth_pb_name_from_contact(contact);
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_number_from_person_id(gint person_id)
+{
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       gint status;
+       gint contact_id = 0;
+
+       gchar *str;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       str = __bluetooth_pb_number_from_contact(contact);
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
+{
+       gint person_id = 0;
+       gchar *str = NULL;
+
+       person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
+
+       if (person_id > 0)
+               str = _bluetooth_pb_fn_from_person_id(person_id);
+       else
+               str = g_strdup("");
+
+       return str;
+}
+
+gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
+{
+       gint person_id = 0;
+       gchar *str = NULL;
+
+       person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
+
+       if (person_id > 0)
+               str = _bluetooth_pb_name_from_person_id(person_id);
+       else {
+               gchar *tmp;
+
+               tmp = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+               str = g_strdup_printf("%s;;;;", tmp);
+
+               g_free(tmp);
+       }
+
+       return str;
+}
+
+gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
+{
+       contacts_record_h phone_log;
+
+       gint status;
+
+       gchar *str;
+       gchar *tmp = NULL;
+
+       status = contacts_db_get_record(_contacts_phone_log._uri,
+                       phonelog_id, &phone_log);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       contacts_record_get_str_p(phone_log,
+                       _contacts_phone_log.address,
+                       &tmp);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(phone_log, TRUE);
+               return NULL;
+       }
+
+       str = g_strdup(tmp);
+
+       contacts_record_destroy(phone_log, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_owner_name(void)
+{
+       gchar *name;
+
+       name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
+
+       if (name == NULL)
+               name = g_strdup("My Name");
+
+       return name;
+}
diff --git a/mobile/pb-agent/bluetooth_pb_vcard.h b/mobile/pb-agent/bluetooth_pb_vcard.h
new file mode 100644 (file)
index 0000000..24d9675
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * bluetooth-agent
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_PB_VCARD_H_
+#define __DEF_BT_PB_VCARD_H_
+
+#include <glib.h>
+
+/* vcard */
+gchar *_bluetooth_pb_vcard_contact(gint person_id,
+                               guint64 filter,
+                               guint8 format);
+
+gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
+                                       guint64 filter,
+                                       guint8 format);
+
+gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
+                               guint64 filter,
+                               guint8 format,
+                               const gchar *attr);
+
+gchar *_bluetooth_pb_fn_from_person_id(gint person_id);
+
+gchar *_bluetooth_pb_name_from_person_id(gint person_id);
+
+gchar *_bluetooth_pb_number_from_person_id(gint person_id);
+
+gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id);
+
+gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id);
+
+gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id);
+
+gchar *_bluetooth_pb_owner_name(void);
+
+#endif
diff --git a/mobile/pb-agent/org.bluez.pb_agent.service b/mobile/pb-agent/org.bluez.pb_agent.service
new file mode 100644 (file)
index 0000000..c4426a3
--- /dev/null
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.bluez.pb_agent
+Exec=/usr/bin/bluetooth-pb-agent
+User=root
diff --git a/packaging/bluetooth-agent.spec b/packaging/bluetooth-agent.spec
new file mode 100644 (file)
index 0000000..fe2e783
--- /dev/null
@@ -0,0 +1,97 @@
+Name:       bluetooth-agent
+Summary:    Bluetooth agent packages that support various external profiles
+Version:    0.0.10
+Release:    1
+Group:      TO_BE/FILLED_IN
+License:    Apache License, Version 2.0
+Source0:    %{name}-%{version}.tar.gz
+
+Requires(post): sys-assert
+BuildRequires:  pkgconfig(aul)
+BuildRequires:  pkgconfig(dbus-glib-1)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(appsvc)
+BuildRequires:  pkgconfig(capi-appfw-application)
+BuildRequires:  pkgconfig(capi-media-image-util)
+BuildRequires:  pkgconfig(libexif)
+BuildRequires:  pkgconfig(vconf)
+%if %{_repository}=="wearable"
+BuildRequires:  pkgconfig(bluetooth-api)
+BuildRequires:  pkgconfig(alarm-service)
+BuildRequires:  pkgconfig(capi-appfw-app-manager)
+BuildRequires:  pkgconfig(syspopup-caller)
+BuildRequires:  pkgconfig(deviced)
+%endif
+%if %{_repository}=="mobile"
+BuildRequires:  pkgconfig(contacts-service2)
+BuildRequires:  pkgconfig(msg-service)
+BuildRequires:  pkgconfig(email-service)
+BuildRequires:  pkgconfig(tapi)
+%endif
+BuildRequires:  cmake
+
+%description
+Bluetooth agent packages that support various external profiles
+
+%prep
+%setup -q
+
+%build
+%if %{_repository}=="wearable"
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+
+export CFLAGS+=" -fpie -fvisibility=hidden"
+export LDFLAGS+=" -Wl,--rpath=/usr/lib -Wl,--as-needed -Wl,--unresolved-symbols=ignore-in-shared-libs -pie"
+
+%if %{_repository}=="wearable"
+cd wearable
+cmake . -DCMAKE_INSTALL_PREFIX=/usr \
+       -DFEATURE_TIZENW=YES \
+%elseif %{_repository}=="mobile"
+cd mobile
+cmake . -DCMAKE_INSTALL_PREFIX=/usr
+%endif
+
+make VERBOSE=1
+
+%install
+rm -rf %{buildroot}
+
+%if %{_repository}=="wearable"
+cd wearable
+%elseif %{_repository}=="mobile"
+cd mobile
+%endif
+
+%make_install
+
+%if %{_repository}=="wearable"
+install -D -m 0644 LICENSE.APLv2 %{buildroot}%{_datadir}/license/bluetooth-agent
+%elseif %{_repository}=="mobile"
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+%endif
+
+%files
+%if %{_repository}=="wearable"
+%manifest %{_repository}/bluetooth-agent.manifest
+%defattr(-, root, root)
+%{_bindir}/bluetooth-hf-agent
+%{_datadir}/license/bluetooth-agent
+%{_datadir}/dbus-1/services/org.bluez.hf_agent.service
+%elseif %{_repository}=="mobile"
+%manifest %{_repository}/bluetooth-agent.manifest
+/opt/etc/smack/accesses.d/bluetooth-agent.rule
+%defattr(-, root, root)
+%{_bindir}/bluetooth-map-agent
+%{_bindir}/bluetooth-pb-agent
+%{_bindir}/bluetooth-hfp-agent
+%{_datadir}/dbus-1/services/org.bluez.pb_agent.service
+%{_datadir}/dbus-1/services/org.bluez.map_agent.service
+%{_datadir}/dbus-1/services/org.bluez.hfp_agent.service
+/usr/share/license/%{name}
+%endif
+
diff --git a/wearable/AUTHORS b/wearable/AUTHORS
new file mode 100644 (file)
index 0000000..1a599df
--- /dev/null
@@ -0,0 +1,4 @@
+Hocheol Seo <hocheol.seo@samsung.com>
+Girish Ashok Joshi <girish.joshi@samsung.com>
+Chanyeol Park <chanyeol.park@samsung.com>
+DoHyun Pyun <dh79.pyun@samsung.com>
diff --git a/wearable/CMakeLists.txt b/wearable/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2327e2f
--- /dev/null
@@ -0,0 +1,4 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+ADD_SUBDIRECTORY(hf-agent)
+
diff --git a/wearable/LICENSE.APLv2 b/wearable/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..6b0b127
--- /dev/null
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/wearable/NOTICE b/wearable/NOTICE
new file mode 100644 (file)
index 0000000..0e0f016
--- /dev/null
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/wearable/bluetooth-agent.manifest b/wearable/bluetooth-agent.manifest
new file mode 100644 (file)
index 0000000..fd520d8
--- /dev/null
@@ -0,0 +1,25 @@
+<manifest>
+    <define>
+        <domain name="bt_agent"/>
+       <request>
+               <smack request="device::app_logging" type="w"/>
+               <smack request="device::sys_logging" type="w"/>
+               <smack request="system::vconf" type="rwxat"/>
+               <smack request="system::share" type="rwxat"/>
+               <smack request="sys-assert::core" type="rwxat"/>
+               <smack request="dbus" type="w"/>
+               <smack request="telephony_framework::api_sim" type="r"/>
+               <smack request="telephony_framework::api_sms" type="r"/>
+               <smack request="contacts-service::svc" type="rw"/>
+               <smack request="contacts-service::phonelog" type="rw"/>
+               <smack request="system::vconf_network" type="r"/>
+               <smack request="deviced::display" type="rw"/>
+       </request>
+       <permit>
+               <smack permit="dbus" type="rwx"/>
+       </permit>
+    </define>
+    <request>
+        <domain name="bt_agent"/>
+    </request>
+</manifest>
diff --git a/wearable/hf-agent/CMakeLists.txt b/wearable/hf-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f46147d
--- /dev/null
@@ -0,0 +1,30 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-hf-agent C)
+
+SET(SRCS bluetooth-hf-agent.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+IF(FEATURE_TIZENW)
+       ADD_DEFINITIONS("-DFEATURE_TIZENW")
+ENDIF(FEATURE_TIZENW)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_hf_agent
+               REQUIRED
+               dlog aul bluetooth-api alarm-service capi-appfw-app-manager
+               syspopup-caller glib-2.0 gio-2.0 gio-unix-2.0
+               deviced vconf)
+
+FOREACH(flag ${pkgs_hf_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_hf_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.hf_agent.service
+               DESTINATION share/dbus-1/services)
diff --git a/wearable/hf-agent/bluetooth-hf-agent.c b/wearable/hf-agent/bluetooth-hf-agent.c
new file mode 100755 (executable)
index 0000000..3966037
--- /dev/null
@@ -0,0 +1,3044 @@
+/*
+ * Bluetooth-hf-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Chethan T N <chethan.tn@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <aul.h>
+#include <gio/gio.h>
+#include <gio/gunixfdlist.h>
+#ifdef FEATURE_TIZENW
+#include <bluetooth-api.h>
+#include <bluetooth-audio-api.h>
+#endif
+#include <syspopup_caller.h>
+#include <dd-display.h>
+#include <app_manager.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "alarm.h"
+#include "bluetooth-hf-agent.h"
+
+/* LE Auto connection defines */
+#define MANUFACTURER_DATA_TYPE         0xFF
+#define MANUFACTURER_DATA_CID          0x75    /* Samsung */
+#define ADVERTISING_INTERVAL_MIN       500     /* ms */
+#define ADVERTISING_INTERVAL_MAX       500     /* ms */
+#define ADVERTISING_FILTER_DEFAULT     0x00
+#define ADVERTISING_FILTER_ALLOW_SCAN_CONN_WL  0x03
+
+#ifdef FEATURE_TIZENW
+#define ADVERTISING_INITIAL_TIMEOUT    8       /* sec */
+#else
+#define ADVERTISING_INITIAL_TIMEOUT    30      /* sec */
+#define ADVERTISING_SHORT_INTERVAL_MIN 150     /* ms */
+#define ADVERTISING_SHORT_INTERVAL_MAX 150     /* ms */
+#endif /* FEATURE_TIZENW */
+/* End of LE Auto connection defines */
+
+#define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
+#define CALL_APP_ID "org.tizen.call"
+
+#define MAX_WAITING_DELAY 8
+
+#define BT_ADDRESS_STRING_SIZE 18
+
+#define ret_if(expr) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) return", #expr); \
+                       return; \
+               } \
+       } while (0)
+
+static GMainLoop *gmain_loop = NULL;
+static char *g_obj_path;
+
+static GDBusConnection *gdbus_conn;
+static GDBusProxy *service_gproxy;
+static int owner_sig_id = -1;
+
+/*Below Inrospection data is exposed to bluez from agent*/
+static const gchar hf_agent_bluez_introspection_xml[] =
+"<node name='/'>"
+" <interface name='org.bluez.HandsfreeAgent'>"
+"     <method name='NewConnection'>"
+"          <arg type='h' name='fd' direction='in'/>"
+"          <arg type='q' name='version' direction='in'/>"
+"     </method>"
+"     <method name='Release'/>"
+"  </interface>"
+"</node>";
+
+/*Below Inrospection data is exposed to application from agent*/
+static const gchar hf_agent_introspection_xml[] =
+"<node name='/'>"
+" <interface name='org.tizen.HfApp'>"
+"              <method name='AnswerCall'>"
+"               </method>"
+"               <method name='TerminateCall'>"
+"               </method>"
+"               <method name='InitiateCall'>"
+"                       <arg type='s' name='phoneno' direction='in'/>"
+"               </method>"
+"               <method name='VoiceRecognition'>"
+"                       <arg type='i' name='status' direction='in'/>"
+"               </method>"
+"               <method name='ScoDisconnect'>"
+"               </method>"
+"               <method name='SpeakerGain'>"
+"                       <arg type='u' name='gain' direction='in'/>"
+"               </method>"
+"               <method name='SendDtmf'>"
+"                       <arg type='s' name='dtmf' direction='in'/>"
+"               </method>"
+"               <method name='SendAtCmd'>"
+"                       <arg type='s' name='atcmd' direction='in'/>"
+"               </method>"
+"               <method name='ReleaseAndAccept'>"
+"               </method>"
+"               <method name='CallSwap'>"
+"               </method>"
+"               <method name='ReleaseAllCall'>"
+"               </method>"
+"               <method name='JoinCall'>"
+"               </method>"
+"               <method name='GetCurrentCodec'>"
+"                      <arg type='i' name='codec' direction='out'/>"
+"               </method>"
+"               <method name='RequestCallList'>"
+"                      <arg type='i' name='count' direction='out'/>"
+"                      <arg type='a(siiii)' name='callList' direction='out'/>"
+"               </method>"
+"               <method name='GetAudioConnected'>"
+"                      <arg type='i' name='status' direction='out'/>"
+"               </method>"
+"               <method name='IsHfConnected'>"
+"                      <arg type='b' name='status' direction='out'/>"
+"               </method>"
+" </interface>"
+"</node>";
+
+static bt_hf_agent_info_t bt_hf_info;
+static gboolean is_hf_connected = FALSE;
+static alarm_id_t adv_timer_id = 0;
+static int32_t current_codec_id = BT_HF_CODEC_ID_CVSD;
+static int32_t sco_audio_connected = BT_HF_AUDIO_DISCONNECTED;
+
+static char prev_cmd[BT_HF_CMD_BUF_SIZE];
+
+typedef struct {
+       int idx;
+       int dir;
+       int status;
+       int mode;
+       int multi_party;
+       int type;
+       char *number;
+} hf_call_list_info_t;
+
+static GError *__bt_hf_agent_set_error(bt_hf_agent_error_t error);
+static int __bt_hf_agent_get_error(const char *error_message);
+static gboolean __bt_hf_agent_emit_property_changed(
+                               GDBusConnection *connection,
+                               const char *path,
+                               const char *interface,
+                               const char *name,
+                               GVariant *property);
+
+static gboolean __bt_hf_agent_data_cb(GIOChannel *chan, GIOCondition cond,
+                                       bt_hf_agent_info_t *bt_hf_info);
+static void __bt_hf_agent_stop_watch(bt_hf_agent_info_t *bt_hf_info);
+static void __bt_hf_agent_start_watch(bt_hf_agent_info_t *bt_hf_info);
+static gboolean __bt_hf_channel_write(GIOChannel *io, gchar *data,
+                                       gsize count);
+static gboolean __bt_hf_send_only(bt_hf_agent_info_t *bt_hf_info, gchar *data,
+                                       gsize count);
+static gboolean __bt_hf_send_and_read(bt_hf_agent_info_t *bt_hf_info,
+                               gchar *data, gchar *response, gsize count);
+static GSList *__bt_hf_parse_indicator_names(gchar *names, GSList *indies);
+static GSList *__bt_hf_parse_indicator_values(gchar *values, GSList *indies);
+static guint __bt_hf_get_hold_mpty_features(gchar *features);
+static gboolean __bt_establish_service_level_conn(bt_hf_agent_info_t *bt_hf_info);
+static void __bt_hf_agent_sigterm_handler(int signo);
+static gboolean __bt_hf_agent_release(void);
+
+static gboolean __bt_get_current_indicators(bt_hf_agent_info_t *bt_hf_info);
+static gboolean __bt_get_supported_indicators(bt_hf_agent_info_t *bt_hf_info);
+static gboolean __bt_hf_agent_connection(gint32 fd, guint16 version);
+static gboolean __bt_hf_agent_connection_release(void);
+
+struct indicator {
+       gchar descr[BT_HF_INDICATOR_DESCR_SIZE];
+       gint value;
+};
+
+static int _hf_agent_answer_call(void);
+
+static int _hf_agent_terminate_call(void);
+
+static int _hf_agent_dial_no(char *no);
+
+static int _hf_agent_set_speaker_gain(unsigned int gain);
+
+static int _hf_agent_send_cmd_read_resp(char *cmd);
+
+static int _hf_agent_voice_recognition(unsigned int status);
+
+static gboolean bt_hf_agent_sco_disconnect(void);
+
+static int _hf_agent_send_dtmf(char *dtmf);
+
+static GVariant *bt_hf_agent_request_call_list(void);
+
+static int bt_hf_agent_send_at_cmd(char *atcmd);
+
+static GQuark __bt_hf_agent_error_quark(void)
+{
+       DBG("\n");
+
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string("hf-agent");
+
+       return quark;
+}
+
+static GError *__bt_hf_agent_set_error(bt_hf_agent_error_t error)
+{
+       ERR("error[%d]\n", error);
+
+       switch (error) {
+       case BT_HF_AGENT_ERROR_NOT_AVAILABLE:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_AVAILABLE);
+       case BT_HF_AGENT_ERROR_NOT_CONNECTED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_CONNECTED);
+       case BT_HF_AGENT_ERROR_CONNECTION_FAILED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NOT_CONNECTION_FAILED);
+       case BT_HF_AGENT_ERROR_BUSY:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_BUSY);
+       case BT_HF_AGENT_ERROR_INVALID_PARAM:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_INVALID_PARAM);
+       case BT_HF_AGENT_ERROR_ALREADY_EXIST:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_ALREADY_EXIST);
+       case BT_HF_AGENT_ERROR_ALREADY_CONNECTED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_ALREADY_CONNECTED);
+       case BT_HF_AGENT_ERROR_NO_MEMORY:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_NO_MEMORY);
+       case BT_HF_AGENT_ERROR_I_O_ERROR:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_I_O_ERROR);
+       case BT_HF_AGENT_ERROR_APPLICATION:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_AVAILABLE);
+       case BT_HF_AGENT_ERROR_NOT_ALLOWED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_ALLOWED);
+       case BT_HF_AGENT_ERROR_NOT_SUPPORTED:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_SUPPORTED);
+       case BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                       BT_ERROR_INVALID_FILE_DESCRIPTOR);
+       case BT_HF_AGENT_ERROR_INTERNAL:
+       default:
+               return g_error_new(BT_HF_AGENT_ERROR, error,
+                                               BT_ERROR_INTERNAL);
+       }
+}
+
+static int __bt_hf_agent_get_error(const char *error_message)
+{
+       if (error_message == NULL) {
+               DBG("Error message NULL\n");
+               return BT_HF_AGENT_ERROR_INTERNAL;
+       }
+
+       ERR("Error message = %s\n", error_message);
+
+       if (g_strcmp0(error_message, BT_ERROR_NOT_AVAILABLE) == 0)
+               return BT_HF_AGENT_ERROR_NOT_AVAILABLE;
+       else if (g_strcmp0(error_message, BT_ERROR_NOT_CONNECTED) == 0)
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       else if (g_strcmp0(error_message, BT_ERROR_BUSY) == 0)
+               return BT_HF_AGENT_ERROR_BUSY;
+       else if (g_strcmp0(error_message, BT_ERROR_INVALID_PARAM) == 0)
+               return BT_HF_AGENT_ERROR_INVALID_PARAM;
+       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_EXIST) == 0)
+               return BT_HF_AGENT_ERROR_ALREADY_EXIST;
+       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_CONNECTED) == 0)
+               return BT_HF_AGENT_ERROR_ALREADY_CONNECTED;
+       else if (g_strcmp0(error_message, BT_ERROR_NO_MEMORY) == 0)
+               return BT_HF_AGENT_ERROR_NO_MEMORY;
+       else if (g_strcmp0(error_message, BT_ERROR_I_O_ERROR) == 0)
+               return BT_HF_AGENT_ERROR_I_O_ERROR;
+       else
+               return BT_HF_AGENT_ERROR_INTERNAL;
+}
+
+#ifdef FEATURE_TIZENW
+static void __bt_set_adv_data(void)
+{
+       int len = 0;
+       int is_setup = 0;
+       bluetooth_advertising_data_t adv;
+
+       /*
+        * Advertising data format
+        * Service ID : 00 02
+        * Device ID : 00 01(b2), 00 02(wing-tip)
+        * Version : 01
+        * Purpose : 01 (setup), 02 (auto connection)
+        */
+
+       memset(adv.data, 0x00, sizeof(adv.data));
+       adv.data[len++] = 9;    /* length */
+       adv.data[len++] = MANUFACTURER_DATA_TYPE;
+       adv.data[len++] = 0x00;
+       adv.data[len++] = MANUFACTURER_DATA_CID;
+
+       /* Service ID */
+       adv.data[len++] = 0x00;
+       adv.data[len++] = 0x02;
+
+       /* Device ID */
+       adv.data[len++] = 0x00;
+       adv.data[len++] = 0x01;
+
+       /* Version */
+       adv.data[len++] = 0x01;
+
+       /* Purpose */
+       if (vconf_get_int(VCONFKEY_SETUP_WIZARD_STATE, &is_setup) < 0)
+               ERR("vconf_get_int is failed");
+       adv.data[len++] = is_setup ? 0x01 : 0x02;
+
+       bluetooth_set_advertising_data(&adv, len);
+}
+
+static void __bt_start_adv(void)
+{
+       int ret;
+
+       DBG("Try Lock");
+       ret = display_lock_state(LCD_OFF, STAY_CUR_STATE, 2000);
+       if (ret >= 0)
+               DBG("Lock PM state as current state!");
+       else
+               DBG("deviced error!");
+
+
+       __bt_set_adv_data();
+
+       DBG("*** Start ADV ***\n");
+       bluetooth_set_custom_advertising(TRUE, ADVERTISING_INTERVAL_MIN,
+                       ADVERTISING_INTERVAL_MAX,
+                       ADVERTISING_FILTER_DEFAULT);
+
+       return;
+}
+
+static void __bt_stop_adv(void)
+{
+       DBG("*** Stop ADV ***\n");
+       bluetooth_set_advertising(FALSE);
+       return;
+}
+
+int __bt_start_adv_timer_cb(alarm_id_t alarm_id, void *data)
+{
+       DBG("*** Advertising timer expired ***\n");
+
+       if (adv_timer_id > 0) {
+               DBG("Other alarm was already started\n");
+               alarmmgr_remove_alarm(adv_timer_id);
+               adv_timer_id =  0;
+       }
+
+       if (is_hf_connected) {
+               DBG("Already connected to HF");
+               return 0;
+       }
+
+       __bt_start_adv();
+
+       return 0;
+}
+
+static void __bt_start_adv_timer(void)
+{
+       int ret_val;
+
+       if (is_hf_connected) {
+               DBG("Already connected to HF");
+               return;
+       }
+
+       if (adv_timer_id > 0) {
+               DBG("Other alarm was already started\n");
+               alarmmgr_remove_alarm(adv_timer_id);
+               adv_timer_id = 0;
+       }
+
+       ret_val = alarmmgr_set_cb(__bt_start_adv_timer_cb, NULL);
+       if (ret_val != ALARMMGR_RESULT_SUCCESS) {
+               DBG("alarmmgr_set_cb is failed : 0x%X\n", ret_val);
+               return;
+       }
+
+       ret_val = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE,
+                                    ADVERTISING_INITIAL_TIMEOUT, 0, NULL,
+                                    &adv_timer_id);
+       if (ret_val != ALARMMGR_RESULT_SUCCESS) {
+               DBG("alarmmgr_add_alarm is failed : 0x%X\n", ret_val);
+               return;
+       }
+
+       return;
+}
+
+static int  __bt_get_last_bonded_device(bluetooth_device_address_t *device_address)
+{
+       DBG("+");
+       int ret;
+       int i;
+       bluetooth_device_info_t *ptr;
+
+       GPtrArray *dev_list = NULL;
+       dev_list = g_ptr_array_new();
+
+       ret = bluetooth_get_bonded_device_list(&dev_list);
+       if (ret < 0) {
+               DBG("failed bluetooth_get_bonded_device_list");
+               g_ptr_array_free(dev_list, TRUE);
+               return 1;
+       }
+       DBG("g pointer arrary count : [%d]", dev_list->len);
+
+       if (dev_list->len == 0) {
+               DBG("No paired device found");
+               g_ptr_array_free(dev_list, TRUE);
+               return 1;
+       }
+
+       for (i = 0; i < dev_list->len; i++) {
+               ptr = g_ptr_array_index(dev_list, i);
+               if (ptr == NULL)
+                       continue;
+               DBG("[%d] %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", i + 1,
+                       ptr->device_address.addr[0], ptr->device_address.addr[1],
+                       ptr->device_address.addr[2], ptr->device_address.addr[3],
+                       ptr->device_address.addr[4], ptr->device_address.addr[5]);
+               memcpy(device_address->addr, ptr->device_address.addr,
+                               sizeof(bluetooth_device_address_t));
+               DBG("\n");
+       }
+       g_ptr_array_foreach(dev_list, (GFunc)g_free, NULL);
+       g_ptr_array_free(dev_list, TRUE);
+       DBG("-");
+       return 0;
+}
+
+static gboolean __bt_hf_auto_connect(void)
+{
+       int ret;
+       bluetooth_device_address_t device_address = { {0} };
+
+       if (is_hf_connected) {
+               DBG("Already connected to HF");
+               return FALSE;
+       }
+
+       ret = __bt_get_last_bonded_device(&device_address);
+       if (ret != 0) {
+               DBG("Error in getting last bonded device.....");
+               return FALSE;
+       }
+
+       DBG("*** Try to connect ***\n");
+       ret = bluetooth_hf_connect(&device_address);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               DBG("*** Connect is failed ***\n");
+               return FALSE;
+       }
+       DBG("*** Connect is done ***\n");
+
+       return TRUE;
+}
+
+/* Dummy event handler for bluetooth_get_bonded_device_list */
+void __hf_event_handler(int event, bt_hf_event_param_t *param, void *data)
+{
+       /* No need to handle events */
+       return;
+}
+#endif /* FEATURE_TIZENW */
+
+static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data)
+{
+       int ret;
+       static int retry_count;
+       bundle *b = (bundle *)user_data;
+       retv_if(user_data == NULL, FALSE);
+
+       ++retry_count;
+
+       ret = syspopup_launch("bt-syspopup", b);
+       if (ret < 0) {
+               ERR("Sorry! Can't launch popup, ret=%d, Re-try[%d] time..",
+                                                       ret, retry_count);
+               if (retry_count >= BT_AGENT_SYSPOPUP_MAX_ATTEMPT) {
+                       ERR("Sorry!! Max retry %d reached", retry_count);
+                       bundle_free(b);
+                       retry_count = 0;
+                       return FALSE;
+               }
+       } else {
+               DBG("Hurray!! Finally Popup launched");
+               retry_count = 0;
+               bundle_free(b);
+       }
+
+       return (ret < 0) ? TRUE : FALSE;
+}
+
+static int __launch_system_popup(bt_hfp_agent_event_type_t event_type)
+{
+       int ret;
+       bundle *b;
+       char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
+
+       DBG("_bt_agent_launch_system_popup: Toast popup +");
+
+       b = bundle_create();
+       if (!b)
+               return -1;
+
+       switch (event_type) {
+       case BT_AGENT_EVENT_HANDSFREE_DISCONNECT:
+               g_strlcpy(event_str, "handsfree-disconnect-request", sizeof(event_str));
+               break;
+
+       case BT_AGENT_EVENT_HANDSFREE_CONNECT:
+               g_strlcpy(event_str, "handsfree-connect-request", sizeof(event_str));
+               break;
+
+       default:
+               bundle_free(b);
+               return -1;
+       }
+
+       bundle_add(b, "event-type", event_str);
+       ret = syspopup_launch("bt-syspopup", b);
+       if (0 > ret) {
+               DBG("Popup launch failed...retry %d\n", ret);
+
+               g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
+                                 (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
+       } else {
+               bundle_free(b);
+       }
+
+       DBG("_bt_agent_launch_system_popup -%d", ret);
+       return 0;
+}
+
+static void __hf_agent_method(GDBusConnection *connection,
+                           const gchar *sender,
+                           const gchar *object_path,
+                           const gchar *interface_name,
+                           const gchar *method_name,
+                           GVariant *parameters,
+                           GDBusMethodInvocation *invocation,
+                           gpointer user_data)
+{
+       DBG("+");
+
+       DBG("method %s", method_name);
+       int ret = 0;
+       GError *err;
+
+       if (g_strcmp0(method_name, "NewConnection") == 0) {
+               gint32 fd;
+               int index;
+               guint16 version;
+               GDBusMessage *msg;
+               GUnixFDList *fd_list;
+
+               g_variant_get(parameters, "(hq)", &index, &version);
+               msg = g_dbus_method_invocation_get_message(invocation);
+               fd_list = g_dbus_message_get_unix_fd_list(msg);
+               if (fd_list == NULL) {
+                       ret = BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR;
+                       goto fail;
+               }
+
+               fd = g_unix_fd_list_get(fd_list, index, NULL);
+               if (fd == -1) {
+                       ret = BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR;
+                       goto fail;
+               }
+
+               DBG("FD is = [%d], version = [%d]\n", fd, version);
+
+               if (!__bt_hf_agent_connection(fd, version)) {
+                       ret = BT_HF_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "Release") == 0) {
+               if (!__bt_hf_agent_connection_release()) {
+                       ret = BT_HF_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "AnswerCall") == 0) {
+               DBG("Going to call AnswerCall");
+               ret = _hf_agent_answer_call();
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "TerminateCall") == 0) {
+               DBG("Going to call TerminateCall");
+               ret = _hf_agent_terminate_call();
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "InitiateCall") == 0) {
+               char *phoneno = NULL;
+
+               g_variant_get(parameters, "(&s)", &phoneno);
+
+               DBG_SECURE("Going to call InitiateCall, Number is = [%s]\n", phoneno);
+               ret = _hf_agent_dial_no(phoneno);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "VoiceRecognition") == 0) {
+               int status = 0;
+
+               g_variant_get(parameters, "(i)", &status);
+
+               DBG("Going to call VoiceRecognition, Status [%d]", status);
+               ret = _hf_agent_voice_recognition(status);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "ScoDisconnect") == 0) {
+               DBG("Going to call ScoDisconnect");
+               if (!bt_hf_agent_sco_disconnect()) {
+                       ret = BT_HF_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "SpeakerGain") == 0) {
+               unsigned int gain = 0;
+
+               g_variant_get(parameters, "(u)", &gain);
+
+               DBG("Going to call SpeakerGain, gain is = [%d]\n", gain);
+               ret = _hf_agent_set_speaker_gain(gain);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "SendDtmf") == 0) {
+               char *dtmf = NULL;
+
+               g_variant_get(parameters, "(&s)", &dtmf);
+
+               DBG("Going to call SendDtmf, dtmf is = [%s]\n", dtmf);
+               ret = _hf_agent_send_dtmf(dtmf);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "SendAtCmd") == 0) {
+               char *cmd = NULL;
+
+               g_variant_get(parameters, "(&s)", &cmd);
+
+               DBG("Going to call SendAtCmd, cmd is = [%s]\n", cmd);
+               ret = bt_hf_agent_send_at_cmd(cmd);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "ReleaseAndAccept") == 0) {
+               DBG("Going to call ReleaseAndAccept");
+               ret = _hf_agent_send_cmd_read_resp(BT_HF_RELEASE_AND_ACCEPT);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "CallSwap") == 0) {
+               DBG("Going to call CallSwap");
+               ret = _hf_agent_send_cmd_read_resp(BT_HF_ACCEPT_AND_HOLD);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "ReleaseAllCall") == 0) {
+               DBG("Going to call ReleaseAllCall");
+               ret = _hf_agent_send_cmd_read_resp(BT_HF_RELEASE_ALL);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "JoinCall") == 0) {
+               DBG("Going to call JoinCall");
+               ret = _hf_agent_send_cmd_read_resp(BT_HF_JOIN_CALL);
+               if (ret)
+                       goto fail;
+
+               g_dbus_method_invocation_return_value(invocation, NULL);
+       } else if (g_strcmp0(method_name, "GetCurrentCodec") == 0) {
+               DBG("Going to call GetCurrentCodec");
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", current_codec_id));
+       } else if (g_strcmp0(method_name, "RequestCallList") == 0) {
+               GVariant *call_var;
+
+               DBG("Going to call RequestCallList");
+               call_var = bt_hf_agent_request_call_list();
+               if (!call_var) {
+                       ret = BT_HF_AGENT_ERROR_NOT_AVAILABLE;
+                       goto fail;
+               }
+               g_dbus_method_invocation_return_value(invocation, call_var);
+       } else if (g_strcmp0(method_name, "GetAudioConnected") == 0) {
+               DBG("Going to call GetAudioConnected");
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", sco_audio_connected));
+       } else if (g_strcmp0(method_name, "IsHfConnected") == 0) {
+               DBG("Going to call IsHfConnected");
+               DBG("is_hf_connected : %s", is_hf_connected ? "Connected":"Disconnected");
+
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(b)", is_hf_connected));
+       }
+       DBG("-");
+       return;
+
+fail:
+       err = __bt_hf_agent_set_error(ret);
+       g_dbus_method_invocation_return_gerror(invocation, err);
+       g_error_free(err);
+       DBG("-");
+}
+
+static const GDBusInterfaceVTable method_table = {
+       __hf_agent_method,
+       NULL,
+       NULL,
+};
+
+static GDBusNodeInfo *__bt_hf_create_method_node_info
+                                       (const gchar *introspection_data)
+{
+       if (introspection_data == NULL)
+               return NULL;
+
+       return g_dbus_node_info_new_for_xml(introspection_data, NULL);
+}
+
+static GDBusConnection *__bt_hf_get_gdbus_connection(void)
+{
+       DBG("+");
+
+       GError *err = NULL;
+
+       if (gdbus_conn == NULL)
+               gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+
+       if (!gdbus_conn) {
+               if (err) {
+                       ERR("Unable to connect to dbus: %s", err->message);
+                       g_clear_error(&err);
+               }
+               return NULL;
+       }
+       DBG("-");
+
+       return gdbus_conn;
+}
+
+static gboolean __bt_hf_register_profile_methods(void)
+{
+       DBG("+");
+       GError *error = NULL;
+       guint object_id;
+       guint owner_id;
+       GDBusNodeInfo *node_info;
+       gchar *path;
+
+       owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+                               BT_HF_SERVICE_NAME,
+                               G_BUS_NAME_OWNER_FLAGS_NONE,
+                               NULL, NULL, NULL,
+                               NULL, NULL);
+
+       DBG("owner_id is [%d]", owner_id);
+
+       node_info = __bt_hf_create_method_node_info(
+                               hf_agent_bluez_introspection_xml);
+       if (node_info == NULL)
+               return FALSE;
+
+       path = g_strdup(BT_HF_BLUEZ_OBJECT_PATH);
+       DBG("path is [%s]", path);
+
+       object_id = g_dbus_connection_register_object(gdbus_conn, path,
+                                       node_info->interfaces[0],
+                                       &method_table,
+                                       NULL, NULL, &error);
+       if (object_id == 0) {
+               ERR("Failed to register: %s", error->message);
+               g_error_free(error);
+               g_free(path);
+               return FALSE;
+       }
+       g_free(path);
+
+       node_info = __bt_hf_create_method_node_info(hf_agent_introspection_xml);
+       if (node_info == NULL)
+               return FALSE;
+
+       path = g_strdup(BT_HF_AGENT_OBJECT_PATH);
+       DBG("path is [%s]", path);
+
+       object_id = g_dbus_connection_register_object(gdbus_conn, path,
+                                               node_info->interfaces[0],
+                                               &method_table,
+                                               NULL, NULL, &error);
+       if (object_id == 0) {
+               ERR("Failed to register: %s", error->message);
+               g_error_free(error);
+               g_free(path);
+               return FALSE;
+       }
+       g_free(path);
+
+       DBG("-");
+       return TRUE;
+}
+
+static GDBusProxy *__bt_hf_gdbus_init_service_proxy(const gchar *service,
+                               const gchar *path, const gchar *interface)
+{
+       DBG("+");
+
+       GDBusProxy *proxy;
+       GError *err = NULL;
+
+       if (gdbus_conn == NULL)
+               gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+
+       if (!gdbus_conn) {
+               if (err) {
+                       ERR("Unable to connect to gdbus: %s", err->message);
+                       g_clear_error(&err);
+               }
+               return NULL;
+       }
+
+       proxy =  g_dbus_proxy_new_sync(gdbus_conn,
+                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       service, path,
+                       interface, NULL, &err);
+
+       if (!proxy) {
+               if (err) {
+                       ERR("Unable to create proxy: %s", err->message);
+                        g_clear_error(&err);
+               }
+               return NULL;
+       }
+
+       DBG("-");
+       return proxy;
+}
+
+static GDBusProxy *__bt_hf_gdbus_get_service_proxy(const gchar *service,
+                               const gchar *path, const gchar *interface)
+{
+       return (service_gproxy) ? service_gproxy :
+                       __bt_hf_gdbus_init_service_proxy(service,
+                                       path, interface);
+}
+
+
+static int __bt_hf_agent_gdbus_method_send(const char *service,
+                               GVariant *path, const char *interface,
+                               const char *method)
+{
+       DBG("+");
+
+       GVariant *ret;
+       GDBusProxy *proxy;
+       GError *error = NULL;
+
+       proxy = __bt_hf_gdbus_get_service_proxy(service, g_obj_path, interface);
+       if (!proxy)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       ret = g_dbus_proxy_call_sync(proxy,
+                               method, path,
+                               G_DBUS_CALL_FLAGS_NONE, -1,
+                               NULL, &error);
+       if (ret == NULL) {
+               /* dBUS-RPC is failed */
+               ERR("dBUS-RPC is failed");
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                              error->code, error->message);
+
+                       g_clear_error(&error);
+               }
+               return BT_HF_AGENT_ERROR_INTERNAL;
+       }
+
+       g_variant_unref(ret);
+
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+/*
+Below methods exposed to Applicatoins
+*/
+static gboolean __bt_hf_agent_emit_signal(GDBusConnection *connection,
+                               const char *path, const char *interface,
+                               const char *signal_name, GVariant *param)
+{
+       DBG("+");
+
+       GError *error = NULL;
+       gboolean ret;
+       ret =  g_dbus_connection_emit_signal(connection,
+                                NULL, path,
+                                interface, signal_name,
+                                param, &error);
+       if (!ret) {
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                              error->code, error->message);
+                       g_clear_error(&error);
+               }
+       }
+       DBG("signal_name = [%s]", signal_name);
+       DBG("-");
+       return ret;
+}
+
+static gboolean __bt_hf_agent_emit_property_changed(
+                               GDBusConnection *connection,
+                               const char *path,
+                               const char *interface,
+                               const char *name,
+                               GVariant *property)
+{
+       DBG("+");
+
+       GError *error = NULL;
+       gboolean ret;
+       ret =  g_dbus_connection_emit_signal(connection,
+                               NULL, path, interface,
+                               "PropertyChanged",
+                               g_variant_new("s(v)", name, property),
+                               &error);
+       if (!ret) {
+               if (error != NULL) {
+                       /* dBUS gives error cause */
+                       ERR("D-Bus API failure: errCode[%x], message[%s]",
+                              error->code, error->message);
+                       g_clear_error(&error);
+               }
+       }
+       DBG("-");
+       return ret;
+}
+
+/*
+Below methods exposed to Bluez
+*/
+
+static void __bt_hf_agent_handle_ind_change(bt_hf_agent_info_t *bt_hf_info,
+                                                       guint index, gint value)
+{
+       gchar *name;
+       struct indicator *ind = g_slist_nth_data(bt_hf_info->indies, index - 1);
+       if (ind == NULL) {
+               ERR("Indicator is NULL");
+               return;
+       }
+
+       name = ind->descr;
+       ind->value = value;
+
+       DBG("__bt_hf_agent_process_ind_change, name is %s, value = [%d]",
+                                                               name, value);
+       if (!strcmp(name, "\"call\"")) {
+               bt_hf_info->ciev_call_status = value;
+               if (value > 0) {
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallStarted", NULL);
+                       bt_hf_info->is_dialing = FALSE;
+                       bt_hf_info->call_active = TRUE;
+               } else if (bt_hf_info->call_active) {
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallEnded", NULL);
+                       bt_hf_info->call_active = FALSE;
+               }
+
+       } else if (!strcmp(name, "\"callsetup\"")) {
+               bt_hf_info->ciev_call_setup_status = value;
+               if (value == 0 && bt_hf_info->is_dialing) {
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallTerminated",
+                                       NULL);
+                       bt_hf_info->is_dialing = FALSE;
+               } else if (!bt_hf_info->is_dialing && value > 0)
+                       bt_hf_info->is_dialing = TRUE;
+
+       } else if (!strcmp(name, "\"callheld\"")) {
+               if (value == 0) { /* No calls held*/
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "NoCallsHeld",
+                                       NULL);
+               } else if (value == 1) {
+                       /*Call is placed on hold or active/held calls swapped */
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallsSwapped", NULL);
+                       bt_hf_info->is_dialing = FALSE;
+               } else {
+                       /*Call on hold, no active call*/
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallOnHold", NULL);
+                       bt_hf_info->is_dialing = FALSE;
+               }
+       } else if (!strcmp(name, "\"service\""))
+               __bt_hf_agent_emit_property_changed(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "RegistrationStatus",
+                               g_variant_new("(q)", value));
+       else if (!strcmp(name, "\"signal\""))
+               __bt_hf_agent_emit_property_changed(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "SignalStrength",
+                               g_variant_new("(q)", value));
+       else if (!strcmp(name, "\"roam\""))
+               __bt_hf_agent_emit_property_changed(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "RoamingStatus",
+                               g_variant_new("(q)", value));
+       else if (!strcmp(name, "\"battchg\""))
+               __bt_hf_agent_emit_property_changed(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "BatteryCharge",
+                               g_variant_new("(q)", value));
+}
+
+
+static gboolean  __bt_hf_agent_launch_call_app(const char *launch_type,
+                                                       const char *number)
+{
+       bundle *b;
+       bool is_running;
+
+       DBG("+");
+       app_manager_is_running(CALL_APP_ID, &is_running);
+       if (is_running)
+               return FALSE;
+
+       DBG_SECURE("Launch type = %s, number(%s)", launch_type, number);
+
+       b = bundle_create();
+       if (NULL == b) {
+               DBG("bundle_create() Failed");
+               return FALSE;
+       }
+
+       bundle_add(b, "launch-type", launch_type);
+
+       if (strlen(number) != 0)
+               bundle_add(b, "number", number);
+
+       aul_launch_app(CALL_APP_ID, b);
+       bundle_free(b);
+
+       DBG("-");
+
+       return TRUE;
+}
+
+static void __bt_hf_agent_handle_voice_activation(gint value)
+{
+       __bt_hf_agent_emit_signal(gdbus_conn, BT_HF_AGENT_OBJECT_PATH,
+               BT_HF_SERVICE_INTERFACE,
+               "VoiceRecognition",
+               g_variant_new("(i)", value));
+
+       return;
+}
+
+static void __bt_hf_agent_handle_speaker_gain(gint value)
+{
+       __bt_hf_agent_emit_signal(gdbus_conn, BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "VolumeSpeaker",
+                               g_variant_new("(i)", value));
+
+       return;
+}
+
+static int __bt_hf_agent_handle_ccwa(bt_hf_agent_info_t *bt_hf_info,
+                                                       const gchar *buf)
+{
+       gchar *ccwa;
+       gchar number[BT_HF_CALLER_NUM_SIZE];
+       gchar *sep;
+       char fmt_str[BT_HF_FMT_STR_SIZE];
+       int len = strlen(buf);
+
+       DBG("__bt_hf_agent_handle_ccwa +");
+       if (len > BT_HF_CALLER_NUM_SIZE + 10) {
+               DBG("buf len %d is too long '%s'", len, buf);
+               return 1;
+       }
+
+       if ((ccwa = strstr(buf, "\r\n+CCWA"))) {
+               snprintf(fmt_str, sizeof(fmt_str), "\r\n+CCWA: \"%%%ds", sizeof(number) - 1);
+               if (sscanf(ccwa, fmt_str, number) == 1) {
+                       sep = strchr(number, '"');
+                       sep[0] = '\0';
+
+                       ccwa = number;
+
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE, "CallWaiting",
+                                       g_variant_new("(s)", ccwa));
+               } else {
+                       ERR_SECURE("CCWA '%s' is Call Wating", buf);
+                       return 1;
+               }
+       }
+       DBG("__bt_hf_agent_handle_ccwa -");
+       return 0;
+}
+
+static GSList *__bt_hf_prepare_call_list(const char *buf) {
+       GSList *call_list = NULL;
+       char *str = NULL;
+       char *ptr = NULL;
+       char *temp = NULL;
+       char delim_sep[] = "\r\n";
+       hf_call_list_info_t *call_info;
+
+       DBG("+");
+       str = strtok(buf, delim_sep);
+       while (str != NULL) {
+               if (!(strstr(str, "+CLCC:"))) {
+                       str = strtok(NULL, delim_sep);
+                       continue;
+               }
+
+               call_info = g_new0(hf_call_list_info_t, 1);
+
+               sscanf(str, "+CLCC: %1d,%1d, %1d, %1d, %1d",
+                               &call_info->idx, &call_info->dir,
+                               &call_info->status, &call_info->mode,
+                               &call_info->multi_party);
+               DBG("Index = [%d], Direction = [%d], Status = [%d], Mode = [%d], Multi_party = [%d]\n",
+                               call_info->idx, call_info->dir, call_info->status,
+                               call_info->mode, call_info->multi_party);
+
+               ptr = strstr(str, "\"");
+               if (ptr) {
+                       temp = strstr(ptr + 1, "\"");
+                       if (temp) {
+                               *temp = '\0';
+                               DBG_SECURE("\tPhone Number = [%s]\n", ptr + 1);
+                               call_info->number = g_strdup(ptr + 1);
+
+                               if (strstr(temp + 1, ",")) {
+                                       temp += 2;
+                                       DBG("\tType = [%s]\n", temp);
+                                       call_info->type = atoi(temp);
+                               }
+                       }
+               } else {
+                       /*In case of no phone no. in CLCC respnse, we should launch call application
+                        * with NULL string. By doing so "unknown" shall be displayed*/
+                       DBG("Phone number does not exist\n");
+                       call_info->number = g_strdup("");
+               }
+
+               call_list = g_slist_append(call_list, call_info);
+               str = strtok(NULL, delim_sep);
+       }
+       DBG("-");
+       return call_list;
+}
+
+static GSList *__bt_hf_get_call_list(bt_hf_agent_info_t *bt_hf_info)
+{
+       char buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       GSList *call_list = NULL;
+
+       DBG("+");
+
+       /* Send CLCC when the callsetup */
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CALLLIST, buf,
+                       sizeof(BT_HF_CALLLIST) - 1);
+       DBG_SECURE("Receive CLCC response buffer = '%s'", buf);
+
+       call_list =  __bt_hf_prepare_call_list(buf);
+       DBG("-");
+       return call_list;
+}
+
+static void __bt_hf_call_info_free(void *data)
+{
+       DBG("+");
+
+       hf_call_list_info_t *call_info = data;
+       g_free(call_info->number);
+       g_free(call_info);
+
+       DBG("-");
+}
+
+static void __bt_hf_free_call_list(GSList *call_list)
+{
+       DBG("+");
+
+       g_slist_free_full(call_list, __bt_hf_call_info_free);
+
+       DBG("-");
+}
+
+static void __bt_hf_launch_call_using_call_list(GSList *call_list,
+                                       bt_hf_agent_info_t *bt_hf_info)
+{
+       guint len;
+       const char *launch_type_str;
+       hf_call_list_info_t *call_info;
+
+       DBG("+");
+       if (call_list == NULL)
+               return;
+
+       len = g_slist_length(call_list);
+
+       while (len--) {
+               call_info = g_slist_nth_data(call_list, len);
+
+               /* Launch based on below conditions
+                 * DC - Active call which is initiated from H
+                 * MR - Alerting call which is initiated from H
+                 * MT - Incoming call */
+               if (call_info->status == BT_HF_CALL_STAT_ACTIVE) {
+                       launch_type_str =  "DC";
+               } else {
+                       if (call_info->dir == BT_HF_CALL_DIR_INCOMING)
+                               launch_type_str =  "MT";
+                       else
+                               launch_type_str =  "MR";
+               }
+
+               if (__bt_hf_agent_launch_call_app(launch_type_str,
+                                       call_info->number)  == FALSE)
+                       DBG("call app launching failed");
+       }
+       DBG("-");
+}
+
+static GVariant *__bt_hf_agent_get_call_status_info(GSList *call_list)
+{
+       DBG("+");
+
+       int32_t call_count;
+       gchar *caller;
+       hf_call_list_info_t *call_info;
+
+       GVariantBuilder *builder;
+       GVariant *var_data;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(siiii)"));
+
+       call_count = g_slist_length(call_list);
+       DBG("Total call count = '%d'", call_count);
+
+       while (call_count--) {
+               call_info = g_slist_nth_data(call_list, call_count);
+               DBG_SECURE("Idx=%d, Dir=%d, status=%d, mode=%d, mparty=%d, number=[%s]\n",
+               call_info->idx, call_info->dir, call_info->status,
+               call_info->mode, call_info->multi_party, call_info->number);
+               caller = call_info->number;
+
+               g_variant_builder_add(builder, "(siiii)",
+                               caller, call_info->dir, call_info->status,
+                               call_info->multi_party, call_info->idx);
+       }
+       var_data = g_variant_new("(ia(siiii))",
+                               g_slist_length(call_list), builder);
+
+       g_variant_builder_unref(builder);
+       DBG("-");
+       return  var_data;
+}
+
+static void __bt_hf_clear_prev_sent_cmd(void)
+{
+       if (prev_cmd[0] != 0)
+               ERR("No sent command");
+
+       memset(prev_cmd, 0, BT_HF_CMD_BUF_SIZE);
+
+       return;
+}
+
+static void __bt_hf_agent_send_call_status_info(GSList *call_list)
+{
+       GVariant *var_data;
+
+       var_data = __bt_hf_agent_get_call_status_info(call_list);
+
+       if (gdbus_conn)
+               __bt_hf_agent_emit_signal(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "CallStatusUpdate",
+                               var_data);
+}
+
+static void __bt_hf_agent_handle_call_list(bt_hf_agent_info_t *bt_hf_info)
+{
+       int ret;
+       char buf[BT_HF_DATA_BUF_SIZE] = {0,};
+
+       DBG("Try Lock");
+       ret = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+       if (ret >= 0)
+               DBG("Lock PM state as current state!");
+       else
+               DBG("deviced error!");
+
+       /* Send CLCC. The response will be handled in the handler */
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CALLLIST, buf,
+                       sizeof(BT_HF_CALLLIST) - 1);
+
+       DBG("Try Unlock");
+       ret = display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
+       if (ret >= 0)
+               DBG("UnLock PM state");
+       else
+               DBG("deviced error!");
+}
+
+static void __bt_hf_agent_request_call_list_info(bt_hf_agent_info_t *bt_hf_info,
+                                                               guint index)
+{
+       char *name;
+       int ret;
+       struct indicator *ind = g_slist_nth_data(bt_hf_info->indies, index - 1);
+       if (ind == NULL) {
+               ERR("Indicator is NULL");
+               return;
+       }
+       name = ind->descr;
+       DBG("name : %s", name);
+
+       if ((strcmp(name, "\"callsetup\"") != 0) &&
+                       (strcmp(name, "\"call\"") != 0) &&
+                               (strcmp(name, "\"callheld\"") != 0))
+               return;
+
+       DBG("Try Lock!!");
+       ret = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+       if (ret >= 0)
+               DBG("Lock PM state as current state!!");
+       else
+               DBG("deviced error!!");
+
+       __bt_hf_agent_handle_call_list(bt_hf_info);
+
+       DBG("Try Unlock!!");
+       ret = display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
+       if (ret >= 0)
+               DBG("UnLock PM state!!");
+       else
+               DBG("deviced error!!");
+
+}
+
+static gboolean __bt_hf_send_available_codec(bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE];
+       gchar cmd_buf[BT_HF_CMD_BUF_SIZE] = {0};
+       gboolean ret;
+
+       snprintf(cmd_buf, sizeof(cmd_buf), BT_HF_AVAILABLE_CODEC,
+                       BT_HF_CODEC_ID_CVSD, BT_HF_CODEC_ID_MSBC);
+       ret = __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf,
+                               strlen(cmd_buf));
+       if (!ret || !strstr(buf, "OK"))
+               return FALSE;
+
+       return TRUE;
+}
+
+static  int _hf_agent_codec_setup(guint codec_id)
+{
+       int ret;
+
+       if (!g_obj_path) {
+               DBG("g_obj_path is NULL\n");
+               return BT_HF_AGENT_ERROR_INTERNAL;
+       }
+
+       switch (codec_id) {
+       case BT_HF_CODEC_ID_CVSD:
+               ret = __bt_hf_agent_gdbus_method_send(BLUEZ_SERVICE_NAME,
+                                               NULL,
+                                               BLUEZ_HF_INTERFACE_NAME,
+                                               "SetNbParameters");
+               break;
+       case BT_HF_CODEC_ID_MSBC:
+               ret = __bt_hf_agent_gdbus_method_send(BLUEZ_SERVICE_NAME,
+                                               NULL,
+                                               BLUEZ_HF_INTERFACE_NAME,
+                                               "SetWbsParameters");
+               break;
+       default:
+               ret = BT_HF_AGENT_ERROR_INTERNAL;
+               DBG("Invalid Codec\n");
+               break;
+       }
+
+       if (ret)
+               DBG("Failed to setup the Codec\n");
+       else
+               current_codec_id = codec_id;
+
+       return ret;
+}
+
+static void __bt_hf_agent_handle_codec_select(bt_hf_agent_info_t *bt_hf_info,
+                                                       guint codec_id)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE];
+       gchar cmd_buf[BT_HF_CMD_BUF_SIZE] = {0};
+       gboolean ret;
+
+       if (codec_id != BT_HF_CODEC_ID_CVSD && codec_id != BT_HF_CODEC_ID_MSBC) {
+               DBG("Codec id doesn't match, so send available codec again");
+               ret = __bt_hf_send_available_codec(bt_hf_info);
+               if (!ret)
+                       DBG("Failed to send avalable codec");
+               return;
+       }
+
+       /* HF should be ready accpet SCO connection before sending theresponse for
+       "\r\n+BCS=>Codec ID\r\n", Keep the BT chip ready to recevie encoded SCO data */
+       ret = _hf_agent_codec_setup(codec_id);
+
+       snprintf(cmd_buf, sizeof(cmd_buf), BT_HF_CODEC_SELECT, codec_id);
+       ret = __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf,
+                               strlen(cmd_buf));
+       if (!ret || !strstr(buf, "OK")) {
+               DBG("Failed to select the Codec\n");
+       } else {
+               /* Inform other modules (Ex:MM) about the selected codec */
+               __bt_hf_agent_emit_signal(gdbus_conn, BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE, "SelectedCodec",
+                               g_variant_new("(u)", codec_id));
+       }
+
+}
+
+void __bt_hf_agent_print_at_buffer(const char *buf)
+{
+
+       int i = 0;
+       char s[1024] = {0, };
+       strncpy(s, buf, BT_HF_DATA_BUF_SIZE - 1);
+       while (s[i] != '\0') {
+               if (s[i] == '\r' || s[i] == '\n')
+                       s[i] = '.';
+
+               i++;
+       }
+       DBG_SECURE("Received AT Buffer, length = %d Buffer = >>>>> %s\n", strlen(s), s);
+}
+
+static int __bt_hf_agent_handler_ciev(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       gchar indicator[BT_HF_INDICATOR_DESCR_SIZE + 4];
+       gchar *sep;
+       gint value;
+       guint index;
+       char fmt_str[BT_HF_FMT_STR_SIZE];
+
+       DBG("++++++++ __bt_hf_agent_handler_ciev +++++++++");
+
+       snprintf(fmt_str, sizeof(fmt_str), "\r\n+CIEV:%%%ds\r\n", sizeof(indicator) - 1);
+       if (sscanf(buf, fmt_str, indicator) == 1) {
+               sep = strchr(indicator, ',');
+               sep[0] = '\0';
+               sep += 1;
+               index = atoi(indicator);
+               value = atoi(sep);
+               __bt_hf_agent_handle_ind_change(bt_hf_info, index, value);
+
+               if (bt_hf_info->ciev_call_status == 0 &&
+                               bt_hf_info->ciev_call_setup_status == 0)
+                       DBG("No active call");
+               else
+                       /* Request CLCC based on indicator change for call/callsetup/callHeld */
+                       __bt_hf_agent_request_call_list_info(bt_hf_info, index);
+       }
+       DBG("--------- __bt_hf_agent_handler_ciev ------------");
+       return 0;
+}
+
+static void __bt_hf_agent_handle_ven_samsung(bt_hf_agent_info_t *bt_hf_info,
+                                               gint app_id, const char *msg)
+{
+       /* Whomesoever wants need to handle it */
+       char *sig_name = "SamsungXSAT";
+       __bt_hf_agent_emit_signal(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               sig_name,
+                               g_variant_new("(is)", app_id, msg));
+}
+
+static int __bt_hf_agent_handler_ring(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("++++++++ __bt_hf_agent_handler_ring ++++++++");
+       DBG("---------__bt_hf_agent_handler_ring --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_clip(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_clip ++++++++");
+       DBG("---------__bt_hf_agent_handler_clip --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_bvra(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_bvra +++++++++");
+       gint value;
+        if (sscanf(buf, "\r\n+BVRA:%1d\r\n", &value) == 1)
+               __bt_hf_agent_handle_voice_activation(value);
+
+        DBG("---------__bt_hf_agent_handler_bvra --------");
+       return 0;
+}
+
+static int __bt_hf_agent_handler_bcs(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       guint codec_id;
+       DBG("+++++++++ __bt_hf_agent_handler_bcs +++++++++-");
+       if (sscanf(buf, "\r\n+BCS:%3d\r\n", &codec_id))
+               __bt_hf_agent_handle_codec_select(bt_hf_info, codec_id);
+
+       DBG("---------__bt_hf_agent_handler_bcs --------");
+       return 0;
+}
+
+static int __bt_hf_agent_handler_vgs(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       gint value;
+       DBG("+++++++++ __bt_hf_agent_handler_vgs +++++++++");
+       if (sscanf(buf, "\r\n+VGS:%2d\r\n", &value))
+               __bt_hf_agent_handle_speaker_gain(value);
+
+       DBG("---------__bt_hf_agent_handler_vgs --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_ccwa(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_ccwa ++++++++");
+               __bt_hf_agent_handle_ccwa(bt_hf_info, buf);
+       DBG("---------__bt_hf_agent_handler_ccwa --------");
+
+       return 0;
+}
+
+
+static int __bt_hf_agent_handler_xsat(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       gint app_id;
+       char msg[BT_HF_DATA_BUF_SIZE];
+       char fmt_str[BT_HF_CMD_BUF_SIZE];
+
+       DBG("+++++++++ __bt_hf_agent_handler_xsat +++++++++");
+
+       snprintf(fmt_str, sizeof(fmt_str), "\r\n+XSAT:%%d,%%%ds\r\n", sizeof(msg) - 1);
+       if (sscanf(buf, fmt_str, &app_id, msg))
+               __bt_hf_agent_handle_ven_samsung(bt_hf_info, app_id, msg);
+
+       DBG("---------__bt_hf_agent_handler_xsat --------");
+
+       return 0;
+}
+
+static int __bt_hf_agent_handler_cme_error(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_cme_error ++++++++");
+
+       if (strstr(prev_cmd, "ATD")) {
+               __bt_hf_agent_emit_signal(gdbus_conn,
+                                       BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallTerminated",
+                                       NULL);
+       }
+
+       __bt_hf_clear_prev_sent_cmd();
+
+       DBG("---------__bt_hf_agent_handler_cme_error --------");
+       return 0;
+}
+
+static int __bt_hf_agent_handler_response_ok(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_response_ok ++++++++");
+       __bt_hf_clear_prev_sent_cmd();
+       return 0;
+}
+
+static int __bt_hf_agent_handler_response_err(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       DBG("+++++++++ __bt_hf_agent_handler_response_err ++++++++");
+
+       if (strstr(prev_cmd, "ATD")) {
+               __bt_hf_agent_emit_signal(gdbus_conn, BT_HF_AGENT_OBJECT_PATH,
+                                       BT_HF_SERVICE_INTERFACE,
+                                       "CallTerminated",
+                                       NULL);
+       }
+       __bt_hf_clear_prev_sent_cmd();
+       return 0;
+}
+
+static int __bt_hf_agent_handler_response_serr(bt_hf_agent_info_t *bt_hf_info,
+                                                       const char *buf)
+{
+       __bt_hf_clear_prev_sent_cmd();
+       return 0;
+}
+
+static int __bt_hf_agent_handler_clcc(bt_hf_agent_info_t *bt_hf_info, const char *buffer)
+{
+
+       GSList *call_list = NULL;
+       int ret;
+       DBG("+++++++++ __bt_hf_agent_handler_clcc ++++++++");
+       DBG_SECURE("Receive CLCC response buffer = '%s'", buffer);
+
+       DBG("Try Lock");
+       ret = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+       if (ret >= 0)
+               DBG("Lock PM state as current state!");
+       else
+               DBG("deviced error!");
+
+       call_list = __bt_hf_prepare_call_list(buffer);
+
+       if (call_list == NULL)
+               goto done;
+
+       __bt_hf_launch_call_using_call_list(call_list, bt_hf_info);
+
+       __bt_hf_agent_send_call_status_info(call_list);
+
+       __bt_hf_free_call_list(call_list);
+
+done:
+       DBG("Try Unlock");
+       ret = display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
+       if (ret >= 0)
+               DBG("UnLock PM state");
+       else
+               DBG("deviced error!");
+       DBG("---------__bt_hf_agent_handler_clcc --------");
+       return 0;
+}
+
+static struct hf_event hf_event_callbacks[] = {
+       { "\r\n+CIEV:", __bt_hf_agent_handler_ciev },
+       { "\r\nRING", __bt_hf_agent_handler_ring },
+       { "\r\n+CLIP:", __bt_hf_agent_handler_clip },
+       { "\r\n+BVRA:", __bt_hf_agent_handler_bvra },
+       { "\r\n+BCS:", __bt_hf_agent_handler_bcs },
+       { "\r\n+VGS:", __bt_hf_agent_handler_vgs },
+       { "\r\n+CCWA:", __bt_hf_agent_handler_ccwa },
+       { "\r\n+XSAT:", __bt_hf_agent_handler_xsat },
+       {"\r\n+CLCC:", __bt_hf_agent_handler_clcc },
+       { 0 }
+};
+
+static struct hf_event hf_event_resp_callbacks[] = {
+       { "\r\n+CME ERROR:", __bt_hf_agent_handler_cme_error },
+       { "\r\nOK\r\n", __bt_hf_agent_handler_response_ok },
+       { "ERROR", __bt_hf_agent_handler_response_err },
+       { "SERR", __bt_hf_agent_handler_response_serr },
+       { 0 }
+};
+
+static int hf_handle_rx_at_cmd(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       struct hf_event *ev;
+
+       INFO_SECURE("[HF AT CMD][RCVD] [%s]", buf);
+       for (ev = hf_event_callbacks; ev->cmd; ev++) {
+               if (!strncmp(buf, ev->cmd, strlen(ev->cmd)))
+                       return ev->callback(bt_hf_info, buf);
+       }
+
+       for (ev = hf_event_resp_callbacks; ev->cmd; ev++) {
+               if (strstr(buf, ev->cmd))
+                       return ev->callback(bt_hf_info, buf);
+       }
+
+       DBG("Unhandled AT command.");
+
+       return -EINVAL;
+}
+
+static int hf_handle_append_clcc_buff(char *cmd_buf, const char *buf)
+{
+       int buf_length;
+       int cmd_length =  0;
+       int cmd_buf_len = 0;
+       char *pos_start, *pos_end;
+       const char *datap = buf;
+
+       cmd_buf_len = strlen(cmd_buf);
+       buf_length = strlen(buf);
+       DBG("buf_length = %d, cmd_buf_len = %d", buf_length, cmd_buf_len);
+
+       if (buf_length > 0 && strstr(datap, "+CLCC")) {
+
+               pos_start = strstr(datap, "\r\n");
+               if (pos_start == NULL) {
+                       DBG("Invalid AT command signature..\n");
+                       return 0;
+               }
+
+               pos_end = g_strrstr(datap, "+CLCC");
+               pos_end =  strstr(pos_end, "\r\n");
+               cmd_length =   (pos_end - pos_start) + 2;
+               DBG("CLCC balance Cmd Length = %d\n", cmd_length);
+               memcpy(cmd_buf + cmd_buf_len, pos_start, cmd_length);
+               cmd_buf[cmd_buf_len + cmd_length] = '\0';
+       }
+       return cmd_length;
+}
+
+
+static int hf_handle_rx_at_buff(bt_hf_agent_info_t *bt_hf_info, const char *buf)
+{
+       int buf_length;
+       int cmd_length;
+       char *pos_start, *pos_end;
+       int tmp;
+       gchar cmd_buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       const char *datap = buf;
+
+       __bt_hf_agent_print_at_buffer(buf);
+
+       buf_length = strlen(buf);
+
+       while (buf_length > 0) {
+               pos_start = strstr(datap, "\r\n");
+               if (pos_start == NULL) {
+                       DBG("Invalid AT command start signature..\n");
+                       break;
+               }
+
+               datap += 2;
+               pos_end = strstr(datap, "\r\n");
+               if (pos_end == NULL) {
+                       DBG("Invalid AT command end signature..\n");
+                       break;
+               }
+               cmd_length =   (pos_end - pos_start) + 2;
+               DBG("Cmd Length = %d\n", cmd_length);
+
+               memcpy(cmd_buf, pos_start, cmd_length);
+               cmd_buf[cmd_length] = '\0';
+
+               buf_length = buf_length - cmd_length;
+               datap = datap + cmd_length - 2;
+
+               /* We need to pass all the CLCC's together to its handler */
+               if (strstr(cmd_buf, "+CLCC")) {
+                       tmp = hf_handle_append_clcc_buff(cmd_buf, datap);
+                       datap += tmp;
+                       buf_length = buf_length - tmp;
+               }
+               hf_handle_rx_at_cmd(bt_hf_info, cmd_buf);
+               DBG("Pending buf_length = %d\n", buf_length);
+       }
+       return TRUE;
+
+}
+static gboolean __bt_hf_agent_data_cb(GIOChannel *chan, GIOCondition cond,
+                                       bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       gsize read;
+       GError *gerr = NULL;
+
+       if (cond & (G_IO_ERR | G_IO_HUP)) {
+               ERR("HF connection terminated...! cond = %d\n", cond);
+               is_hf_connected = FALSE;
+#ifdef FEATURE_TIZENW
+               __bt_start_adv();
+#endif
+               __bt_hf_agent_release();
+               return FALSE;
+       }
+
+       if (g_io_channel_read_chars(chan, buf, sizeof(buf) - 1, &read, &gerr)
+                       != G_IO_STATUS_NORMAL) {
+               if (gerr) {
+                       ERR("Read failed, cond = [%d], Err msg = [%s]",
+                                                       cond, gerr->message);
+                       g_error_free(gerr);
+               }
+               return TRUE;
+       }
+       buf[read] = '\0';
+       DBG("***  Received AT buffer packet ****");
+       hf_handle_rx_at_buff(bt_hf_info, buf);
+
+       return TRUE;
+}
+
+static void __bt_hf_agent_start_watch(bt_hf_agent_info_t *bt_hf_info)
+{
+       bt_hf_info->watch_id = g_io_add_watch(bt_hf_info->io_chan,
+                       G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+                       (GIOFunc) __bt_hf_agent_data_cb, bt_hf_info);
+}
+
+static void __bt_hf_agent_stop_watch(bt_hf_agent_info_t *bt_hf_info)
+{
+       g_source_remove(bt_hf_info->watch_id);
+}
+
+static gboolean __bt_hf_channel_write(GIOChannel *io, gchar *data,
+                                       gsize count)
+{
+       gsize written = 0;
+       GIOStatus status;
+
+       while (count > 0) {
+               status = g_io_channel_write_chars(io, data, count, &written,
+                                               NULL);
+               if (status != G_IO_STATUS_NORMAL)
+                       return FALSE;
+
+               data += written;
+               count -= written;
+       }
+       return TRUE;
+}
+
+static gboolean __bt_hf_send_only(bt_hf_agent_info_t *bt_hf_info, gchar *data,
+                                                               gsize count)
+{
+       GIOChannel *io_chan = bt_hf_info->io_chan;
+
+       if (!__bt_hf_channel_write(io_chan, data, count))
+               return FALSE;
+
+       g_io_channel_flush(io_chan, NULL);
+
+       DBG("Send only buffer size =[%d] - Send <<<<<| %s", count, data);
+
+       return TRUE;
+}
+
+static gboolean __bt_hf_send_and_read(bt_hf_agent_info_t *bt_hf_info,
+               gchar *data, gchar *response, gsize count)
+{
+       GIOChannel *io_chan = bt_hf_info->io_chan;
+       gsize rd_size = 0;
+       gboolean recvd_ok = FALSE;
+       gboolean recvd_error = FALSE;
+       gboolean recvd_sec_error = FALSE;
+       gchar *resp_buf = response;
+       gsize toread = BT_HF_DATA_BUF_SIZE - 1;
+       int i = 0;
+       int fd;
+       int err;
+       struct pollfd p;
+
+       /* Should not send cmds if DUT send a command and wait the response */
+       if (prev_cmd[0] != 0) {
+               DBG("DUT is waiting a respond for previous TX cmd. Skip sennding.");
+               return FALSE;
+       }
+
+       memset(resp_buf, 0, BT_HF_DATA_BUF_SIZE);
+
+       if (!__bt_hf_channel_write(io_chan, data, count))
+               return FALSE;
+
+       g_io_channel_flush(io_chan, NULL);
+
+       INFO_SECURE("[HF AT CMD][SENT] %s", data);
+       DBG("Send buffer size =[%d] - Send <<<<< %s", count, data);
+
+       fd = g_io_channel_unix_get_fd(io_chan);
+       p.fd = fd;
+       p.events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
+
+       /* Maximun 8 seconds of poll or 8 minus no of cmd received */
+       for (i = 1; i <= MAX_WAITING_DELAY; i++) {
+               DBG("Loop Counter = %d", i);
+               p.revents = 0;
+               err = poll(&p, 1, 1000);
+               if (err < 0) {
+                       DBG("Loop Counter = %d, >>>> Poll error happen", i);
+                       return FALSE;
+               } else if (err == 0) {
+                       DBG("Loop Counter = %d, >>>> Poll Timeout", i);
+               }
+
+               if (p.revents & (POLLERR | POLLHUP | POLLNVAL)) {
+                       DBG("Loop Counter = %d, >> Poll ERR/HUP/INV (%d)",
+                                                               i, p.revents);
+
+                       __bt_hf_agent_emit_signal(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "Disconnected",
+                               g_variant_new("(s)",
+                                               bt_hf_info->remote_addr));
+
+                       bt_hf_info->state = BT_HF_STATE_DISCONNECTED;
+                       return FALSE;
+               }
+
+               if (p.revents & POLLIN) {
+                       rd_size = read(fd, resp_buf, toread);
+                       resp_buf[rd_size] = '\0';
+                       INFO_SECURE("[HF AT CMD][RCVD] (send&read) [%s]", resp_buf);
+                       recvd_ok = NULL != strstr(resp_buf, BT_HF_OK_RESPONSE);
+                       recvd_error = NULL != strstr(resp_buf, BT_HF_ERROR_RESPONSE);
+                       recvd_sec_error = NULL != strstr(resp_buf, BT_HF_SEC_ERROR_RESPONSE);
+
+                       resp_buf += rd_size;
+                       toread -= rd_size;
+
+                       if (recvd_ok || recvd_error || recvd_sec_error) {
+                               DBG("Break Loop Counter = %d", i);
+                               break;
+                       }
+               }
+       }
+
+       /* Once service level connection is established we need to handle
+        * all the intermediate AT commands */
+       if (bt_hf_info->state == BT_HF_STATE_CONNECTED)
+               hf_handle_rx_at_buff(bt_hf_info, response);
+       return TRUE;
+}
+
+static GSList *__bt_hf_parse_indicator_names(gchar *names, GSList *indies)
+{
+       gchar *current = names - 1;
+       GSList *result = indies;
+       gchar *next;
+       struct indicator *ind;
+       DBG("Indicator buffer = %s", names);
+       while (current != NULL) {
+               current += 2;
+               next = strstr(current, ",(");
+               ind = g_slice_new(struct indicator);
+               g_strlcpy(ind->descr, current, BT_HF_INDICATOR_DESCR_SIZE);
+               ind->descr[(intptr_t) next - (intptr_t) current] = '\0';
+               result = g_slist_append(result, (gpointer) ind);
+               current = strstr(next + 1, ",(");
+       }
+       return result;
+}
+
+/* get values from <val0>,<val1>,... */
+static GSList *__bt_hf_parse_indicator_values(gchar *values, GSList *indies)
+{
+       gint val;
+       gchar *current = values - 1;
+       GSList *runner = indies;
+       struct indicator *ind;
+       DBG("Indicator string = %s", values);
+       while (current != NULL) {
+               current += 1;
+               sscanf(current, "%1d", &val);
+               current = strchr(current, ',');
+               ind = g_slist_nth_data(runner, 0);
+               ind->value = val;
+               runner = g_slist_next(runner);
+       }
+       return indies;
+}
+
+static guint __bt_hf_get_hold_mpty_features(gchar *features)
+{
+       guint result = 0;
+
+       if (strstr(features, "0"))
+               result |= BT_HF_CHLD_0;
+
+       if (strstr(features, "1"))
+               result |= BT_HF_CHLD_1;
+
+       if (strstr(features, "1x"))
+               result |= BT_HF_CHLD_1x;
+
+       if (strstr(features, "2"))
+               result |= BT_HF_CHLD_2;
+
+       if (strstr(features, "2x"))
+               result |= BT_HF_CHLD_2x;
+
+       if (strstr(features, "3"))
+               result |= BT_HF_CHLD_3;
+
+       if (strstr(features, "4"))
+               result |= BT_HF_CHLD_4;
+
+       return result;
+}
+
+static gboolean __bt_hf_agent_sco_conn_cb(GIOChannel *chan, GIOCondition cond, gpointer user_data)
+{
+       bt_hf_agent_info_t *bt_hf_info = user_data;
+
+       DBG("");
+       if (cond & G_IO_NVAL)
+               return FALSE;
+
+       if (cond & (G_IO_HUP | G_IO_ERR)) {
+               g_io_channel_shutdown(chan, TRUE, NULL);
+               close(bt_hf_info->cli_sco_fd);
+
+               DBG("Emit AudioDisconnected Signal");
+
+               sco_audio_connected = BT_HF_AUDIO_DISCONNECTED;
+
+               __bt_hf_agent_emit_signal(gdbus_conn,
+                               BT_HF_AGENT_OBJECT_PATH,
+                               BT_HF_SERVICE_INTERFACE,
+                               "AudioDisconnected", NULL);
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_agent_query_and_update_call_list(gpointer data)
+{
+       DBG("+");
+       bt_hf_agent_info_t *bt_hf_info = data;
+
+       if (bt_hf_info->cli_sco_fd >= 0)
+               __bt_hf_agent_handle_call_list(bt_hf_info);
+       else
+               DBG("SCO Audio is already disconnected");
+
+       DBG("-");
+
+       return FALSE;
+}
+
+static gboolean __bt_hf_agent_sco_accept_cb(GIOChannel *chan, GIOCondition cond, gpointer user_data)
+{
+       bt_hf_agent_info_t *bt_hf_info = user_data;
+       int sco_skt;
+       int cli_sco_sock;
+       GIOChannel *sco_io;
+
+       DBG("");
+
+       if (cond & G_IO_NVAL)
+               return FALSE;
+
+       sco_skt = g_io_channel_unix_get_fd(chan);
+
+       if (cond & (G_IO_HUP | G_IO_ERR)) {
+               close(sco_skt);
+               return FALSE;
+       }
+
+       cli_sco_sock = accept(sco_skt, NULL, NULL);
+       if (cli_sco_sock < 0)
+               return FALSE;
+
+       bt_hf_info->cli_sco_fd = cli_sco_sock;
+
+       sco_io = g_io_channel_unix_new(cli_sco_sock);
+       g_io_channel_set_close_on_unref(sco_io, TRUE);
+       g_io_channel_set_encoding(sco_io, NULL, NULL);
+       g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_buffered(sco_io, FALSE);
+
+       g_io_add_watch(sco_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+                                       __bt_hf_agent_sco_conn_cb, bt_hf_info);
+
+       /* S-Voice app requires the AudioConnected signal earlier */
+       DBG("Emit AudioConnected Signal");
+
+       sco_audio_connected = BT_HF_AUDIO_CONNECTED;
+
+       __bt_hf_agent_emit_signal(gdbus_conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "AudioConnected", NULL);
+
+       /* In the case of incoming call, the call app is already launched,
+        * hence AudioConnected signal is enough to update the call status.
+        * In the case of outgoing call we need to lauch the callapp.
+        */
+       if (bt_hf_info->ciev_call_status == 0
+               && bt_hf_info->ciev_call_setup_status == 0)
+               __bt_get_current_indicators(bt_hf_info);
+
+       g_idle_add(__bt_agent_query_and_update_call_list, bt_hf_info);
+
+       return TRUE;
+}
+
+static gboolean __bt_hf_agent_sco_accept(bt_hf_agent_info_t *bt_hf_info)
+{
+       struct sockaddr_sco addr;
+       GIOChannel *sco_io;
+       bdaddr_t bd_addr = {{0},};
+       int sco_skt;
+
+       if (bt_hf_info->state != BT_HF_STATE_CONNECTED)
+               return FALSE;
+
+       /* Create socket */
+       sco_skt = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
+       if (sco_skt < 0) {
+               DBG("Can't create socket:\n");
+               return FALSE;
+       }
+
+       /* Bind to local address */
+       memset(&addr, 0, sizeof(addr));
+       addr.sco_family = AF_BLUETOOTH;
+       memcpy(&addr.sco_bdaddr, &bd_addr, sizeof(bdaddr_t));
+
+       if (bind(sco_skt, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               DBG("Can't bind socket:\n");
+               goto error;
+       }
+
+       if (listen(sco_skt, 1)) {
+               DBG("Can not listen on the socket:\n");
+               goto error;
+       }
+
+       sco_io = g_io_channel_unix_new(sco_skt);
+       g_io_channel_set_close_on_unref(sco_io, TRUE);
+       g_io_channel_set_encoding(sco_io, NULL, NULL);
+       g_io_channel_set_flags(sco_io, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_channel_set_buffered(sco_io, FALSE);
+
+       bt_hf_info->sco_fd = sco_skt;
+       bt_hf_info->sco_io_chan = sco_io;
+
+       bt_hf_info->sco_watch_id = g_io_add_watch(sco_io,
+                       G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, __bt_hf_agent_sco_accept_cb, bt_hf_info);
+
+       g_io_channel_unref(sco_io);
+
+       return TRUE;
+
+error:
+       close(sco_skt);
+       return FALSE;
+}
+
+static gboolean __bt_get_supported_indicators(bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       gboolean ret;
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_INDICATORS_SUPP, buf,
+                               sizeof(BT_HF_INDICATORS_SUPP) - 1);
+       if (!ret || !strstr(buf, "+CIND:"))
+               return FALSE;
+
+       bt_hf_info->indies = __bt_hf_parse_indicator_names(strchr(buf, '('), NULL);
+
+       return TRUE;
+}
+
+static gboolean __bt_get_bia_cmd(bt_hf_agent_info_t *bt_hf_info, gchar *cmd, gsize cmd_size)
+{
+       GSList *l;
+       gsize ret;
+
+       if (bt_hf_info == NULL || cmd == NULL) {
+               ERR("Invalid parameter");
+               return FALSE;
+       }
+
+       ret = g_strlcpy(cmd, BT_HF_INDICATORS_ACTIVATION, cmd_size);
+
+       for (l = bt_hf_info->indies; l != NULL; l = g_slist_next(l)) {
+               ret = g_strlcat(cmd, "0,", cmd_size);
+               if (ret >= cmd_size) {
+                       ERR("Too many indices");
+                       return FALSE;
+               }
+
+       }
+
+       cmd[ret - 1] = '\0';
+       DBG("BIA Str : %s", cmd);
+
+       ret = g_strlcat(cmd, "\r", cmd_size);
+       if (ret >= cmd_size) {
+               ERR("Too many indices");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_get_current_indicators(bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE] = {0,};
+       gboolean ret;
+       gchar *str;
+       GSList *l;
+       int index =  1;
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_INDICATORS_VAL, buf,
+               sizeof(BT_HF_INDICATORS_VAL) - 1);
+       if (!ret || !strstr(buf, "+CIND:"))
+               return FALSE;
+
+       /* if buf has other command prefix, skip it */
+       str = strstr(buf, "+CIND");
+       if (str == NULL)
+               return FALSE;
+
+       bt_hf_info->indies = __bt_hf_parse_indicator_values(str + 6, bt_hf_info->indies);
+
+       /* Parse the updated value */
+       for (l = bt_hf_info->indies; l != NULL; l = g_slist_next(l), ++index) {
+               struct indicator *ind = l->data;
+               if (!ind) {
+                       DBG("Index is NULL");
+                       break;
+               }
+
+               if (0 == g_strcmp0(ind->descr, "\"call\"")) {
+                       DBG("CIND Match found index = %d, %s, value = %d",
+                                               index, ind->descr, ind->value);
+                       bt_hf_info->ciev_call_status = ind->value;
+                       if (ind->value > 0) {
+                               bt_hf_info->is_dialing = FALSE;
+                               bt_hf_info->call_active = TRUE;
+                       }
+               } else if (0 == g_strcmp0(ind->descr, "\"callsetup\"")) {
+                       DBG("CIND Match found index = %d, %s, value = %d",
+                                               index, ind->descr, ind->value);
+                       bt_hf_info->ciev_call_setup_status = ind->value;
+                       if (!bt_hf_info->is_dialing && ind->value > 0)
+                               bt_hf_info->is_dialing = TRUE;
+               }
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_establish_service_level_conn(bt_hf_agent_info_t *bt_hf_info)
+{
+       gchar buf[BT_HF_DATA_BUF_SIZE];
+       gchar cmd_buf[BT_HF_CMD_BUF_SIZE] = {0};
+       gboolean ret;
+       char *buf_ptr;
+       guint feature = BT_HF_FEATURE_EC_ANDOR_NR |
+                       BT_HF_FEATURE_CALL_WAITING_AND_3WAY |
+                       BT_HF_FEATURE_CLI_PRESENTATION |
+                       BT_HF_FEATURE_VOICE_RECOGNITION |
+                       BT_HF_FEATURE_REMOTE_VOLUME_CONTROL |
+                       BT_HF_FEATURE_ENHANCED_CALL_STATUS |
+                       BT_HF_FEATURE_CODEC_NEGOTIATION;
+
+       snprintf(cmd_buf, sizeof(cmd_buf), BT_HF_FEATURES, feature);
+       ret = __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf,
+                               strlen(cmd_buf));
+       if (!ret )
+               return FALSE;
+
+       buf_ptr = strstr(buf, "\r\n+BRSF:");
+       if (buf_ptr == NULL)
+               return FALSE;
+
+       if (!ret || sscanf(buf_ptr, "\r\n+BRSF:%5d", &bt_hf_info->ag_features) != 1)
+               return FALSE;
+       DBG("Gateway supported features are 0x%X", bt_hf_info->ag_features);
+
+       if (bt_hf_info->ag_features & BT_AG_FEATURE_CODEC_NEGOTIATION) {
+               ret = _hf_agent_codec_setup(BT_HF_CODEC_ID_MSBC);
+               if (ret != BT_HF_AGENT_ERROR_NONE)
+                       DBG("Unable to set the default WBC codec");
+
+               ret = __bt_hf_send_available_codec(bt_hf_info);
+               if (!ret)
+                       return FALSE;
+       } else {
+               /* Default codec is NB */
+               ret = _hf_agent_codec_setup(BT_HF_CODEC_ID_CVSD);
+               if (ret != BT_HF_AGENT_ERROR_NONE)
+                       DBG("Unable to set the default NBC codec");
+       }
+
+       ret = __bt_get_supported_indicators(bt_hf_info);
+       if (!ret)
+               return FALSE;
+
+
+       ret = __bt_get_current_indicators(bt_hf_info);
+       if (!ret)
+               return FALSE;
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_INDICATORS_ENABLE, buf,
+                                       sizeof(BT_HF_INDICATORS_ENABLE) - 1);
+       if (!ret || !strstr(buf, "OK"))
+               return FALSE;
+
+       if ((bt_hf_info->ag_features & BT_AG_FEATURE_3WAY) != 0) {
+               ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_HOLD_MPTY_SUPP,
+                                       buf, sizeof(BT_HF_HOLD_MPTY_SUPP) - 1);
+               if (!ret || !strstr(buf, "+CHLD:")) {
+                       ERR("Unable to get the CHLD Supported info");
+                       return FALSE;
+               }
+               bt_hf_info->hold_multiparty_features = __bt_hf_get_hold_mpty_features(
+                                                       strchr(buf, '('));
+       } else
+               bt_hf_info->hold_multiparty_features = 0;
+
+       DBG("Service layer connection successfully established...!");
+
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CALLER_IDENT_ENABLE, buf,
+                       sizeof(BT_HF_CALLER_IDENT_ENABLE) - 1);
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CARRIER_FORMAT, buf,
+                       sizeof(BT_HF_CARRIER_FORMAT) - 1);
+       __bt_hf_send_and_read(bt_hf_info, BT_HF_CALLWAIT_NOTI_ENABLE, buf,
+                       sizeof(BT_HF_CALLWAIT_NOTI_ENABLE) - 1);
+
+       if ((bt_hf_info->ag_features & BT_AG_FEATURE_NREC) != 0)
+               __bt_hf_send_and_read(bt_hf_info, BT_HF_NREC, buf,
+                                               sizeof(BT_HF_NREC) - 1);
+
+       if ((bt_hf_info->ag_features & BT_AG_FEATURE_EXTENDED_RES_CODE) != 0)
+               __bt_hf_send_and_read(bt_hf_info, BT_HF_EXTENDED_RESULT_CODE,
+                       buf, sizeof(BT_HF_EXTENDED_RESULT_CODE) - 1);
+
+       if (__bt_get_bia_cmd(bt_hf_info, cmd_buf, sizeof(cmd_buf)) == TRUE)
+               __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf, strlen(cmd_buf));
+       else
+               ERR("__bt_get_bia_cmd is failed");
+
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_XSAT, buf,
+                                               sizeof(BT_HF_XSAT) - 1);
+       DBG("sent BT_HF_XSAT");
+
+       /* send Bluetooth Samsung Support Feature cmd */
+       ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_BSSF, buf,
+                                               sizeof(BT_HF_BSSF) - 1);
+       DBG("sent BT_HF_BSSF");
+
+       return TRUE;
+}
+
+static void __bt_hf_agent_sigterm_handler(int signo)
+{
+       ERR("***** Signal handler came with signal %d *****", signo);
+       __bt_hf_agent_emit_signal(gdbus_conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "CallEnded", NULL);
+       DBG("CallEnded Signal done");
+       if (gmain_loop) {
+               g_main_loop_quit(gmain_loop);
+               DBG("Exiting");
+               gmain_loop = NULL;
+       } else {
+               DBG("Terminating HF agent");
+               exit(0);
+       }
+}
+
+static void __bt_convert_addr_type_to_rev_string(char *address,
+                               unsigned char *addr)
+{
+       ret_if(address == NULL);
+       ret_if(addr == NULL);
+
+       g_snprintf(address, BT_ADDRESS_STRING_SIZE,
+                       "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+                       addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+}
+
+static gboolean __bt_agent_request_service_level_conn(gpointer data)
+{
+       char *remote_addr;
+       GError *error;
+       int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
+
+       DBG("+");
+       memset(prev_cmd, 0, BT_HF_CMD_BUF_SIZE);
+
+       if (!__bt_establish_service_level_conn(&bt_hf_info)) {
+               error = __bt_hf_agent_set_error(BT_HF_AGENT_ERROR_CONNECTION_FAILED);
+               g_error_free(error);
+               //:TODO: in case of any error Close the socket
+               DBG("Service Level Connection is fail");
+               goto done;
+       }
+
+       bt_hf_info.state = BT_HF_STATE_CONNECTED;
+
+       __bt_hf_agent_sco_accept(&bt_hf_info);
+
+       __bt_hf_agent_start_watch(&bt_hf_info);
+
+       remote_addr = bt_hf_info.remote_addr;
+
+       DBG_SECURE("Address is : %s", remote_addr);
+
+       if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) == 0) {
+               DBG("BT device state is : 0x%X", bt_device_state);
+               bt_device_state |= VCONFKEY_BT_DEVICE_AG_CONNECTED;
+               if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0) {
+                       DBG("vconf_set_int failed");
+               }
+       } else {
+               DBG("vconf_get_str failed");
+       }
+
+       __bt_hf_agent_emit_signal(gdbus_conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "Connected",
+                       g_variant_new("(s)", remote_addr));
+
+       /* Request the call list and launch call app if required */
+       __bt_hf_agent_handle_call_list(&bt_hf_info);
+
+#ifdef FEATURE_TIZENW
+       __bt_stop_adv();
+#endif
+done:
+       DBG("-");
+       return FALSE;
+}
+
+static gboolean __bt_hf_agent_connection(gint32 fd, guint16 version)
+{
+       GIOFlags flags;
+
+       struct sockaddr_remote address;
+       socklen_t address_len;
+
+       DBG("**** New HFP connection ****\n");
+
+       is_hf_connected = TRUE;
+
+       if (adv_timer_id > 0) {
+               DBG("**** Alarm is going on. It is cancelled ****\n");
+               alarmmgr_remove_alarm(adv_timer_id);
+               adv_timer_id = 0;
+       }
+
+       address_len = sizeof(address);
+       if (getpeername(fd, (struct sockaddr *) &address, &address_len) != 0)
+               DBG("BD_ADDR is NULL");
+
+       DBG("RFCOMM connection for HFP is completed. Fd = [%d]\n", fd);
+       bt_hf_info.fd = fd;
+       bt_hf_info.io_chan = g_io_channel_unix_new(bt_hf_info.fd);
+       flags = g_io_channel_get_flags(bt_hf_info.io_chan);
+
+       flags &= ~G_IO_FLAG_NONBLOCK;
+       flags &= G_IO_FLAG_MASK;
+       g_io_channel_set_flags(bt_hf_info.io_chan, flags, NULL);
+       g_io_channel_set_encoding(bt_hf_info.io_chan, NULL, NULL);
+       g_io_channel_set_buffered(bt_hf_info.io_chan, FALSE);
+
+       bt_hf_info.remote_addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       __bt_convert_addr_type_to_rev_string(bt_hf_info.remote_addr,
+                                               address.remote_bdaddr.b);
+
+       g_idle_add(__bt_agent_request_service_level_conn, NULL);
+
+       return TRUE;
+}
+
+static void __bt_hf_agent_indicator_slice_free(gpointer mem)
+{
+       g_slice_free(struct indicator, mem);
+}
+
+static gboolean __bt_hf_agent_release(void)
+{
+       int bt_device_state = VCONFKEY_BT_DEVICE_NONE;
+
+       g_slist_foreach(bt_hf_info.indies, (GFunc) __bt_hf_agent_indicator_slice_free, NULL);
+       g_slist_free(bt_hf_info.indies);
+
+       g_io_channel_shutdown(bt_hf_info.io_chan, TRUE, NULL);
+       g_io_channel_unref(bt_hf_info.io_chan);
+       bt_hf_info.io_chan = NULL;
+
+       g_source_remove(bt_hf_info.sco_watch_id);
+
+       bt_hf_info.state = BT_HF_STATE_DISCONNECTED;
+
+       if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) == 0) {
+               DBG("BT device state is : 0x%X", bt_device_state);
+               bt_device_state ^= VCONFKEY_BT_DEVICE_AG_CONNECTED;
+               if (vconf_set_int(VCONFKEY_BT_DEVICE, bt_device_state) != 0) {
+                       DBG("vconf_set_int failed");
+               }
+       } else {
+               DBG("vconf_get_str failed");
+       }
+
+       __bt_hf_agent_stop_watch(&bt_hf_info);
+       __bt_hf_agent_emit_signal(gdbus_conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "Disconnected",
+                       g_variant_new("(s)", bt_hf_info.remote_addr));
+
+       g_free(bt_hf_info.remote_addr);
+
+       __launch_system_popup(BT_AGENT_EVENT_HANDSFREE_DISCONNECT);
+       return TRUE;
+}
+
+static gboolean __bt_hf_agent_connection_release(void)
+{
+       return __bt_hf_agent_release();
+}
+
+static void __bt_hf_agent_register(void)
+{
+       DBG("+");
+
+       gchar *path = g_strdup(BT_HF_BLUEZ_OBJECT_PATH);
+
+       __bt_hf_agent_gdbus_method_send(BLUEZ_SERVICE_NAME,
+                               g_variant_new("(o)", path),
+                               BLUEZ_HF_INTERFACE_NAME,
+                               "RegisterAgent");
+
+       g_free(path);
+
+       DBG("-");
+       return;
+}
+
+static void __bt_hf_agent_unregister(void)
+{
+       DBG("+");
+
+       gchar *path = g_strdup(BT_HF_BLUEZ_OBJECT_PATH);
+
+       if (g_obj_path) {
+               __bt_hf_agent_gdbus_method_send(BLUEZ_SERVICE_NAME,
+                                               g_variant_new("(o)", path),
+                                               BLUEZ_HF_INTERFACE_NAME,
+                                               "UnregisterAgent");
+               g_free(g_obj_path);
+               g_obj_path = NULL;
+       }
+
+       g_free(path);
+
+       DBG("-");
+       return;
+}
+
+static void __bt_hf_agent_filter_cb(GDBusConnection *connection,
+                                                const gchar *sender_name,
+                                                const gchar *object_path,
+                                                const gchar *interface_name,
+                                                const gchar *signal_name,
+                                                GVariant *parameters,
+                                                gpointer user_data)
+{
+       DBG("+");
+       char *path = NULL;
+
+       if (strcasecmp(signal_name, "AdapterAdded") == 0) {
+
+               g_variant_get(parameters, "(&o)", &path);
+               if (!path) {
+                       ERR("Invalid adapter path");
+                       return;
+               }
+
+               DBG("Adapter Path = [%s]", path);
+
+               g_obj_path = g_strdup(path);
+               DBG("g_obj_path = [%s]", g_obj_path);
+
+               __bt_hf_agent_register();
+#ifdef FEATURE_TIZENW
+               __bt_start_adv_timer();
+               __bt_hf_auto_connect();
+#endif /* FEATURE_TIZENW */
+       } else if (strcasecmp(signal_name, "AdapterRemoved") == 0) {
+               __bt_hf_agent_unregister();
+       }
+
+       DBG("-");
+}
+
+static void __bt_hf_agent_dbus_init(void)
+{
+
+       DBG("+");
+
+       if (__bt_hf_get_gdbus_connection() == NULL) {
+               ERR("Error in creating the gdbus connection\n");
+               return;
+       }
+       if (!__bt_hf_register_profile_methods()) {
+               ERR("Error in register_profile_methods\n");
+               return;
+       }
+
+       owner_sig_id = g_dbus_connection_signal_subscribe(gdbus_conn,
+                               NULL, "org.bluez.Manager", NULL, NULL, NULL, 0,
+                               __bt_hf_agent_filter_cb, NULL, NULL);
+
+       DBG("-");
+       return;
+}
+
+static void __bt_hf_agent_dbus_deinit(void)
+{
+
+       if (service_gproxy) {
+               g_object_unref(service_gproxy);
+               service_gproxy = NULL;
+       }
+
+       if (gdbus_conn) {
+               if (owner_sig_id != -1)
+                       g_dbus_connection_signal_unsubscribe(gdbus_conn,
+                                               owner_sig_id);
+
+               g_object_unref(gdbus_conn);
+               gdbus_conn = NULL;
+       }
+       return;
+}
+
+static int __bt_hf_agent_convert_cme_error(int value)
+{
+       ERR("CMEE Error, value = %d", value);
+
+       switch (value) {
+       case BT_AG_CME_ERROR_NO_PHONE_CONNECTION:
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       case BT_AG_CME_ERROR_NOT_ALLOWED:
+               return BT_HF_AGENT_ERROR_NOT_ALLOWED;
+       case BT_AG_CME_ERROR_NOT_SUPPORTED:
+               return BT_HF_AGENT_ERROR_NOT_SUPPORTED;
+
+       default:
+               return BT_HF_AGENT_ERROR_INTERNAL;
+               break;
+       }
+}
+static int _hf_agent_answer_call(void)
+{
+       int ret;
+       char buf[BT_HF_DATA_BUF_SIZE];
+       DBG("+\n");
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       ret = __bt_hf_send_and_read(&bt_hf_info, BT_HF_ANSWER_CALL, buf,
+                               sizeof(BT_HF_ANSWER_CALL) - 1);
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       if (strstr(buf, BT_HF_OK_RESPONSE)) {
+               DBG("OK, return\n");
+               return BT_HF_AGENT_ERROR_NONE;
+       }
+
+       if ((bt_hf_info.ag_features & BT_AG_FEATURE_EXTENDED_RES_CODE) != 0) {
+               int value;
+               char *buf_ptr;
+               buf_ptr = strstr(buf, "\r\n+CME ERROR:");
+               if (buf_ptr) {
+                       if (sscanf(buf_ptr, "\r\n+CME ERROR:%2d\r\n", &value))
+                               return __bt_hf_agent_convert_cme_error(value);
+               }
+       }
+
+       DBG("-\n");
+       return BT_HF_AGENT_ERROR_INTERNAL;
+}
+
+static int _hf_agent_terminate_call(void)
+{
+       int ret;
+       char buf[BT_HF_DATA_BUF_SIZE];
+       DBG("+\n");
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       ret = __bt_hf_send_and_read(&bt_hf_info, BT_HF_END_CALL, buf,
+                               sizeof(BT_HF_END_CALL) - 1);
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       if (strstr(buf, BT_HF_OK_RESPONSE)) {
+               DBG("OK, return\n");
+               return BT_HF_AGENT_ERROR_NONE;
+       }
+       DBG("-\n");
+       return BT_HF_AGENT_ERROR_INTERNAL;
+}
+
+static int _hf_agent_dial_no(char *no)
+{
+       int ret;
+       char buf[BT_MAX_TEL_NUM_STR + 6] = {0};
+       char rbuf[BT_HF_DATA_BUF_SIZE];
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       if (strlen(no) > 0) {
+               snprintf(buf, sizeof(buf),  BT_HF_DIAL_NO, no);
+
+               /* prev_cmd is meant for only meant for ATD Error handling */
+               snprintf(prev_cmd, BT_HF_CMD_BUF_SIZE, "%s", buf);
+
+               ret = __bt_hf_send_only(&bt_hf_info, buf, strlen(buf));
+
+               if (!ret)
+                       return BT_HF_AGENT_ERROR_INTERNAL;
+
+               return BT_HF_AGENT_ERROR_NONE;
+       }
+       ret = __bt_hf_send_and_read(&bt_hf_info, BT_HF_REDIAL, rbuf,
+                                               sizeof(BT_HF_REDIAL) - 1);
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       if (strstr(rbuf, BT_HF_OK_RESPONSE))
+               return BT_HF_AGENT_ERROR_NONE;
+
+       if ((bt_hf_info.ag_features & BT_AG_FEATURE_EXTENDED_RES_CODE) != 0) {
+               int value;
+               char *rbuf_ptr;
+               rbuf_ptr =  strstr(rbuf, "\r\n+CME ERROR:");
+               if (rbuf_ptr) {
+                       if (sscanf(rbuf_ptr, "\r\n+CME ERROR:%2d\r\n", &value))
+                               return __bt_hf_agent_convert_cme_error(value);
+               }
+       }
+
+       return BT_HF_AGENT_ERROR_INTERNAL;
+}
+
+static int _hf_agent_voice_recognition(unsigned int status)
+{
+       int ret;
+       char buf[20] = {0};
+       char rbuf[BT_HF_DATA_BUF_SIZE];
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       snprintf(buf, sizeof(buf),  BT_HF_VOICE_RECOGNITION, status);
+       ret = __bt_hf_send_and_read(&bt_hf_info, buf, rbuf,
+                               strlen(buf));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       if (strstr(rbuf, BT_HF_OK_RESPONSE)) {
+               DBG("OK, return\n");
+               return BT_HF_AGENT_ERROR_NONE;
+       }
+       return BT_HF_AGENT_ERROR_INTERNAL;
+}
+
+static int _hf_agent_set_speaker_gain(unsigned int gain)
+{
+       int ret;
+       char buf[20] = {0};
+       char rbuf[BT_HF_DATA_BUF_SIZE];
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       if (gain > BT_HF_MAX_SPEAKER_GAIN)
+               return BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       snprintf(buf, sizeof(buf),  BT_HF_SPEAKER_GAIN, gain);
+       ret = __bt_hf_send_and_read(&bt_hf_info, buf, rbuf,
+                               strlen(buf));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       if (strstr(rbuf, BT_HF_OK_RESPONSE)) {
+               DBG("OK, return\n");
+               return BT_HF_AGENT_ERROR_NONE;
+       }
+       return BT_HF_AGENT_ERROR_INTERNAL;
+
+}
+
+static int _hf_agent_send_dtmf(char *dtmf)
+{
+       int ret;
+       char buf[20] = {0};
+
+       if (strlen(dtmf) <= 0)
+               return BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED) {
+               ERR("HF not Connected");
+               return BT_HF_AGENT_ERROR_NOT_CONNECTED;
+       }
+
+       snprintf(buf, sizeof(buf),  BT_HF_DTMF, dtmf);
+       ret = __bt_hf_send_only(&bt_hf_info, buf, strlen(buf));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+
+static int _hf_agent_send_cmd_read_resp(char *cmd)
+{
+       int ret;
+       char buf[BT_HF_DATA_BUF_SIZE];
+
+       if (strlen(cmd) <= 0)
+               return BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       ret = __bt_hf_send_and_read(&bt_hf_info, cmd, buf,
+                               strlen(cmd));
+       if (!ret)
+               return BT_HF_AGENT_ERROR_INTERNAL;
+
+       if (strstr(buf, BT_HF_OK_RESPONSE)) {
+               DBG("OK, return\n");
+               return BT_HF_AGENT_ERROR_NONE;
+       }
+
+       return BT_HF_AGENT_ERROR_INTERNAL;
+}
+
+static gboolean bt_hf_agent_sco_disconnect(void)
+{
+       DBG("+");
+       close(bt_hf_info.cli_sco_fd);
+       bt_hf_info.cli_sco_fd = -1;
+
+       DBG("Emit AudioDisconnected Signal");
+       __bt_hf_agent_emit_signal(gdbus_conn,
+                       BT_HF_AGENT_OBJECT_PATH,
+                       BT_HF_SERVICE_INTERFACE,
+                       "AudioDisconnected", NULL);
+       DBG("-");
+       return TRUE;
+}
+
+static GVariant *bt_hf_agent_request_call_list()
+{
+       GSList *call_list = NULL;
+       GVariant *var_data;
+       DBG("+");
+
+       call_list = __bt_hf_get_call_list(&bt_hf_info);
+       if (!call_list) {
+               DBG("call list is NULL");
+               return NULL;
+       }
+
+       var_data = __bt_hf_agent_get_call_status_info(call_list);
+       __bt_hf_free_call_list(call_list);
+
+       DBG("-");
+       return var_data;
+}
+
+static int bt_hf_agent_send_at_cmd(char *atcmd)
+
+{
+       gboolean ret;
+       char cmd_buf[BT_HF_CMD_BUF_SIZE * 2] = {0, };
+       char rbuf[BT_HF_DATA_BUF_SIZE];
+       DBG("+");
+
+       if (atcmd == NULL)
+               return  BT_HF_AGENT_ERROR_INVALID_PARAM;
+
+       if (bt_hf_info.state != BT_HF_STATE_CONNECTED)
+               return  BT_HF_AGENT_ERROR_NOT_CONNECTED;
+
+       strncpy(cmd_buf, atcmd, sizeof(cmd_buf) - 1);
+       strncat(cmd_buf, "\r", (sizeof(cmd_buf) - 1) - strlen(cmd_buf));
+
+       ret = __bt_hf_send_and_read(&bt_hf_info, cmd_buf, rbuf, strlen(cmd_buf));
+       if (!ret)
+               ret = BT_HF_AGENT_ERROR_INTERNAL;
+
+       if (strstr(rbuf, BT_HF_OK_RESPONSE))
+               DBG("OK, return\n");
+
+       DBG("-");
+       return BT_HF_AGENT_ERROR_NONE;
+}
+
+int main(void)
+{
+       int ret_val;
+       struct sigaction sa;
+       const char *pkg_name = "org.tizen.hf_agent";
+
+       DBG("Starting Bluetooth HF agent");
+
+       g_type_init();
+
+       ret_val = alarmmgr_init(pkg_name);
+       if (ret_val != ALARMMGR_RESULT_SUCCESS) {
+               DBG("Alarm Init failed ");
+               return FALSE;
+       }
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_flags = SA_NOCLDSTOP;
+       sa.sa_handler = __bt_hf_agent_sigterm_handler;
+       sigaction(SIGTERM, &sa, NULL);
+       sigaction(SIGSEGV, &sa, NULL);
+       sigaction(SIGABRT, &sa, NULL);
+       gmain_loop = g_main_loop_new(NULL, FALSE);
+
+       if (gmain_loop == NULL) {
+               ERR("GMainLoop create failed\n");
+               return EXIT_FAILURE;
+       }
+
+       __bt_hf_agent_dbus_init();
+#ifdef FEATURE_TIZENW
+       bluetooth_hf_init(__hf_event_handler, NULL);
+#endif
+       g_main_loop_run(gmain_loop);
+
+       __bt_hf_agent_dbus_deinit();
+
+       if (gmain_loop)
+               g_main_loop_unref(gmain_loop);
+
+       DBG("Terminating Bluetooth HF agent");
+       return 0;
+}
diff --git a/wearable/hf-agent/bluetooth-hf-agent.h b/wearable/hf-agent/bluetooth-hf-agent.h
new file mode 100644 (file)
index 0000000..cf1dc7d
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Bluetooth-hf-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Girishashok Joshi <girish.joshi@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_HF_AGENT_H_
+#define __DEF_BT_HF_AGENT_H_
+
+#undef LOG_TAG
+#define LOG_TAG "BT_HF_AGENT"
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define INFO(fmt, args...) SLOGI(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define INFO_SECURE(fmt, args...) SECURE_SLOGI(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+
+#define BTPROTO_SCO    2
+
+#define BT_HF_DATA_BUF_SIZE 1024
+#define BT_HF_CMD_BUF_SIZE 32
+#define BT_HF_INDICATOR_DESCR_SIZE 20
+#define BT_HF_CALLER_NUM_SIZE 64       /* size of number + type */
+#define BT_HF_FMT_STR_SIZE 32
+
+#define BT_HF_AGENT_ERROR (__bt_hf_agent_error_quark())
+
+#define BT_ERROR_INTERNAL "InternalError"
+#define BT_ERROR_NOT_AVAILABLE "NotAvailable"
+#define BT_ERROR_NOT_CONNECTED "NotConnected"
+#define BT_ERROR_NOT_CONNECTION_FAILED "ConnectionFailed"
+#define BT_ERROR_BUSY "InProgress"
+#define BT_ERROR_INVALID_PARAM "InvalidArguments"
+#define BT_ERROR_ALREADY_EXIST "AlreadyExists"
+#define BT_ERROR_ALREADY_CONNECTED "Already Connected"
+#define BT_ERROR_NO_MEMORY "No memory"
+#define BT_ERROR_I_O_ERROR "I/O error"
+#define BT_ERROR_OPERATION_NOT_AVAILABLE "Operation currently not available"
+#define BT_ERROR_OPERATION_NOT_ALLOWED "Operation not allowed"
+#define BT_ERROR_OPERATION_NOT_SUPPORTED "Operation not supported"
+#define BT_ERROR_INVALID_FILE_DESCRIPTOR "Invalid File Descriptor"
+
+typedef enum {
+       BT_HF_AGENT_ERROR_NONE,
+       BT_HF_AGENT_ERROR_INTERNAL,
+       BT_HF_AGENT_ERROR_NOT_AVAILABLE,
+       BT_HF_AGENT_ERROR_NOT_CONNECTED,
+       BT_HF_AGENT_ERROR_CONNECTION_FAILED,
+       BT_HF_AGENT_ERROR_BUSY,
+       BT_HF_AGENT_ERROR_INVALID_PARAM,
+       BT_HF_AGENT_ERROR_ALREADY_EXIST,
+       BT_HF_AGENT_ERROR_ALREADY_CONNECTED,
+       BT_HF_AGENT_ERROR_NO_MEMORY,
+       BT_HF_AGENT_ERROR_I_O_ERROR,
+       BT_HF_AGENT_ERROR_APPLICATION,
+       BT_HF_AGENT_ERROR_NOT_ALLOWED,
+       BT_HF_AGENT_ERROR_NOT_SUPPORTED,
+       BT_HF_AGENT_ERROR_INVALID_FILE_DESCRIPTOR,
+} bt_hf_agent_error_t;
+
+/* Extended Audio Gateway Error Result Codes */
+typedef enum {
+       BT_AG_CME_ERROR_NONE                    = -1,
+       BT_AG_CME_ERROR_AG_FAILURE              = 0,
+       BT_AG_CME_ERROR_NO_PHONE_CONNECTION     = 1,
+       BT_AG_CME_ERROR_NOT_ALLOWED             = 3,
+       BT_AG_CME_ERROR_NOT_SUPPORTED           = 4,
+       BT_AG_CME_ERROR_PH_SIM_PIN_REQUIRED     = 5,
+       BT_AG_CME_ERROR_SIM_NOT_INSERTED        = 10,
+       BT_AG_CME_ERROR_SIM_PIN_REQUIRED        = 11,
+       BT_AG_CME_ERROR_SIM_PUK_REQUIRED        = 12,
+       BT_AG_CME_ERROR_SIM_FAILURE             = 13,
+       BT_AG_CME_ERROR_SIM_BUSY                = 14,
+       BT_AG_CME_ERROR_INCORRECT_PASSWORD      = 16,
+       BT_AG_CME_ERROR_SIM_PIN2_REQUIRED       = 17,
+       BT_AG_CME_ERROR_SIM_PUK2_REQUIRED       = 18,
+       BT_AG_CME_ERROR_MEMORY_FULL             = 20,
+       BT_AG_CME_ERROR_INVALID_INDEX           = 21,
+       BT_AG_CME_ERROR_MEMORY_FAILURE          = 23,
+       BT_AG_CME_ERROR_TEXT_STRING_TOO_LONG    = 24,
+       BT_AG_CME_ERROR_INVALID_TEXT_STRING     = 25,
+       BT_AG_CME_ERROR_DIAL_STRING_TOO_LONG    = 26,
+       BT_AG_CME_ERROR_INVALID_DIAL_STRING     = 27,
+       BT_AG_CME_ERROR_NO_NETWORK_SERVICE      = 30,
+       BT_AG_CME_ERROR_NETWORK_TIMEOUT         = 31,
+       BT_AG_CME_ERROR_NETWORK_NOT_ALLOWED     = 32,
+} bt_ag_cme_error_t;
+
+typedef enum {
+       BT_HF_CALL_DIR_OUTGOING,
+       BT_HF_CALL_DIR_INCOMING,
+} bt_hf_call_direction_t;
+
+/* Call status as per spec */
+typedef enum {
+       BT_HF_CALL_STAT_ACTIVE,
+       BT_HF_CALL_STAT_HELD,
+       BT_HF_CALL_STAT_DIALING,
+       BT_HF_CALL_STAT_ALERTING,
+       BT_HF_CALL_STAT_INCOMING,
+       BT_HF_CALL_STAT_WAITING,
+} bt_hf_call_status_t;
+
+/*Handsfree supported features*/
+#define BT_HF_FEATURE_EC_ANDOR_NR                      0x0001
+#define BT_HF_FEATURE_CALL_WAITING_AND_3WAY    0x0002
+#define BT_HF_FEATURE_CLI_PRESENTATION         0x0004
+#define BT_HF_FEATURE_VOICE_RECOGNITION                0x0008
+#define BT_HF_FEATURE_REMOTE_VOLUME_CONTROL    0x0010
+#define BT_HF_FEATURE_ENHANCED_CALL_STATUS     0x0020
+#define BT_HF_FEATURE_ENHANCED_CALL_CONTROL    0x0040
+#define BT_HF_FEATURE_CODEC_NEGOTIATION                0x0080
+
+/*AG suported feature*/
+#define BT_AG_FEATURE_3WAY 0x1
+#define BT_AG_FEATURE_NREC     0x0002
+#define BT_AG_FEATURE_EXTENDED_RES_CODE 0x100
+#define BT_AG_FEATURE_CODEC_NEGOTIATION        0x0200
+
+#define BT_HF_CODEC_ID_CVSD 1
+#define BT_HF_CODEC_ID_MSBC 2
+
+#define BT_HF_AUDIO_DISCONNECTED 0
+#define BT_HF_AUDIO_CONNECTED 1
+
+#define BT_MAX_TEL_NUM_STR 100
+
+#define BT_HF_FEATURES "AT+BRSF=%d\r\n"     /* = 0x7F = All features supported */
+#define BT_HF_INDICATORS_SUPP "AT+CIND=?\r\n"
+#define BT_HF_INDICATORS_VAL "AT+CIND?\r\n"
+#define BT_HF_INDICATORS_ENABLE "AT+CMER=3,0,0,1\r\n"
+#define BT_HF_HOLD_MPTY_SUPP "AT+CHLD=?\r\n"
+#define BT_HF_CALLER_IDENT_ENABLE "AT+CLIP=1\r\n"
+#define BT_HF_CARRIER_FORMAT "AT+COPS=3,0\r\n"
+#define BT_HF_EXTENDED_RESULT_CODE "AT+CMEE=1\r\n"
+#define BT_HF_INDICATORS_ACTIVATION "AT+BIA="
+#define BT_HF_ANSWER_CALL "ATA\r\n"
+#define BT_HF_END_CALL "AT+CHUP\r\n"
+#define BT_HF_REDIAL "AT+BLDN\r\n"
+#define BT_HF_DIAL_NO "ATD%.100s;\r\n"
+#define BT_HF_VOICE_RECOGNITION "AT+BVRA=%d\r\n"
+#define BT_HF_XSAT "AT+XSAT=00,TY,WA\r\n"
+#define BT_HF_BSSF "AT+BSSF=8\r\n"
+#define BT_HF_CALLLIST "AT+CLCC\r\n"
+#define BT_HF_AVAILABLE_CODEC "AT+BAC=%d,%d\r\n"
+#define BT_HF_CODEC_SELECT "AT+BCS=%d\r\n"
+#define BT_HF_SPEAKER_GAIN "AT+VGS=%d\r\n"
+#define BT_HF_DTMF "AT+VTS=%s\r\n"
+#define BT_HF_NREC "AT+NREC=0\r\n"
+#define BT_HF_CALLWAIT_NOTI_ENABLE "AT+CCWA=1\r\n"
+#define BT_HF_RELEASE_ALL "AT+CHLD=0\r\n"
+#define BT_HF_RELEASE_AND_ACCEPT "AT+CHLD=1\r\n"
+#define BT_HF_ACCEPT_AND_HOLD "AT+CHLD=2\r\n"
+#define BT_HF_JOIN_CALL "AT+CHLD=3\r\n"
+
+#define BT_MAX_EVENT_STR_LENGTH         50
+#define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
+
+#define BT_HF_MAX_SPEAKER_GAIN 15
+#define BT_HF_MIN_SPEAKER_GAIN 0
+
+
+typedef enum {
+       BT_AGENT_EVENT_HANDSFREE_CONNECT = 0x1100,
+       BT_AGENT_EVENT_HANDSFREE_DISCONNECT = 0x1200,
+} bt_hfp_agent_event_type_t;
+
+/* Hold and multipary AG features.
+ * Comments below are copied from hands-free spec for reference */
+/* Releases all held calls or sets User Determined User Busy (UDUB)
+ * for a waiting call */
+#define BT_HF_CHLD_0 0x01
+/* Releases all active calls (if any exist) and accepts the other
+ * (held or waiting) call */
+#define BT_HF_CHLD_1 0x02
+/* Releases specified active call only <x> */
+#define BT_HF_CHLD_1x 0x04
+/* Places all active calls (if any exist) on hold and accepts the other
+ * (held or waiting) call */
+#define BT_HF_CHLD_2 0x08
+/* Request private consultation mode with specified call <x> (Place all
+ * calls on hold EXCEPT the call <x>) */
+#define BT_HF_CHLD_2x 0x10
+/* Adds a held call to the conversation */
+#define BT_HF_CHLD_3 0x20
+/* Connects the two calls and disconnects the subscriber from both calls
+ * (Explicit Call Transfer). Support for this value and its associated
+ * functionality is optional for the HF. */
+#define BT_HF_CHLD_4 0x40
+
+#define BT_HF_OK_RESPONSE "\r\nOK\r\n"
+#define BT_HF_ERROR_RESPONSE "ERROR"
+#define BT_HF_SEC_ERROR_RESPONSE "SERR"
+
+#define BT_HF_SERVICE_NAME "org.bluez.hf_agent"
+#define BT_HF_AGENT_OBJECT_PATH "/org/bluez/handsfree_agent"
+#define BT_HF_SERVICE_INTERFACE "org.tizen.HfApp"
+
+#define BT_HF_BLUEZ_OBJECT_PATH "/org/tizen/handsfree"
+#define BT_HF_BLUEZ_INTERFACE  "org.bluez.HandsfreeAgent"
+
+#define BLUEZ_SERVICE_NAME "org.bluez"
+#define BLUEZ_HF_INTERFACE_NAME "org.bluez.HandsfreeGateway"
+
+#define PM_SERVICE_NAME "org.tizen.system.deviced"
+#define PM_OBJECT_PATH "/Org/Tizen/System/DeviceD/Display"
+#define PM_INTERFACE_NAME "org.tizen.system.deviced.display"
+
+#define retv_if(expr, val) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) return", #expr); \
+                       return (val); \
+               } \
+       } while (0)
+
+typedef enum {
+       BT_HF_STATE_DISCONNECTED,
+       BT_HF_STATE_CONNECTED
+} bt_hf_state_t;
+
+typedef struct {
+       guint32 fd;
+       gint sco_fd;
+       gint cli_sco_fd;
+
+       GIOChannel *io_chan;
+       GIOChannel *sco_io_chan;
+       bt_hf_state_t state;
+
+       guint watch_id;
+       guint sco_watch_id;
+       guint cli_sco_watch_id;
+
+       guint ag_features;
+       guint hold_multiparty_features;
+       GSList *indies;
+
+       gboolean is_dialing;
+       gboolean call_active;
+
+       guint ciev_call_status;
+       guint ciev_call_setup_status;
+
+       char *remote_addr;
+}bt_hf_agent_info_t;
+
+struct hf_event {
+       const char *cmd;
+       int (*callback) (bt_hf_agent_info_t *bt_hf_info, const char *buf);
+};
+
+typedef struct {
+       unsigned char b[6];
+} __attribute__((packed)) bdaddr_t;
+
+/* Remote socket address */
+struct sockaddr_remote {
+       sa_family_t     family;
+       bdaddr_t        remote_bdaddr;
+       uint8_t         channel;
+};
+
+/* SCO socket address */
+struct sockaddr_sco {
+       sa_family_t     sco_family;
+       bdaddr_t        sco_bdaddr;
+};
+
+#endif /* __DEF_BT_HF_AGENT_H_ */
diff --git a/wearable/hf-agent/org.bluez.hf_agent.service b/wearable/hf-agent/org.bluez.hf_agent.service
new file mode 100644 (file)
index 0000000..2b18469
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.bluez.hf_agent
+Exec=/usr/bin/bluetooth-hf-agent
diff --git a/wearable/hfp-agent/CMakeLists.txt b/wearable/hfp-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f5fc75f
--- /dev/null
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-hfp-agent C)
+
+SET(SRCS bluetooth-hfp-agent.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_hfp_agent
+               REQUIRED
+               dbus-glib-1 vconf appsvc contacts-service2 tapi capi-appfw-application aul)
+
+FOREACH(flag ${pkgs_hfp_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
+               ARGS "--prefix=bt_hfp_agent \\
+               ${CMAKE_CURRENT_SOURCE_DIR}/hfp_agent.xml \\
+               --mode=glib-server \\
+               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_hfp_agent_glue.h")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_hfp_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.hfp_agent.service
+               DESTINATION share/dbus-1/services)
diff --git a/wearable/hfp-agent/bluetooth-hfp-agent.c b/wearable/hfp-agent/bluetooth-hfp-agent.c
new file mode 100644 (file)
index 0000000..01ddd1a
--- /dev/null
@@ -0,0 +1,1977 @@
+/*
+ * Bluetooth-hfp-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Girishashok Joshi <girish.joshi@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <signal.h>
+
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+#include <app.h>
+#include <aul.h>
+
+#include "vconf.h"
+#include "vconf-keys.h"
+#include "contacts.h"
+#include "appsvc.h"
+
+#include "bluetooth-hfp-agent.h"
+
+static GMainLoop *gmain_loop = NULL;
+static DBusGConnection *g_connection = NULL;
+static DBusConnection *gconn = NULL;
+static gboolean nrec_status = FALSE;
+
+#define BT_ERROR_INTERNAL "InternalError"
+#define BT_ERROR_NOT_AVAILABLE "NotAvailable"
+#define BT_ERROR_NOT_CONNECTED "NotConnected"
+#define BT_ERROR_BUSY "InProgress"
+#define BT_ERROR_INVALID_PARAM "InvalidArguments"
+#define BT_ERROR_ALREADY_EXSIST "AlreadyExists"
+#define BT_ERROR_ALREADY_CONNECTED "Already Connected"
+#define BT_ERROR_NO_MEMORY "No memory"
+#define BT_ERROR_I_O_ERROR "I/O error"
+#define BT_ERROR_OPERATION_NOT_AVAILABLE "Operation currently not available"
+#define BT_ERROR_BATTERY "Battery error "
+#define BT_ERROR_SIGNAL "Signal error"
+#define BT_ERROR_NO_CALL_LOG "No Call log"
+#define BT_ERROR_INVLAID_DTMF "Invalid dtmf"
+
+#define BLUEZ_SERVICE_NAME "org.bluez"
+#define TELEPHONY_CSD_INTERFACE "org.tizen.telephony.csd"
+#define TELEPHONY_CSD_OBJECT_PATH "/org/tizen/csd"
+#define TELEPHONY_APP_INTERFACE "org.tizen.csd.Call.Instance"
+
+#define BT_HFP_AGENT_SET_PROPERTY "SetProperty"
+
+#define BT_HFP_AGENT_OBJECT "/org/bluez/agent/hfp_agent"
+#define BT_HFP_AGENT_INTERFACE "org.bluez.hfp_agent"
+
+#define BT_SIGNAL_ARRAY_MAX 2
+
+/* AT+CSQ : Returns received signal strength indication.
+     Command response: +CSQ: <rssi>,<ber>
+    <ber> is not supported and has a constant value of 99, included for compatibility reasons.
+*/
+#define BT_SIGNAL_QUALITY_BER 99
+
+/*Length of the string used to send telephone number to app-svc
+   format: tel:<number>
+*/
+#define BT_MAX_TEL_NUM_STRING 20
+
+/**
+ * @brief Outgoing call type status
+ *
+ * 0 : Follow last call log \n
+ * 1 : Voice call \n
+ * 2 : Video call \n
+ */
+#define BT_FOLLOW_CALL_LOG 0
+#define BT_VOICE_CALL 1
+#define BT_VIDEO_CALL 2
+
+/**
+ * @brief The status of making outgoing calls with BT headsets
+ *
+ * 0 : Even when device locked \n
+ * 1 : Only when device unlocked \n
+ */
+#define BT_MO_EVEN_LOCKED 0
+#define BT_MO_ONLY_UNLOCKED 1
+
+#define BT_CHECK_SIGNAL_STRENGTH(rssi) \
+       if (rssi >= VCONFKEY_TELEPHONY_RSSI_4) \
+               rssi = VCONFKEY_TELEPHONY_RSSI_5
+
+typedef struct {
+       GObject parent;
+} BtHfpAgent;
+
+typedef struct {
+       GObjectClass parent;
+} BtHfpAgentClass;
+
+GType bt_hfp_agent_get_type(void);
+
+#define BT_HFP_TYPE_AGENT (bt_hfp_agent_get_type())
+
+#define BT_HFP_AGENT(object)(G_TYPE_CHECK_INSTANCE_CAST((object), \
+                       BT_HFP_TYPE_AGENT , BtHfpAgent))
+
+#define BT_HFP_AGENT_CLASS(klass)(G_TYPE_CHECK_CLASS_CAST((klass), \
+                       BT_HFP_TYPE_AGENT , BtHfpAgentClass))
+
+#define BT_IS_HFP_AGENT(object)(G_TYPE_CHECK_INSTANCE_TYPE((object), \
+                       BT_HFP_TYPE_AGENT))
+
+#define BT_IS_HFP_AGENT_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE((klass), \
+                       BT_HFP_TYPE_AGENT))
+
+#define BT_HFP_AGENT_GET_CLASS(obj)(G_TYPE_INSTANCE_GET_CLASS((obj), \
+                       BT_HFP_TYPE_AGENT , BtHfpAgentClass))
+
+G_DEFINE_TYPE(BtHfpAgent, bt_hfp_agent, G_TYPE_OBJECT)
+
+static gboolean bt_hfp_agent_register_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_unregister_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_incoming_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_outgoing_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_change_call_status(BtHfpAgent *agent,
+                               const gchar *path, gint status, gint call_id,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_answer_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_release_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_reject_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_threeway_call(BtHfpAgent *agent, gint call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent,
+                               const gchar *number, guint flags,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_dial_memory(BtHfpAgent *agent, gint location,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_send_dtmf(BtHfpAgent *agent, const gchar *dtmf,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_voice_dial(BtHfpAgent *agent, gboolean activate,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_battery_status(BtHfpAgent *object,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_signal_quality(BtHfpAgent *object,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_properties(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_get_operator_name(BtHfpAgent *object,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_nrec_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context);
+
+static gboolean bt_hfp_agent_connection_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context);
+
+#include "bluetooth_hfp_agent_glue.h"
+
+static void bt_hfp_agent_init(BtHfpAgent *obj)
+{
+       DBG("\n");
+
+       g_assert(obj != NULL);
+}
+
+static void bt_hfp_agent_finalize(GObject *obj)
+{
+       DBG("\n");
+
+       G_OBJECT_CLASS(bt_hfp_agent_parent_class)->finalize(obj);
+}
+
+static void bt_hfp_agent_class_init(BtHfpAgentClass *klass)
+{
+       DBG("\n");
+
+       GObjectClass *object_class = (GObjectClass *)klass;
+
+       g_assert(klass != NULL);
+
+       object_class->finalize = bt_hfp_agent_finalize;
+
+       dbus_g_object_type_install_info(BT_HFP_TYPE_AGENT,
+                                       &dbus_glib_bt_hfp_agent_object_info);
+}
+
+static GQuark __bt_hfp_agent_error_quark(void)
+{
+       DBG("\n");
+
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string("agent");
+
+       return quark;
+}
+
+static GError *__bt_hfp_agent_set_error(bt_hfp_agent_error_t error)
+{
+       ERR("error[%d]\n", error);
+
+       switch (error) {
+       case BT_HFP_AGENT_ERROR_NOT_AVAILABLE:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_NOT_AVAILABLE);
+       case BT_HFP_AGENT_ERROR_NOT_CONNECTED:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_NOT_CONNECTED);
+       case BT_HFP_AGENT_ERROR_BUSY:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_BUSY);
+       case BT_HFP_AGENT_ERROR_INVALID_PARAM:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_INVALID_PARAM);
+       case BT_HFP_AGENT_ERROR_ALREADY_EXSIST:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_ALREADY_EXSIST);
+       case BT_HFP_AGENT_ERROR_ALREADY_CONNECTED:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_ALREADY_CONNECTED);
+       case BT_HFP_AGENT_ERROR_NO_MEMORY:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_NO_MEMORY);
+       case BT_HFP_AGENT_ERROR_I_O_ERROR:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_I_O_ERROR);
+       case BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_OPERATION_NOT_AVAILABLE);
+       case BT_HFP_AGENT_ERROR_BATTERY_STATUS:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_BATTERY);
+       case BT_HFP_AGENT_ERROR_SIGNAL_STATUS:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_SIGNAL);
+       case BT_HFP_AGENT_ERROR_NO_CALL_LOGS:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                       BT_ERROR_NO_CALL_LOG);
+       case BT_HFP_AGENT_ERROR_INTERNAL:
+       default:
+               return g_error_new(BT_HFP_AGENT_ERROR, error,
+                                               BT_ERROR_INTERNAL);
+       }
+}
+
+static int __bt_hfp_agent_get_error(const char *error_message)
+{
+       if (error_message == NULL) {
+               DBG("Error message NULL\n");
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       ERR("Error message = %s \n", error_message);
+
+       if (g_strcmp0(error_message, BT_ERROR_NOT_AVAILABLE) == 0)
+               return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
+       else if (g_strcmp0(error_message, BT_ERROR_NOT_CONNECTED) == 0)
+               return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+       else if (g_strcmp0(error_message, BT_ERROR_BUSY) == 0)
+               return BT_HFP_AGENT_ERROR_BUSY;
+       else if (g_strcmp0(error_message, BT_ERROR_INVALID_PARAM) == 0)
+               return BT_HFP_AGENT_ERROR_INVALID_PARAM;
+       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_EXSIST) == 0)
+               return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
+       else if (g_strcmp0(error_message, BT_ERROR_ALREADY_CONNECTED) == 0)
+               return BT_HFP_AGENT_ERROR_ALREADY_CONNECTED;
+       else if (g_strcmp0(error_message, BT_ERROR_NO_MEMORY) == 0)
+               return BT_HFP_AGENT_ERROR_NO_MEMORY;
+       else if (g_strcmp0(error_message, BT_ERROR_I_O_ERROR) == 0)
+               return BT_HFP_AGENT_ERROR_I_O_ERROR;
+       else if (g_strcmp0(error_message, BT_ERROR_OPERATION_NOT_AVAILABLE) == 0)
+               return BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE;
+       else if (g_strcmp0(error_message, BT_ERROR_INVLAID_DTMF) == 0)
+               return BT_HFP_AGENT_ERROR_INVALID_DTMF;
+       else
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+}
+
+static int __bt_hfp_agent_dbus_method_send(const char *service,
+                               const char *path, const char *interface,
+                               const char *method, gboolean response,
+                               int type, ...)
+{
+       DBusMessage *msg;
+       DBusMessage *reply;
+       DBusError err;
+       va_list args;
+       int error;
+
+       msg = dbus_message_new_method_call(service, path, interface,
+                                                               method);
+       if (!msg) {
+               ERR("Unable to allocate new D-Bus %s message \n", method);
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       va_start(args, type);
+
+       if (!dbus_message_append_args_valist(msg, type, args)) {
+               dbus_message_unref(msg);
+               va_end(args);
+               return BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       va_end(args);
+
+       dbus_error_init(&err);
+
+       if (response) {
+               reply = dbus_connection_send_with_reply_and_block(gconn,
+                                                       msg, -1, &err);
+               dbus_message_unref(msg);
+
+               if (!reply) {
+                       ERR("Error returned in method call\n");
+                       if (dbus_error_is_set(&err)) {
+                               error = __bt_hfp_agent_get_error(err.message);
+                               dbus_error_free(&err);
+                               return error;
+                       } else {
+                               ERR("Error is not set\n");
+                               return BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+               }
+               dbus_message_unref(reply);
+       } else {
+               dbus_connection_send(gconn, msg, NULL);
+               dbus_message_unref(msg);
+       }
+
+       return BT_HFP_AGENT_ERROR_NONE;
+}
+
+/**
+ * [Org.Hfp.App.Interface] interface functions
+ */
+static gboolean bt_hfp_agent_register_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context)
+{
+       gboolean flag = TRUE;
+       char *sender;
+       GError *error;
+       int ret;
+
+       if (path == NULL) {
+               ERR("Invalid Argument path\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "RegisterTelephonyAgent", TRUE,
+                               DBUS_TYPE_BOOLEAN, &flag,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_unregister_application(BtHfpAgent *agent,
+                               const gchar *path, DBusGMethodInvocation *context)
+{
+       gboolean flag = FALSE;
+       char *sender;
+       GError *error;
+       int ret;
+
+       if (path == NULL) {
+               ERR("Invalid Argument path\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "RegisterTelephonyAgent", TRUE,
+                               DBUS_TYPE_BOOLEAN, &flag,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_incoming_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       char *sender;
+       int ret;
+
+       if (path == NULL || number == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+       DBG("Call id = %d\n", call_id);
+       DBG_SECURE("Phone number = %s\n", number);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "Incoming", TRUE,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &number,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_STRING, &sender,
+                               DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_outgoing_call(BtHfpAgent *agent, const gchar *path,
+                               const gchar *number, gint call_id,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       char *sender;
+       int ret;
+
+       if (path == NULL || number == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+       DBG("Call id = %d\n", call_id);
+       DBG_SECURE("Phone number = %s\n", number);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "Outgoing", TRUE,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_STRING, &number,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_STRING, &sender,
+                               DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_change_call_status(BtHfpAgent *agent,
+                               const gchar *path, gint status, gint call_id,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       char *sender;
+       int ret;
+
+       if (path == NULL) {
+               ERR("Invalid Argument path\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s\n", path);
+       DBG("Call id[%d] :: Status[%d]\n", call_id, status);
+
+       sender = dbus_g_method_get_sender(context);
+
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(BLUEZ_SERVICE_NAME,
+                               TELEPHONY_CSD_OBJECT_PATH,
+                               TELEPHONY_CSD_INTERFACE,
+                               "SetCallStatus", TRUE,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_UINT32, &status,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_STRING, &sender,
+                               DBUS_TYPE_INVALID);
+       g_free(sender);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+void __bt_append_entry(DBusMessageIter *iter,
+                       const char *key, int type, void *val)
+{
+       DBusMessageIter entry;
+       DBusMessageIter value;
+       const char *str;
+       char signal[BT_SIGNAL_ARRAY_MAX] = { type, '\0' };
+
+       if (type == DBUS_TYPE_STRING) {
+               str = *((const char **) val);
+               if (str == NULL) {
+                       return;
+               }
+       }
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+       dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+       dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+                                               signal, &value);
+       dbus_message_iter_append_basic(&value, type, val);
+       dbus_message_iter_close_container(&entry, &value);
+       dbus_message_iter_close_container(iter, &entry);
+}
+
+static gboolean bt_hfp_agent_get_properties(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context)
+{
+       DBusMessage *reply;
+       DBusMessageIter iter;
+       DBusMessageIter dict;
+       GError *error;
+
+       reply = dbus_g_method_get_reply(context);
+       if (!reply) {
+               ERR("Internal error\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+                       DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                       DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+                       DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+       DBG("NREC status [%d]\n", nrec_status);
+       __bt_append_entry(&dict, "nrec", DBUS_TYPE_BOOLEAN, &nrec_status);
+       dbus_message_iter_close_container(&iter, &dict);
+       dbus_g_method_send_reply(context, reply);
+
+       return TRUE;
+}
+
+
+/**
+ * [Org.Hfp.Bluez.Interface] interface functions
+ */
+static gboolean bt_hfp_agent_answer_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Answer", FALSE,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_release_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Release", FALSE,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_reject_call(BtHfpAgent *agent, unsigned int call_id,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Call Id = %d", call_id);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Reject", FALSE,
+                               DBUS_TYPE_UINT32, &call_id,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_threeway_call(BtHfpAgent *agent, gint value,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       int ret;
+       GError *error;
+
+       if (path == NULL || sender == NULL) {
+               ERR("Invalid Arguments\n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG("Application path = %s \n", path);
+       DBG("Value = %d", value);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "Threeway", TRUE,
+                               DBUS_TYPE_UINT32, &value,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean __bt_is_phone_locked(int *phone_lock_state)
+{
+       int ret;
+
+       if (NULL == phone_lock_state)
+               return FALSE;
+
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, phone_lock_state);
+       if (ret != 0) {
+               ERR("Failed to read  [%s]\n", VCONFKEY_IDLE_LOCK_STATE);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_get_outgoing_callapp_type(int *callapp_type)
+{
+       int ret;
+
+       if (NULL == callapp_type)
+               return FALSE;
+
+       ret = vconf_get_int(VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, callapp_type);
+       if (ret != 0) {
+               ERR("Failed to read  [%s]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT);
+               return FALSE;
+       }
+
+       DBG(" [%s] = [%d]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, *callapp_type);
+
+       return TRUE;
+}
+
+static gboolean __bt_get_outgoing_call_condition(int *condition)
+{
+       int ret;
+
+       if (NULL == condition)
+               return FALSE;
+
+       ret = vconf_get_int(VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT, condition);
+       if (ret != 0) {
+               ERR("Failed to read  [%s]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_make_call(const char *number)
+{
+       bundle *b;
+       char telnum[BT_MAX_TEL_NUM_STRING];
+
+       b = bundle_create();
+       if (NULL == b)
+               return FALSE;
+
+       appsvc_set_operation(b, APPSVC_OPERATION_CALL);
+       snprintf(telnum, sizeof(telnum), "tel:%s", number);
+       appsvc_set_uri(b, telnum);
+       appsvc_add_data(b, "ctindex", "-1");
+       appsvc_run_service(b, 0, NULL, NULL);
+       bundle_free(b);
+
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_make_video_call(const char *mo_number)
+{
+       bundle *kb;
+
+       kb = bundle_create();
+       if (NULL == kb)
+               return FALSE;
+
+       bundle_add(kb, "KEY_CALL_TYPE", "MO");
+       bundle_add(kb, "number", mo_number);
+       aul_launch_app("org.tizen.vtmain", kb);
+       bundle_free(kb);
+
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int error_code = BT_HFP_AGENT_ERROR_NONE;
+       char *last_number = NULL;
+       int log_type;
+       int callapp_type;
+       int phone_lock_state;
+       int condition;
+       contacts_list_h list = NULL;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_record_h record = NULL;
+       unsigned int projections[] = {
+               _contacts_phone_log.address,
+               _contacts_phone_log.log_type,
+       };
+
+       DBG("\n");
+
+       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_connect2 failed \n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       if (filter == NULL)
+               goto done;
+
+       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               CONTACTS_PLOG_TYPE_VOICE_OUTGOING) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_int failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_operator failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_filter_add_int failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       contacts_query_create(_contacts_phone_log._uri, &query);
+
+       if (query == NULL)
+               goto done;
+
+       contacts_query_set_filter(query, filter);
+
+       if (contacts_query_set_projection(query, projections,
+                               sizeof(projections)/sizeof(unsigned int)) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_query_set_projection failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_query_set_sort(query, _contacts_phone_log.log_time, false) !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_query_set_sort failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_db_get_records_with_query(query, 0, 1, &list)  !=
+                               CONTACTS_ERROR_NONE) {
+               ERR(" contacts_db_get_records_with_query failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_first(list)  != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_list_first failed \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_get_current_record_p(list, &record)  !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (record == NULL)
+               goto done;
+
+       if (contacts_record_get_str(record, _contacts_phone_log.address,
+                               &last_number)!= CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (last_number == NULL) {
+               ERR("No last number \n");
+               error_code = BT_HFP_AGENT_ERROR_NO_CALL_LOGS;
+               goto done;
+       }
+
+       if (!__bt_is_phone_locked(&phone_lock_state)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (!__bt_get_outgoing_call_condition(&condition)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (condition == BT_MO_ONLY_UNLOCKED &&
+                       phone_lock_state == VCONFKEY_IDLE_LOCK) {
+               ERR("Call failed. Phone is locked.\n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       switch (callapp_type) {
+               case BT_VOICE_CALL:
+                       if (!__bt_hfp_agent_make_call(last_number)) {
+                               ERR("Problem launching application \n");
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+                       break;
+               case BT_VIDEO_CALL:
+                       if(!__bt_hfp_agent_make_video_call(last_number)) {
+                               ERR("Problem launching application \n");
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+                       break;
+               case BT_FOLLOW_CALL_LOG:
+                       if(contacts_record_get_int(record,
+                               _contacts_phone_log.log_type,
+                               &log_type) != CONTACTS_ERROR_NONE) {
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                               break;
+                       }
+                       if (log_type == CONTACTS_PLOG_TYPE_VOICE_OUTGOING) {
+                               if (!__bt_hfp_agent_make_call(last_number)) {
+                                       ERR("Problem launching application \n");
+                                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                               }
+                       }
+                       else if(log_type == CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) {
+                               if(!__bt_hfp_agent_make_video_call(last_number)) {
+                                       ERR("Problem launching application \n");
+                                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                               }
+                       } else {
+                               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       }
+                       break;
+               default:
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       break;
+       }
+
+done:
+       if (list != NULL)
+               contacts_list_destroy(list, TRUE);
+
+       if (filter != NULL)
+               contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       contacts_disconnect2();
+
+       if (last_number != NULL)
+               g_free(last_number);
+
+       if (error_code == BT_HFP_AGENT_ERROR_NONE) {
+               dbus_g_method_return(context);
+               return TRUE;
+       } else {
+               error = __bt_hfp_agent_set_error(error_code);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+}
+
+static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent,
+                               const gchar *number, guint flags,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int error_code;
+       int callapp_type;
+       int phone_lock_state;
+       int condition;
+
+       if (number == NULL) {
+               ERR("Invalid Argument\n");
+               error_code = BT_HFP_AGENT_ERROR_INVALID_PARAM;
+               goto fail;
+       }
+
+       DBG_SECURE("Number = %s \n", number);
+       DBG("flags = %d", flags);
+
+       if (!__bt_is_phone_locked(&phone_lock_state)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (!__bt_get_outgoing_callapp_type(&callapp_type)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (!__bt_get_outgoing_call_condition(&condition)) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (condition == BT_MO_ONLY_UNLOCKED &&
+                       phone_lock_state == VCONFKEY_IDLE_LOCK) {
+               ERR("Call failed. Phone is locked.\n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto fail;
+       }
+
+       if (callapp_type == BT_VIDEO_CALL) {
+               if(!__bt_hfp_agent_make_video_call(number)) {
+                       ERR("Problem launching application \n");
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+       } else {
+               if (!__bt_hfp_agent_make_call(number)) {
+                       ERR("Problem launching application \n");
+                       error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+                       goto fail;
+               }
+       }
+
+       dbus_g_method_return(context);
+       return TRUE;
+fail:
+       error = __bt_hfp_agent_set_error(error_code);
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bt_hfp_agent_dial_memory(BtHfpAgent *agent, gint location,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int error_code = BT_HFP_AGENT_ERROR_NONE;
+       char *number = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_query_h query = NULL;
+       contacts_list_h list = NULL;
+       contacts_record_h record = NULL;
+       unsigned int projections[] = {
+               _contacts_speeddial.number,
+       };
+
+       DBG("location = %d \n", location);
+
+       /*Get number from contacts location*/
+       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
+               ERR(" contacts_connect2 failed \n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       contacts_filter_create(_contacts_speeddial._uri, &filter);
+
+       if (filter == NULL)
+               goto done;
+
+       if (contacts_filter_add_int(filter, _contacts_speeddial.speeddial_number,
+                               CONTACTS_MATCH_EQUAL, location) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       contacts_query_create(_contacts_speeddial._uri, &query);
+
+       if (query == NULL)
+               goto done;
+
+       contacts_query_set_filter(query, filter);
+
+       if (contacts_query_set_projection(query, projections,
+                               sizeof(projections)/sizeof(unsigned int)) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_db_get_records_with_query(query, 0, 1, &list) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_first(list) != CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (contacts_list_get_current_record_p(list, &record) !=
+                               CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (record == NULL)
+               goto done;
+
+       if (contacts_record_get_str(record, _contacts_speeddial.number,
+                                                       &number)!= CONTACTS_ERROR_NONE) {
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+               goto done;
+       }
+
+       if (number == NULL) {
+               ERR("No number at the location \n");
+               error_code = BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX;
+               goto done;
+       }
+
+       DBG_SECURE("number %s\n", number);
+
+       /*Make Voice call*/
+       if (!__bt_hfp_agent_make_call(number)) {
+               ERR("Problem launching application \n");
+               error_code = BT_HFP_AGENT_ERROR_INTERNAL;
+       }
+
+       g_free(number);
+done:
+       if (list != NULL)
+               contacts_list_destroy(list, TRUE);
+
+       if (filter != NULL)
+               contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       contacts_disconnect2();
+
+       if (error_code == BT_HFP_AGENT_ERROR_NONE) {
+               dbus_g_method_return(context);
+               return TRUE;
+       } else {
+               error = __bt_hfp_agent_set_error(error_code);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+}
+
+static gboolean bt_hfp_agent_send_dtmf(BtHfpAgent *agent, const gchar *dtmf,
+                               const gchar *path, const gchar *sender,
+                               DBusGMethodInvocation *context)
+{
+       GError *error;
+       int ret;
+
+       if (dtmf == NULL || path == NULL || sender == NULL) {
+               ERR("Invalid Argument\n");
+               error = __bt_hfp_agent_set_error(
+                                       BT_HFP_AGENT_ERROR_INVALID_PARAM);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       DBG_SECURE("Dtmf = %s \n", dtmf);
+       DBG("Application path = %s \n", path);
+       DBG("Sender = %s\n", sender);
+
+       ret = __bt_hfp_agent_dbus_method_send(sender,
+                               path, TELEPHONY_APP_INTERFACE,
+                               "SendDtmf", FALSE,
+                               DBUS_TYPE_STRING, &dtmf,
+                               DBUS_TYPE_INVALID);
+
+       if (ret != BT_HFP_AGENT_ERROR_NONE) {
+               error = __bt_hfp_agent_set_error(ret);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       /*App Selector code here needed*/
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static void __bt_hfp_agent_launch_voice_dial(gboolean activate)
+{
+       service_h service = NULL;
+
+       service_create(&service);
+
+       if (service == NULL) {
+               ERR("Service create failed");
+               return;
+       }
+
+       service_set_package(service, "org.tizen.svoice");
+       service_set_operation(service, SERVICE_OPERATION_DEFAULT);
+       service_add_extra_data(service, "domain", "bt_headset");
+
+       if (!activate)
+               service_add_extra_data(service, "action_type", "deactivate");
+
+       if (service_send_launch_request(service, NULL, NULL) !=
+                                               SERVICE_ERROR_NONE)
+               ERR("launch failed");
+
+       service_destroy(service);
+       return;
+}
+
+static gboolean bt_hfp_agent_voice_dial(BtHfpAgent *agent, gboolean activate,
+                               DBusGMethodInvocation *context)
+{
+       DBG("Activate = %d \n", activate);
+
+       __bt_hfp_agent_launch_voice_dial(activate);
+       dbus_g_method_return(context);
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_get_battery_status(BtHfpAgent *object,
+                               DBusGMethodInvocation *context)
+{
+       gint battery_chrg_status;
+       gint battery_capacity;
+       GError *error;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
+                                               &battery_chrg_status)) {
+               ERR("VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW failed\n");
+               goto fail;
+       }
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
+                                               &battery_capacity)) {
+               ERR("VCONFKEY_SYSMAN_BATTERY_CAPACITY failed\n");
+               goto fail;
+       }
+
+       DBG("Status:[%d]  Capacity:[%d]\n", battery_chrg_status, battery_capacity);
+
+       dbus_g_method_return(context, battery_chrg_status, battery_capacity);
+       return TRUE;
+
+fail:
+       error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_BATTERY_STATUS);
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bt_hfp_agent_get_signal_quality(BtHfpAgent *object,
+                                       DBusGMethodInvocation *context)
+{
+       gint rssi;
+       GError *error;
+
+       if (vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi)) {
+               ERR("VCONFKEY_TELEPHONY_RSSI failed\n");
+               goto fail;
+       }
+
+       BT_CHECK_SIGNAL_STRENGTH(rssi);
+       DBG("RSSI : %d \n", rssi);
+
+       dbus_g_method_return(context, rssi, BT_SIGNAL_QUALITY_BER);
+       return TRUE;
+fail:
+       error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_SIGNAL_STATUS);
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       return FALSE;
+}
+
+static gboolean bt_hfp_agent_get_operator_name(BtHfpAgent *object,
+                               DBusGMethodInvocation *context)
+{
+       char *operator_name;
+       GError *error;
+
+       operator_name = vconf_get_str(VCONFKEY_TELEPHONY_NWNAME);
+       if (NULL == operator_name) {
+               ERR("vconf_get_str failed \n");
+               error = __bt_hfp_agent_set_error(BT_HFP_AGENT_ERROR_INTERNAL);
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       }
+
+       if (!g_utf8_validate(operator_name, -1, NULL)) {
+               free(operator_name);
+               operator_name = strdup("Unknown");
+       }
+
+       DBG_SECURE("operator_name  = [%s] \n", operator_name);
+
+       dbus_g_method_return(context, operator_name);
+       free(operator_name);
+
+       return TRUE;
+}
+
+static gboolean bt_hfp_agent_nrec_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context)
+{
+       DBusMessage *signal;
+
+       DBG("NREC status = %d \n", status);
+
+       if (status)
+               nrec_status = FALSE;
+       else
+               nrec_status = TRUE;
+
+       dbus_g_method_return(context);
+
+       /*Emit NREC Status change signal with value*/
+       signal = dbus_message_new_signal(BT_HFP_AGENT_OBJECT,
+                                       BT_HFP_AGENT_INTERFACE,
+                                       "NrecStatusChanged");
+       if (!signal) {
+               ERR("Signal is NULL\n");
+               return FALSE;
+       }
+
+       if (!dbus_message_append_args(signal,
+                               DBUS_TYPE_BOOLEAN, &nrec_status,
+                               DBUS_TYPE_INVALID)) {
+               ERR("Signal appending failed\n");
+               dbus_message_unref(signal);
+               return FALSE;
+       }
+
+       dbus_connection_send(gconn, signal, NULL);
+       dbus_message_unref(signal);
+       return TRUE;
+}
+
+static void __bt_hfp_agent_append_variant(DBusMessageIter *iter,
+                       int type, void *val)
+{
+       DBusMessageIter value_iter;
+       const char *variant;
+
+       switch (type) {
+       case DBUS_TYPE_BOOLEAN:
+               variant = DBUS_TYPE_BOOLEAN_AS_STRING;
+               break;
+       case DBUS_TYPE_STRING:
+               variant = DBUS_TYPE_STRING_AS_STRING;
+               break;
+       case DBUS_TYPE_BYTE:
+               variant = DBUS_TYPE_BYTE_AS_STRING;
+               break;
+       case DBUS_TYPE_UINT16:
+               variant = DBUS_TYPE_UINT16_AS_STRING;
+               break;
+       case DBUS_TYPE_UINT32:
+               variant = DBUS_TYPE_UINT32_AS_STRING;
+               break;
+       case DBUS_TYPE_INT16:
+               variant = DBUS_TYPE_INT16_AS_STRING;
+               break;
+       case DBUS_TYPE_INT32:
+               variant = DBUS_TYPE_INT32_AS_STRING;
+               break;
+       case DBUS_TYPE_OBJECT_PATH:
+               variant = DBUS_TYPE_OBJECT_PATH_AS_STRING;
+               break;
+       default:
+               variant = DBUS_TYPE_VARIANT_AS_STRING;
+               break;
+       }
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, variant,
+                                                       &value_iter);
+       dbus_message_iter_append_basic(&value_iter, type, val);
+       dbus_message_iter_close_container(iter, &value_iter);
+}
+
+static gboolean __bt_hfp_agent_dbus_method_variant_send(const char *path,
+               const char *interface, const char *method, const char *name,
+               int type, void *value)
+{
+       DBusMessage *msg;
+       DBusMessage *reply;
+       DBusError err;
+       DBusMessageIter iter;
+
+       msg = dbus_message_new_method_call(BLUEZ_SERVICE_NAME,
+                       path, interface, method);
+
+       if (!msg) {
+               ERR("Unable to allocate new D-Bus %s message", method);
+               return FALSE;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
+
+       __bt_hfp_agent_append_variant(&iter, type, value);
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(gconn,
+                               msg, -1, &err);
+
+       dbus_message_unref(msg);
+
+       if (!reply) {
+               if (dbus_error_is_set(&err)) {
+                       if (err.message != NULL) {
+                               ERR("Error message = %s\n", err.message);
+                       }
+                       dbus_error_free(&err);
+               }
+               return FALSE;
+       }
+
+       dbus_message_unref(reply);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_registration_status_changed(
+               bt_hfp_agent_network_registration_status_t status)
+{
+       const char *property = g_strdup("RegistrationChanged");
+
+       DBG("status = [%d]", status);
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property, DBUS_TYPE_BYTE, &status)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_subscriber_number_changed(
+                                                       const char *number)
+{
+       const char *property = g_strdup("SubscriberNumberChanged");
+
+       DBG_SECURE("number = [%s]", number);
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property,
+                       DBUS_TYPE_STRING, &number)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_signal_bar_changed(int signal_bar)
+{
+       const char *property = g_strdup("SignalBarsChanged");
+
+       DBG("Level = [%d]", signal_bar);
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property, DBUS_TYPE_INT32, &signal_bar)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static gboolean __bt_hfp_agent_send_battery_level_changed(int battery_level)
+{
+       const char *property = g_strdup("BatteryBarsChanged");
+       int battery_status;
+
+       DBG("Level = [%d] \n", battery_level);
+
+       /* We need to send battery status ranging from 0-5 */
+       if (battery_level < 5)
+                battery_status = 0;
+       else if (battery_level >= 100)
+               battery_status = 5;
+       else
+               battery_status = battery_level / 20 + 1;
+
+       if (!__bt_hfp_agent_dbus_method_variant_send(TELEPHONY_CSD_OBJECT_PATH,
+                       TELEPHONY_CSD_INTERFACE,
+                       BT_HFP_AGENT_SET_PROPERTY,
+                       property,
+                       DBUS_TYPE_INT32, &battery_status)) {
+               ERR("__bt_hfp_agent_dbus_method_variant_send failed\n");
+               g_free((void *)property);
+               return FALSE;
+       }
+
+       g_free((void *)property);
+       return TRUE;
+}
+
+static void __bt_hfp_agent_send_battery_level(void)
+{
+       int ret;
+       int batt;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &batt);
+       if (ret != 0) {
+               ERR("vconf_get_int failed err = %d \n", ret);
+               return;
+       }
+
+       __bt_hfp_agent_send_battery_level_changed(batt);
+}
+
+static void __bt_hfp_agent_send_signal_status(void)
+{
+       int ret;
+       int signal_level;
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &signal_level);
+       if (ret != 0) {
+               ERR("vconf_get_int failed err = %d \n", ret);
+               return;
+       }
+
+       BT_CHECK_SIGNAL_STRENGTH(signal_level);
+       __bt_hfp_agent_send_signal_bar_changed(signal_level);
+}
+
+static void __bt_hfp_agent_network_send( int service, int roam_status)
+{
+       int ret;
+       bt_hfp_agent_network_registration_status_t network_service;
+
+       switch (service) {
+       case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
+       case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
+       case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
+               service = 0;
+               break;
+       default:
+               service = 1;
+               break;
+       }
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
+       if (ret != 0) {
+               ERR("Get roaming status failed err = %d\n", ret);
+               return;
+       }
+
+       if (roam_status == 0 && service == 1)
+               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_HOME;
+       else if (roam_status == 1 && service == 1)
+               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_ROAMING;
+       else
+               network_service = BT_HFP_AGENT_NETWORK_REG_STATUS_UNKOWN;
+
+       __bt_hfp_agent_send_registration_status_changed(network_service);
+}
+
+static void __bt_hfp_agent_send_network_status(void)
+{
+       int ret;
+       int roam_status;
+       int service;
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
+       if (ret != 0) {
+               ERR("vconf_get_int failed for \n");
+               return;
+       }
+
+       DBG("roam_status  = [%d] \n", roam_status);
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &service);
+       if (ret != 0) {
+               ERR("vconf_get_int failed\n");
+               return;
+       }
+
+       DBG("service  = [%d] \n", service);
+
+       __bt_hfp_agent_network_send(service, roam_status);
+}
+
+static void __bt_hfp_agent_send_vconf_values(void)
+{
+       __bt_hfp_agent_send_battery_level();
+       __bt_hfp_agent_send_signal_status();
+       __bt_hfp_agent_send_network_status();
+}
+
+static void __bt_hfp_agent_battery_status_cb(keynode_t *node)
+{
+       int batt = vconf_keynode_get_int(node);
+
+       __bt_hfp_agent_send_battery_level_changed(batt);
+}
+
+static void __bt_hfp_agent_network_signal_status_cb(keynode_t *node)
+{
+       int signal_bar = vconf_keynode_get_int(node);
+
+       BT_CHECK_SIGNAL_STRENGTH(signal_bar);
+       __bt_hfp_agent_send_signal_bar_changed(signal_bar);
+}
+
+static void __bt_hfp_agent_network_register_status_cb(keynode_t *node)
+{
+       int service = vconf_keynode_get_int(node);
+       int roam_status;
+       int ret;
+
+       DBG("Current Signal Level = [%d] \n", service);
+
+       ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status);
+       if (ret != 0) {
+               ERR("Get roaming status failed err = %d\n", ret);
+               return;
+       }
+
+       __bt_hfp_agent_network_send(service, roam_status);
+}
+
+static void __bt_hfp_agent_subscribe_vconf_updates(void)
+{
+       int ret;
+
+       DBG("\n");
+
+       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
+                               (void *)__bt_hfp_agent_battery_status_cb, NULL);
+       if (0 != ret) {
+               ERR("Subsrciption to battery status failed err =  [%d]\n", ret);
+       }
+
+       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_RSSI,
+                       (void *)__bt_hfp_agent_network_signal_status_cb, NULL);
+       if (0 != ret) {
+               ERR("Subsrciption to netowrk signal failed err =  [%d]\n", ret);
+       }
+
+       ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
+                       (void *)__bt_hfp_agent_network_register_status_cb, NULL);
+       if (0 != ret) {
+               ERR("Subsrciption to network failed err =  [%d]\n", ret);
+       }
+}
+
+static void __bt_hfp_agent_release_vconf_updates(void)
+{
+       int ret;
+
+       DBG("\n");
+
+       ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
+                       (vconf_callback_fn)__bt_hfp_agent_battery_status_cb);
+       if (0 != ret) {
+               ERR("vconf_ignore_key_changed failed\n");
+       }
+
+       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_RSSI,
+               (vconf_callback_fn)__bt_hfp_agent_network_signal_status_cb);
+       if (0 != ret) {
+               ERR("vconf_ignore_key_changed failed\n");
+       }
+
+       ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SVCTYPE,
+               (vconf_callback_fn)__bt_hfp_agent_network_register_status_cb);
+       if (0 != ret) {
+               ERR("vconf_ignore_key_changed failed\n");
+       }
+}
+
+static gboolean bt_hfp_agent_connection_status(BtHfpAgent *agent, gboolean status,
+                               DBusGMethodInvocation *context)
+{
+       DBG("HF device is %s\n", status ? "Connected" : "Disconnected");
+
+       if (status) {
+               __bt_hfp_agent_send_vconf_values();
+               __bt_hfp_agent_subscribe_vconf_updates();
+       } else {
+               __bt_hfp_agent_release_vconf_updates();
+               nrec_status = FALSE;
+       }
+
+       dbus_g_method_return(context);
+
+       return TRUE;
+}
+
+
+static void __bt_hfp_agent_dbus_init(BtHfpAgent *agent)
+{
+       GError *error = NULL;
+       DBusGProxy *bus_proxy = NULL;
+       guint result;
+
+       g_connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+       if (error != NULL) {
+               ERR("Failed connection to system bus[%s] \n", error->message);
+               g_error_free(error);
+               return;
+       }
+
+       bus_proxy = dbus_g_proxy_new_for_name(g_connection,
+                                       DBUS_SERVICE_DBUS,
+                                       DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+       if (bus_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
+                       BT_HFP_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID,
+                       G_TYPE_UINT, &result, G_TYPE_INVALID)) {
+               if (error != NULL) {
+                       ERR("RequestName RPC failed[%s]\n", error->message);
+                       g_error_free(error);
+               }
+
+               g_object_unref(bus_proxy);
+               return;
+       }
+
+       DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+               ERR("Failed to get the primary well-known name.\n");
+               g_object_unref(bus_proxy);
+               return;
+       }
+
+       g_object_unref(bus_proxy);
+
+       dbus_g_connection_register_g_object(g_connection,
+               BT_HFP_SERVICE_OBJECT_PATH, G_OBJECT(agent));
+
+       gconn = dbus_g_connection_get_connection(g_connection);
+       if (gconn == NULL) {
+               ERR("Failed to get connection \n");
+               return;
+       }
+}
+
+static void  __bt_hfp_agent_tel_cb(TapiHandle *handle,
+                               int result,
+                               void *data,
+                               void *user_data)
+{
+       TelSimMsisdnList_t *number;
+       gchar *subscriber_number;
+
+       if (data == NULL)
+       {
+               ERR("data == NULL \n");
+               return;
+       }
+
+       number = (TelSimMsisdnList_t *)data;
+       subscriber_number = g_strdup(number->list[0].num);
+       __bt_hfp_agent_send_subscriber_number_changed(subscriber_number);
+       g_free(subscriber_number);
+}
+
+static void __bt_hfp_agent_sigterm_handler(int signo)
+{
+       if (gmain_loop) {
+               g_main_loop_quit(gmain_loop);
+       } else {
+               DBG("Terminating HFP agent");
+               exit(0);
+       }
+}
+
+int main(void)
+{
+       TapiHandle *handle;
+       BtHfpAgent *bt_hfp_obj = NULL;
+       struct sigaction sa;
+       int tapi_result;
+
+       DBG("Starting Bluetooth HFP agent");
+
+       g_type_init();
+
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_flags = SA_NOCLDSTOP;
+       sa.sa_handler = __bt_hfp_agent_sigterm_handler;
+       sigaction(SIGTERM, &sa, NULL);
+       sigaction(SIGINT, &sa, NULL);
+
+       gmain_loop = g_main_loop_new(NULL, FALSE);
+
+       if (gmain_loop == NULL) {
+               ERR("GMainLoop create failed \n");
+               return EXIT_FAILURE;
+       }
+
+       bt_hfp_obj = g_object_new(BT_HFP_TYPE_AGENT, NULL);
+
+       handle = tel_init(NULL);
+       tapi_result = tel_get_sim_msisdn(handle, __bt_hfp_agent_tel_cb,
+                                       bt_hfp_obj);
+
+       if(tapi_result != TAPI_API_SUCCESS)
+               ERR("Fail to get sim info: %d", tapi_result);
+
+       __bt_hfp_agent_dbus_init(bt_hfp_obj);
+
+       g_main_loop_run(gmain_loop);
+
+       tel_deinit(handle);
+
+       if (bt_hfp_obj) {
+               dbus_g_connection_unregister_g_object(g_connection,
+                                               G_OBJECT(bt_hfp_obj));
+               g_object_unref(bt_hfp_obj);
+       }
+
+       if (g_connection)
+               dbus_g_connection_unref(g_connection);
+
+       if (gmain_loop)
+               g_main_loop_unref(gmain_loop);
+
+       DBG("Terminating Bluetooth HFP agent");
+       return 0;
+}
diff --git a/wearable/hfp-agent/bluetooth-hfp-agent.h b/wearable/hfp-agent/bluetooth-hfp-agent.h
new file mode 100644 (file)
index 0000000..e77bd15
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Bluetooth-hfp-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:    Hocheol Seo <hocheol.seo@samsung.com>
+ *             Girishashok Joshi <girish.joshi@samsung.com>
+ *             Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_HFP_AGENT_H_
+#define __DEF_BT_HFP_AGENT_H_
+
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+
+#define BT_HFP_AGENT_ERROR (__bt_hfp_agent_error_quark())
+
+typedef enum {
+       BT_HFP_AGENT_NETWORK_REG_STATUS_HOME,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_ROAMING,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_OFFLINE,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_SEARCHING,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_NO_SIM,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_POWEROFF,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_POWERSAFE,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_NO_COVERAGE,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_REJECTED,
+       BT_HFP_AGENT_NETWORK_REG_STATUS_UNKOWN,
+} bt_hfp_agent_network_registration_status_t;
+
+typedef enum {
+       BT_HFP_AGENT_ERROR_INTERNAL,
+       BT_HFP_AGENT_ERROR_NOT_AVAILABLE,
+       BT_HFP_AGENT_ERROR_NOT_CONNECTED,
+       BT_HFP_AGENT_ERROR_BUSY,
+       BT_HFP_AGENT_ERROR_INVALID_PARAM,
+       BT_HFP_AGENT_ERROR_ALREADY_EXSIST,
+       BT_HFP_AGENT_ERROR_ALREADY_CONNECTED,
+       BT_HFP_AGENT_ERROR_NO_MEMORY,
+       BT_HFP_AGENT_ERROR_I_O_ERROR,
+       BT_HFP_AGENT_ERROR_OPERATION_NOT_AVAILABLE,
+       BT_HFP_AGENT_ERROR_NO_CALL_LOGS,
+       BT_HFP_AGENT_ERROR_INVALID_MEMORY_INDEX,
+       BT_HFP_AGENT_ERROR_INVALID_CHLD_INDEX,
+       BT_HFP_AGENT_ERROR_BATTERY_STATUS,
+       BT_HFP_AGENT_ERROR_SIGNAL_STATUS,
+       BT_HFP_AGENT_ERROR_NOT_SUPPORTED,
+       BT_HFP_AGENT_ERROR_INVALID_NUMBER,
+       BT_HFP_AGENT_ERROR_APPLICATION,
+       BT_HFP_AGENT_ERROR_INVALID_DTMF,
+       BT_HFP_AGENT_ERROR_NONE,
+} bt_hfp_agent_error_t;
+
+#define BT_HFP_SERVICE_OBJECT_PATH "/org/bluez/hfp_agent"
+#define BT_HFP_SERVICE "org.bluez.hfp_agent"
+
+#undef LOG_TAG
+#define LOG_TAG "BT_HFP_AGENT"
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+
+#endif /* __DEF_BT_HFP_AGENT_H_ */
diff --git a/wearable/hfp-agent/hfp_agent.xml b/wearable/hfp-agent/hfp_agent.xml
new file mode 100644 (file)
index 0000000..b942156
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="Org.Hfp.App.Interface">
+
+    <method name="RegisterApplication">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+    </method>
+
+    <method name="UnregisterApplication">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+    </method>
+
+    <method name="IncomingCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="number"/>
+      <arg type="i" name="id"/>
+    </method>
+
+    <method name="OutgoingCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="number"/>
+      <arg type="i" name="id"/>
+    </method>
+
+    <method name="ChangeCallStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="path"/>
+      <arg type="i" name="status"/>
+      <arg type="i" name="id"/>
+    </method>
+
+    <method name="GetProperties">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+    </method>
+
+ </interface>
+
+ <interface name="Org.Hfp.Bluez.Interface">
+
+    <method name="AnswerCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+       <arg type="u" name="callid"/>
+       <arg type="s" name="path"/>
+       <arg type="s" name="sender"/>
+    </method>
+
+    <method name="ReleaseCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="u" name="callid"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="RejectCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="u" name="callid"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="ThreewayCall">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="u" name="value"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="DialLastNum">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+    </method>
+
+    <method name="DialNum">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="Number"/>
+      <arg type="u" name="flags"/>
+    </method>
+
+    <method name="DialMemory">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="i" name="location"/>
+    </method>
+
+    <method name="SendDtmf">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="dtmf"/>
+      <arg type="s" name="path"/>
+      <arg type="s" name="sender"/>
+    </method>
+
+    <method name="VoiceDial">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="b" name="activate"/>
+    </method>
+
+    <method name="GetBatteryStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="i" name="bcl" direction="out"/>
+      <arg type="i" name="bcs" direction="out"/>
+    </method>
+
+    <method name="GetSignalQuality">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="i" name="rssi" direction="out"/>
+      <arg type="i" name="ber" direction="out"/>
+    </method>
+
+    <method name="GetOperatorName">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="operator" direction="out"/>
+    </method>
+
+    <method name="NrecStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="b" name="status"/>
+    </method>
+
+    <method name="ConnectionStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="b" name="status"/>
+    </method>
+
+  </interface>
+</node>
diff --git a/wearable/hfp-agent/org.bluez.hfp_agent.service b/wearable/hfp-agent/org.bluez.hfp_agent.service
new file mode 100644 (file)
index 0000000..ec36aa3
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.bluez.hfp_agent
+Exec=/usr/bin/bluetooth-hfp-agent
diff --git a/wearable/map-agent/CMakeLists.txt b/wearable/map-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..84c4aa7
--- /dev/null
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-map-agent C)
+
+SET(SRCS bluetooth_map_agent.c map_bmessage.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_map_agent
+               REQUIRED
+               dbus-glib-1 dlog msg-service tapi vconf)
+
+FOREACH(flag ${pkgs_map_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
+               ARGS "--prefix=bluetooth_map \\
+               ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent.xml \\
+               --mode=glib-server \\
+               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent_glue.h")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_map_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.map_agent.service
+               DESTINATION share/dbus-1/services)
diff --git a/wearable/map-agent/bluetooth_map_agent.c b/wearable/map-agent/bluetooth_map_agent.c
new file mode 100644 (file)
index 0000000..c0fbc2e
--- /dev/null
@@ -0,0 +1,2154 @@
+/*
+ * Bluetooth-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <time.h>
+#include "vconf.h"
+#include "vconf-keys.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+/*Messaging Header Files*/
+#include "msg.h"
+#include "msg_storage.h"
+#include "msg_storage_types.h"
+#include "msg_transport.h"
+#include "msg_transport_types.h"
+#include "msg_types.h"
+
+#include <TelSms.h>
+#include <TapiUtility.h>
+#include <ITapiNetText.h>
+
+#include <bluetooth_map_agent.h>
+
+#include <map_bmessage.h>
+
+#define OBEX_CLIENT_SERVICE "org.openobex.client"
+#define OBEX_CLIENT_INTERFACE "org.openobex.Client"
+#define OBEX_CLIENT_PATH "/"
+#define MNS_CLIENT_INTERFACE "org.openobex.MessageNotification"
+
+#define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", \
+               G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_INVALID))
+
+#define DBUS_STRUCT_MESSAGE_LIST (dbus_g_type_get_struct("GValueArray", \
+               G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_STRING, \
+               G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_STRING, \
+               G_TYPE_STRING, G_TYPE_STRING,   G_TYPE_BOOLEAN, G_TYPE_STRING, \
+               G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
+               G_TYPE_BOOLEAN, G_TYPE_STRING, \
+               G_TYPE_INVALID))
+
+static msg_handle_t g_msg_handle = NULL;
+static TapiHandle *g_tapi_handle = NULL;
+static TelSmsAddressInfo_t *g_sca_info = NULL;
+static DBusGProxy *g_mns_proxy;
+
+#define BT_MAP_NEW_MESSAGE "NewMessage"
+#define BT_MAP_STATUS_CB "sent status callback"
+#define BT_MAP_MSG_CB "sms message callback"
+#define BT_MNS_OBJECT_PATH "/org/bluez/mns"
+#define BT_MNS_INTERFACE "org.bluez.mns"
+#define BT_MAP_SENT_FOLDER_NAME "SENT"
+#define BT_MAP_MSG_TEMPLATE "TEMPLATE"
+#define BT_MAP_DELETED_FOLDER_NAME "DELETED"
+#define BT_MAP_MSG_INFO_MAX 256
+#define BT_MAP_MSG_HANDLE_MAX 21
+#define BT_MAP_TIMESTAMP_MAX_LEN 16
+#define BT_MAP_SUBJECT_MAX_LEN 50
+#define BT_MAP_MSG_BODY_MAX 1024
+#define BT_MSG_UPDATE  0
+#define BT_MSG_DELETE  1
+#define BT_SMS 0
+
+#define BEGIN_BMSEG "BEGIN:BMSG\r\n"
+#define END_BMSEG "END:BMSG\r\n"
+#define BMSEG_VERSION "VERSION:1.0\r\n"
+#define MSEG_STATUS "STATUS:%s\r\n"
+#define MSEG_TYPE "TYPE:%s\r\n"
+#define FOLDER_PATH "FOLDER:%s\r\n"
+#define VCARD "BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s\r\nTEL:%s\r\nEND:VCARD\r\n"
+#define BEGIN_BENV "BEGIN:BENV\r\n"
+#define END_BENV "END:BENV\r\n"
+#define BEGIN_BBODY "BEGIN:BBODY\r\n"
+#define END_BBODY "END:BBODY\r\n"
+#define ENCODING "ENCODING:%s\r\n"
+#define CHARSET "CHARSET:%s\r\n"
+#define LANGUAGE "LANGUAGE:%s\r\n"
+#define LENGTH "LENGTH:%d\r\n"
+#define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n"
+#define MSG_BODY_BEGIN "BEGIN:MSG\r\n"
+#define MSG_BODY_END "\r\nEND:MSG\r\n"
+
+GSList *id_list = NULL;
+guint64 current_push_map_id;
+
+typedef enum {
+       SMS_TON_UNKNOWN = 0,            /* unknown */
+       SMS_TON_INTERNATIONAL = 1,      /* international number */
+       SMS_TON_NATIONAL = 2,           /* national number */
+       SMS_TON_NETWORK_SPECIFIC = 3, /* network specific number */
+       SMS_TON_DEDICATED_ACCESS = 4, /* subscriber number */
+       SMS_TON_ALPHA_NUMERIC = 5,      /* alphanumeric, GSM 7-bit default */
+       SMS_TON_ABBREVIATED_NUMBER = 6, /* abbreviated number */
+       SMS_TON_RESERVED_FOR_EXT = 7 /* reserved for extension */
+} bt_sim_type_of_num_t;
+
+struct id_info {
+       guint64 map_id;
+       int uid;
+};
+
+struct msg_send_option {
+       bool save_copy;
+       bool retry_send;
+       bool native;
+};
+
+struct message_info {
+       char *handle;
+       char *subject;
+       char *datetime;
+       char *sender_name;
+       char *sender_addressing;
+       char *recipient_name;
+       char *recipient_addressing;
+       char *type;
+       char *size;
+       char *reception_status;
+       char *attachment_size;
+       char *replyto_addressing;
+       gboolean text;
+       gboolean priority;
+       gboolean read;
+       gboolean sent;
+       gboolean protect;
+};
+
+typedef struct {
+       GObject parent;
+} BluetoothMapAgent;
+
+typedef struct {
+       GObjectClass parent;
+} BluetoothMapAgentClass;
+
+GType bluetooth_map_agent_get_type(void);
+
+#define BLUETOOTH_MAP_TYPE_AGENT (bluetooth_map_agent_get_type())
+
+#define BLUETOOTH_MAP_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_CAST((object), \
+       BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgent))
+#define BLUETOOTH_MAP_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST((klass), \
+       BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass))
+#define BLUETOOTH_MAP_IS_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+       BLUETOOTH_MAP_TYPE_AGENT))
+#define BLUETOOTH_MAP_IS_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE((klass), \
+       BLUETOOTH_MAP_TYPE_AGENT))
+#define BLUETOOTH_MAP_AGENT_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS((obj), \
+       BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass))
+
+G_DEFINE_TYPE(BluetoothMapAgent, bluetooth_map_agent, G_TYPE_OBJECT)
+
+GMainLoop *g_mainloop = NULL;
+static DBusGConnection *g_connection = NULL;
+static char *g_mns_path = NULL;
+static struct msg_send_option opt;
+
+static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
+                                       gchar *folder_name, guint16 max,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
+                                       gchar *message_name,
+                                       gboolean attach, gboolean transcode,
+                                       gboolean first_request,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
+                                       gboolean save_copy,
+                                       gboolean retry_send,
+                                       gboolean native,
+                                       gchar *folder_name,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
+                                       gchar *bmsg,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
+                                       gchar *handle, gboolean read_status,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
+                                       gchar *handle, gboolean delete_status,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
+                                       gchar *remote_addr,
+                                       gboolean status,
+                                       DBusGMethodInvocation *context);
+static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context);
+
+#include "bluetooth_map_agent_glue.h"
+
+static void bluetooth_map_agent_init(BluetoothMapAgent *obj)
+{
+       DBG("+\n");
+
+       g_assert(obj != NULL);
+}
+
+static void bluetooth_map_agent_finalize(GObject *obj)
+{
+       DBG("+\n");
+
+       G_OBJECT_CLASS(bluetooth_map_agent_parent_class)->finalize(obj);
+}
+
+static void bluetooth_map_agent_class_init(BluetoothMapAgentClass *klass)
+{
+       GObjectClass *object_class = (GObjectClass *) klass;
+
+       g_assert(klass != NULL);
+
+       object_class->finalize = bluetooth_map_agent_finalize;
+
+       dbus_g_object_type_install_info(BLUETOOTH_MAP_TYPE_AGENT,
+                                       &dbus_glib_bluetooth_map_object_info);
+}
+
+static GQuark __bt_map_agent_error_quark(void)
+{
+       static GQuark quark = 0;
+       if (!quark)
+               quark = g_quark_from_static_string("agent");
+
+       return quark;
+}
+
+static GError *__bt_map_agent_error(bt_map_agent_error_t error,
+                                    const char *err_msg)
+{
+       return g_error_new(BT_MAP_AGENT_ERROR, error, err_msg, NULL);
+}
+
+static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
+                                       gchar *folder, gchar *old_folder,
+                                       gchar *msg_type);
+
+static char *__bt_get_truncated_utf8_string(char *src)
+{
+       char *p = src;
+       char *next;
+       char dest[BT_MAP_SUBJECT_MAX_LEN] = {0,};
+       int count;
+       int i = 0;
+
+       if (src == NULL)
+               return FALSE;
+
+       while (*p != '\0' && i < sizeof(dest)) {
+               next = g_utf8_next_char(p);
+               count = next - p;
+
+               while (count > 0 && ((i + count) < sizeof(dest))) {
+                       dest[i++] = *p;
+                       p++;
+                       count --;
+               }
+               p = next;
+       }
+
+       return g_strdup(dest);
+}
+
+static guint64 __bt_validate_uid(int uid)
+{
+       DBG("Validate uid");
+       struct id_info *info;
+       int count;
+       int i;
+
+       count = g_slist_length(id_list);
+       for (i = 0; i < count; i++) {
+               info = (struct id_info *)g_slist_nth_data(id_list, i);
+               if (!info)
+                       break;
+
+               if (info->uid == uid) {
+                       DBG("uid = %d\n", uid);
+                       return info->map_id;
+               }
+       }
+
+       return 0;
+}
+
+static guint64 __bt_add_id(int uid)
+{
+       DBG("Add id: %d\n", uid);
+       static guint64 map_id;
+       struct id_info *info;
+       guint64 test;
+
+       test = __bt_validate_uid(uid);
+       DBG("test: %llx\n", test);
+       if (test)
+               return test;
+
+       info = g_new0(struct id_info, 1);
+
+       map_id++;
+
+       info->map_id = map_id;
+       info->uid = uid;
+       DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid);
+
+       id_list = g_slist_append(id_list, info);
+
+       return map_id;
+}
+
+static int __bt_get_id(guint64 map_id)
+{
+       DBG("get id\n");
+       struct id_info *info;
+       int count;
+       int i;
+
+       count = g_slist_length(id_list);
+
+       for (i = 0; i < count; i++) {
+               info = (struct id_info *)g_slist_nth_data(id_list, i);
+
+               if (info->map_id == map_id)
+                       return info->uid;
+       }
+
+       return -1;
+}
+
+static int __bt_get_uid(gchar *handle)
+{
+       guint64 map_id;
+       int uid;
+
+       if (NULL == handle)
+               return -1;
+
+       map_id = g_ascii_strtoull(handle, NULL, 16);
+       if (!map_id)
+               return -1;
+
+       uid = __bt_get_id(map_id);
+
+       return uid;
+}
+
+static int __bt_update_id(guint64 map_id, int new_uid)
+{
+       DBG("update id\n");
+       struct id_info *info;
+       int i;
+       int count;
+
+       count = g_slist_length(id_list);
+
+       for (i = 0; i < count; i++) {
+               info = g_slist_nth_data(id_list, i);
+
+               if (info->map_id == map_id) {
+                       info->uid = new_uid;
+                       return map_id;
+               }
+       }
+
+       return -1;
+}
+
+static void __bt_remove_list(GSList *id_list)
+{
+       if (!id_list)
+               return;
+
+       DBG("Removing id list\n");
+       g_slist_free_full(id_list, g_free);
+}
+
+static int __bt_get_folder_id(char *folder_path)
+{
+       int folder_id = -1;
+       int i;
+       char *folder;
+       msg_struct_list_s folder_list = {0,};
+       msg_error_t err;
+       msg_struct_t p_folder;
+       DBG_SECURE("folder_path %s\n", folder_path);
+
+       folder = strrchr(folder_path, '/');
+       if (NULL == folder)
+               folder = folder_path;
+       else
+               folder++;
+
+       err = msg_get_folder_list(g_msg_handle, &folder_list);
+       if (err != MSG_SUCCESS)
+               goto done;
+
+       for (i = 0; i < folder_list.nCount; i++) {
+               char folder_name[BT_MAP_MSG_INFO_MAX] = {0, };
+
+               p_folder = folder_list.msg_struct_info[i];
+
+               err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       folder_name, BT_MAP_MSG_INFO_MAX);
+               if (err != MSG_SUCCESS)
+                       continue;
+
+               DBG_SECURE("folder_name %s\n", folder_name);
+               if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) {
+                       err = msg_get_int_value(p_folder,
+                                       MSG_FOLDER_INFO_ID_INT,
+                                       &folder_id);
+                       if (err != MSG_SUCCESS)
+                               goto done;
+
+                       DBG("folder_id %d", folder_id);
+                       break;
+               }
+       }
+
+done:
+       if (folder_list.msg_struct_info)
+               msg_release_list_struct(&folder_list);
+
+       return folder_id;
+
+}
+
+static void __bt_add_deleted_folder(void)
+{
+       msg_error_t err;
+       msg_struct_t folder_info = msg_create_struct(MSG_STRUCT_FOLDER_INFO);
+
+       err = msg_set_int_value(folder_info, MSG_FOLDER_INFO_TYPE_INT,
+                                               MSG_FOLDER_TYPE_USER_DEF);
+       if (err != MSG_SUCCESS) {
+               ERR("Failed adding type %d", err);
+               msg_release_struct(&folder_info);
+               return;
+       }
+
+       err = msg_set_str_value(folder_info, MSG_FOLDER_INFO_NAME_STR,
+                                       "DELETED", MAX_FOLDER_NAME_SIZE);
+       if (err != MSG_SUCCESS) {
+               ERR("Failed adding str %d", err);
+               msg_release_struct(&folder_info);
+               return;
+       }
+
+       err = msg_add_folder(g_msg_handle, folder_info);
+       if (err != MSG_SUCCESS) {
+               ERR("Failed adding folder %d", err);
+               msg_release_struct(&folder_info);
+               return;
+       }
+
+       msg_release_struct(&folder_info);
+
+       return;
+}
+
+static gchar *__bt_get_folder_name(int id)
+{
+       int ret;
+       int i;
+       int folder_id;
+       gboolean path_found = FALSE;
+       char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
+
+       msg_struct_list_s folder_list = {0,};
+       msg_struct_t p_folder;
+
+       ret = msg_get_folder_list(g_msg_handle, &folder_list);
+       if (ret != MSG_SUCCESS)
+               return g_strdup("TELECOM/MSG");
+
+       if (folder_list.msg_struct_info == NULL)
+               return g_strdup("TELECOM/MSG");
+
+       for (i = 0; i < folder_list.nCount; i++) {
+               p_folder = folder_list.msg_struct_info[i];
+
+               ret = msg_get_int_value(p_folder,
+                                       MSG_FOLDER_INFO_ID_INT,
+                                       &folder_id);
+               if (ret != MSG_SUCCESS)
+                       break;
+               DBG("folder_id %d, id = %d", folder_id, id);
+               if (folder_id == id) {
+                       ret = msg_get_str_value(p_folder,
+                                       MSG_FOLDER_INFO_NAME_STR,
+                                       folder_name, BT_MAP_MSG_INFO_MAX);
+                       if (ret != MSG_SUCCESS)
+                               break;
+
+                       path_found = TRUE;
+                       DBG_SECURE("folder_name %s", folder_name);
+                       break;
+               }
+       }
+
+       if (folder_list.msg_struct_info) {
+               ret = msg_release_list_struct(&folder_list);
+               ERR("Err %d", ret);
+       }
+
+       if (path_found != TRUE)
+               return g_strdup("TELECOM/MSG");
+       else
+               return g_strdup_printf("TELECOM/MSG/%s", folder_name);
+}
+
+static void __get_msg_timestamp(time_t *ltime, char *timestamp)
+{
+       struct tm local_time;
+       int year;
+       int month;
+
+       if (!localtime_r(ltime, &local_time))
+               return;
+
+       year = local_time.tm_year + 1900; /* years since 1900 */
+       month = local_time.tm_mon + 1; /* months since January */
+       snprintf(timestamp, 16, "%04d%02d%02dT%02d%02d%02d", year, month,
+                                       local_time.tm_mday, local_time.tm_hour,
+                                       local_time.tm_min, local_time.tm_sec);
+
+       return;
+}
+
+#define SET_TON_NPI(dest, ton, npi) {  \
+       dest = 0x80;                    \
+       dest |= (ton & 0x07) << 4;      \
+       dest |= npi & 0x0F;             \
+}
+
+static int __bt_ascii_to_upper(int ch)
+{
+       return (('a' <= (ch) && (ch) <= 'z') ? ((ch) - ('a'-'A')) : (ch));
+}
+
+static int __bt_sms_pack_gsm_code(gchar *p_out, const char *data, int in_len)
+{
+       DBG("+");
+       int i;
+       int pos;
+       int shift = 0;
+
+       for (pos = 0, i = 0; i < in_len; pos++, i++) {
+               /* pack the low bits */
+               p_out[pos] = data[i] >> shift;
+
+               if (i + 1 < in_len) {
+                       /* pack the high bits using the low bits
+                          of the next character */
+                       p_out[pos] |= data[i+1] << (7 - shift);
+
+                       shift++;
+
+                       if (shift == 7) {
+                               shift = 0;
+                               i++;
+                       }
+               }
+       }
+       DBG("-");
+       return pos;
+}
+
+static void __bt_sms_conv_digit_to_bcd(gchar *p_bcd, char *p_digits, int digit_len)
+{
+       int i;
+       int j;
+       int digit;
+       unsigned char higher;
+       unsigned char lower;
+
+       if (p_bcd == NULL || p_digits == NULL)
+               return;
+
+       /* 0123456789 -> 1032547698 */
+       for (i = 0, j = 0; i < digit_len; i = i + 2, j++) {
+               if (p_digits[i] == '*')
+                       digit = 0x0A;
+               else if (p_digits[i] == '#')
+                       digit = 0x0B;
+               else if (__bt_ascii_to_upper(p_digits[i]) == 'P')
+                       digit = 0x0C;
+               else
+                       digit = (int) (p_digits[i] - '0');
+
+               lower = digit & 0x0F;
+
+               if (digit_len != i + 1) {
+                       if (p_digits[i+1] == '*')
+                               digit = 0x0A;
+                       else if (p_digits[i+1] == '#')
+                               digit = 0x0B;
+                       else if (__bt_ascii_to_upper(p_digits[i+1]) == 'P')
+                               digit = 0x0C;
+                       else
+                               digit = (int) (p_digits[i+1] - '0');
+
+                       higher = digit & 0x0F;
+               } else {
+                       higher = 0xFF;
+               }
+
+               p_bcd[j] = (higher << 4) | lower;
+       }
+}
+
+static int  __bt_sms_encode_addr(gchar *addr_field, char *dial_num,
+                               int dial_num_len, int ton, int npi)
+{
+       DBG("+");
+       int index = 0;
+
+       if (dial_num == NULL || addr_field == NULL)
+               return -1;
+
+       if (dial_num[0] == '+') {
+               dial_num++;
+               dial_num_len--;
+               ton = SMS_TON_INTERNATIONAL;
+       }
+
+       if (ton != SMS_TON_ALPHA_NUMERIC) {
+               /* Origination address length address length */
+               addr_field[index++] = (unsigned char)dial_num_len;
+       } else {
+               addr_field[index] = (unsigned char)
+                                       (((dial_num_len * 7 + 7) / 8) * 2);
+
+               if (((dial_num_len * 7) % 8) <= 4)
+                       addr_field[index]--;
+
+               index++;
+       }
+
+       SET_TON_NPI(addr_field[index], ton, npi);
+       index++; /* SET_TON_NPI */
+
+       if (ton != SMS_TON_ALPHA_NUMERIC) {
+               __bt_sms_conv_digit_to_bcd(&addr_field[index],
+                                       (char *)dial_num, dial_num_len);
+
+               if (dial_num_len % 2)
+                       index += (dial_num_len / 2) + 1;
+               else
+                       index += dial_num_len / 2;
+       } else {
+               index += __bt_sms_pack_gsm_code(&addr_field[index],
+                                               dial_num, (int)dial_num_len);
+       }
+
+       return index;
+}
+
+static int __bt_sms_encode_time(gchar *addr_field, time_t *tm)
+{
+       int index = 0;
+       struct tm ltime;
+       int year;
+       int month;
+
+       if (!localtime_r(tm, &ltime))
+               return index;
+
+       year = ltime.tm_year + 1900; /* years since 1900 */
+       year = year % 100;
+       month = ltime.tm_mon + 1; /* months since January */
+
+       addr_field[index++] = ((year % 10)  << 4) + (year / 10);
+       addr_field[index++] = ((month % 10) << 4) + (month / 10);
+       addr_field[index++] = ((ltime.tm_mday % 10) << 4) +
+                                                       (ltime.tm_mday / 10);
+       addr_field[index++] = ((ltime.tm_hour % 10) << 4) +
+                                                       (ltime.tm_hour / 10);
+       addr_field[index++] = ((ltime.tm_min % 10) << 4) + (ltime.tm_min / 10);
+       addr_field[index++] = ((ltime.tm_sec % 10) << 4) + (ltime.tm_sec / 10);
+       addr_field[index] = 0x00;
+
+       return index;
+}
+
+static gchar *__bt_get_sms_pdu_from_msg_data(gchar *number,
+                                               char *msg, time_t tm,
+                                               int *msg_pdu_len)
+{
+       DBG("+");
+       gchar packet[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,};
+       int index = 0;
+
+       packet[index] = 0x00; /* Since SCA is unknown for stored messages */
+       index++;
+
+       /* TP-MTI : Type of message */
+       packet[index] = 0x00;   /* SMS-DELIVER PDU */
+
+       /* TP-MMS bit is set to 1 as we support only SMS */
+       packet[index] |= 0x04;
+       index++;
+
+       /* TP-OA : Mobile originating address */
+       index += __bt_sms_encode_addr(packet+index,
+                                       number, strlen(number),
+                                       g_sca_info->Ton, g_sca_info->Npi);
+
+       /* TP-PID : Since we use only SMS so set to 0 */
+       packet[index++] = 0x00;
+
+       /* TP-DCS : Data Coding Scheme, default value set */
+       packet[index++] = 0x00;
+
+       /* TP-SCTS : Message timestamp */
+       index += __bt_sms_encode_time(packet+index, &tm);
+       index++;
+       /* TP-UDL : Message body length */
+       packet[index++] = strlen(msg);
+
+       /* TP-UD : Message body */
+       index += __bt_sms_pack_gsm_code(packet + index, msg, strlen(msg));
+
+       *msg_pdu_len = index;
+       DBG("-");
+
+       return g_memdup(packet, index);
+}
+
+static void __bt_get_sms_sca(TapiHandle *handle, int result, void *data,
+                                                       void *user_data)
+{
+       TelSmsAddressInfo_t *scaInfo = data;
+
+       DBG("__bt_get_sms_sca 0x%x", result);
+
+       if (data == NULL)
+               return;
+
+       g_sca_info = g_malloc0(sizeof(TelSmsAddressInfo_t));
+       g_sca_info->Ton = scaInfo->Ton;
+       g_sca_info->Npi = scaInfo->Npi;
+       g_sca_info->DialNumLen = scaInfo->DialNumLen;
+}
+
+static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
+                                                       gboolean transcode)
+{
+       int ret;
+       int m_type = MSG_TYPE_SMS;
+       int folder_id;
+       int count;
+       int dptime = 0;
+       int j;
+       bool read_status = false;
+       char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
+       char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
+       char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
+
+       msg_list_handle_t addr_list = NULL;
+       msg_struct_t addr_info = NULL;
+
+       GString *msg;
+       gchar *folder_path;
+       gchar *msg_pdu;
+
+       msg = g_string_new(BEGIN_BMSEG);
+       g_string_append(msg, BMSEG_VERSION);
+
+       ret = msg_get_bool_value(msg_info, MSG_MESSAGE_READ_BOOL, &read_status);
+       if (ret == MSG_SUCCESS) {
+               DBG("read_status %d\n", read_status);
+       }
+
+       if (read_status)
+               g_string_append_printf(msg, MSEG_STATUS, "READ");
+       else
+               g_string_append_printf(msg, MSEG_STATUS, "UNREAD");
+
+       ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type);
+       if (ret == MSG_SUCCESS) {
+               DBG("m_type %d\n", m_type);
+                g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM");
+       }
+
+       ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
+                                                       &folder_id);
+       if (ret == MSG_SUCCESS) {
+               DBG("folder_id %d\n", folder_id);
+
+               folder_path = __bt_get_folder_name(folder_id);
+               g_string_append_printf(msg, FOLDER_PATH, folder_path);
+       }
+
+       ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_HND,
+                                               (void **)&addr_list);
+       if (ret == MSG_SUCCESS) {
+               count = msg_list_length(addr_list);
+               DBG("count %d \n", count);
+
+               if (count > 0) {
+                       addr_info = (msg_struct_t)msg_list_nth_data(addr_list,
+                                                                       0);
+
+                       msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                                       addr_value, MAX_ADDRESS_VAL_LEN);
+                       DBG_SECURE("addr_value %s\n", addr_value);
+                       msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_DISPLAYNAME_STR,
+                                       name_value, MAX_DISPLAY_NAME_LEN);
+                       if (!strlen(name_value))
+                               g_stpcpy(name_value, addr_value);
+
+                       DBG_SECURE("name_value %s\n", name_value);
+
+                       g_string_append_printf(msg, VCARD, name_value,
+                                                               addr_value);
+               }
+       }
+
+       g_string_append(msg, BEGIN_BENV);
+       g_string_append(msg, BEGIN_BBODY);
+
+       if (transcode) {
+               g_string_append_printf(msg, CHARSET, "UTF-8");
+
+
+               ret = msg_get_str_value(msg_info,
+                                       MSG_MESSAGE_SMS_DATA_STR,
+                                       msg_body, BT_MAP_MSG_BODY_MAX);
+               if (ret == MSG_SUCCESS) {
+                       g_string_append_printf(msg, LENGTH, strlen(msg_body));
+                       g_string_append_printf(msg, MSG_BODY, msg_body);
+               }
+       } else {
+               g_string_append_printf(msg, ENCODING, "G-7BIT");
+               g_string_append_printf(msg, CHARSET, "native");
+
+               msg_get_int_value(msg_info,
+                               MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
+
+               ret = msg_get_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
+                                       msg_body, BT_MAP_MSG_BODY_MAX);
+               if (ret == MSG_SUCCESS) {
+                       int msg_pdu_len = 0;
+                       msg_pdu = __bt_get_sms_pdu_from_msg_data(addr_value,
+                                                       msg_body, dptime,
+                                                       &msg_pdu_len);
+                       DBG("msg_pdu_len = %d", msg_pdu_len);
+
+                       g_string_append_printf(msg, LENGTH, msg_pdu_len);
+                       g_string_append(msg, MSG_BODY_BEGIN);
+                       for (j = 0; j < msg_pdu_len; j++)
+                               g_string_append_printf(msg, "%02x",
+                                                               msg_pdu[j]);
+
+                       g_string_append(msg, MSG_BODY_END);
+                       g_free(msg_pdu);
+               }
+       }
+
+       g_string_append(msg, END_BBODY);
+       g_string_append(msg, END_BENV);
+       g_string_append(msg, END_BMSEG);
+
+       return g_string_free(msg, FALSE);
+}
+
+static void __bt_message_info_free(struct message_info msg_info)
+{
+       g_free(msg_info.handle);
+       g_free(msg_info.subject);
+       g_free(msg_info.datetime);
+       g_free(msg_info.sender_name);
+       g_free(msg_info.sender_addressing);
+       g_free(msg_info.replyto_addressing);
+       g_free(msg_info.recipient_name);
+       g_free(msg_info.recipient_addressing);
+       g_free(msg_info.type);
+       g_free(msg_info.reception_status);
+       g_free(msg_info.size);
+       g_free(msg_info.attachment_size);
+}
+
+static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
+{
+       struct message_info msg_info = {0,};
+       int ret;
+       int msg_id;
+       guint64 uid;
+       int dptime;
+       int m_type = 0;
+       int data_size;
+       int priority;
+       int direction_type;
+       int count;
+       bool protect_status = 0;
+       bool read_status = 0;
+
+       char msg_handle[BT_MAP_MSG_HANDLE_MAX] = {0,};
+       char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,};
+       char msg_size[5] = {0,};
+       char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
+       char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
+       char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
+
+       msg_info.text = FALSE;
+       msg_info.protect = FALSE;
+       msg_info.read = FALSE;
+       msg_info.priority = FALSE;
+
+       msg_struct_t msg = NULL;
+       msg_struct_t send_opt = NULL;
+       msg_list_handle_t addr_list = NULL;
+       msg_struct_t addr_info = NULL;
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id);
+       if (ret == MSG_SUCCESS) {
+               uid = __bt_add_id(msg_id);
+               snprintf(msg_handle, sizeof(msg_handle), "%llx", uid);
+       }
+       msg_info.handle = g_strdup(msg_handle);
+
+       msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+
+       ret = msg_get_message(g_msg_handle,
+                                               (msg_message_id_t)msg_id,
+                                               msg, send_opt);
+       if (ret != MSG_SUCCESS) {
+               DBG("ret = %d\n", ret);
+               goto next;
+       }
+
+       ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_HND,
+                                                       (void **)&addr_list);
+       if (ret != MSG_SUCCESS) {
+               DBG("ret = %d\n", ret);
+               goto next;
+       }
+
+       count = msg_list_length(addr_list);
+
+       if (count != 0) {
+               addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0);
+
+               ret = msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                                       addr_value, MAX_ADDRESS_VAL_LEN);
+               if (ret == MSG_SUCCESS)
+                       DBG_SECURE("addr_value %s\n", addr_value);
+
+               ret = msg_get_str_value(addr_info,
+                                       MSG_ADDRESS_INFO_DISPLAYNAME_STR,
+                                       name_value, MAX_DISPLAY_NAME_LEN);
+
+               if (ret == MSG_SUCCESS)
+                       DBG_SECURE("name_value %s\n", name_value);
+
+               if (!strlen(name_value))
+                       g_stpcpy(name_value, addr_value);
+
+               DBG_SECURE("name_value %s\n", name_value);
+       }
+
+       ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT,
+                                               &direction_type);
+       if (ret != MSG_SUCCESS)
+               goto next;
+
+       if (direction_type == MSG_DIRECTION_TYPE_MT) {
+               msg_info.sender_name = g_strdup(name_value);
+               msg_info.sender_addressing = g_strdup(addr_value);
+               msg_info.recipient_name = g_strdup("Unknown");
+               msg_info.recipient_addressing = g_strdup("0000");
+       } else {
+               msg_info.sender_name = g_strdup("Unknown");
+               msg_info.sender_addressing = g_strdup("0000");
+               msg_info.recipient_name = g_strdup(name_value);
+               msg_info.recipient_addressing = g_strdup(addr_value);
+       }
+
+next:
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
+
+       ret = msg_get_int_value(msg_struct_handle,
+                               MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
+       if (ret == MSG_SUCCESS) {
+               __get_msg_timestamp((time_t *)&dptime, msg_datetime);
+       }
+       msg_info.datetime = g_strdup(msg_datetime);
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT,
+                                                               &m_type);
+       if (ret == MSG_SUCCESS) {
+               DBG("m_type %d\n", m_type);
+       }
+
+       msg_info.type = g_strdup("SMS_GSM");
+
+       ret = msg_get_str_value(msg_struct_handle,
+                               MSG_MESSAGE_SMS_DATA_STR, msg_body,
+                               BT_MAP_MSG_BODY_MAX);
+       if (ret == MSG_SUCCESS) {
+               DBG_SECURE("SMS subject %s", msg_body);
+               if (strlen(msg_body)) {
+                       msg_info.text = TRUE ;
+                       msg_info.subject = __bt_get_truncated_utf8_string(msg_body);
+               }
+       }
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT,
+                                                               &data_size);
+       if (ret == MSG_SUCCESS)
+               snprintf(msg_size, sizeof(msg_size), "%d", data_size);
+
+       msg_info.size = g_strdup(msg_size);
+
+       msg_info.reception_status = g_strdup("complete");
+       msg_info.attachment_size = g_strdup("0");
+
+       ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL,
+                                                       &protect_status);
+       if (ret == MSG_SUCCESS) {
+               if (protect_status)
+                       msg_info.protect = TRUE;
+       }
+
+       ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL,
+                                                               &read_status);
+       if (ret == MSG_SUCCESS) {
+               if (read_status)
+                       msg_info.read = TRUE;
+       }
+
+       ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT,
+                                                               &priority);
+       if (ret == MSG_SUCCESS) {
+               if (priority == MSG_MESSAGE_PRIORITY_HIGH)
+                       msg_info.priority = TRUE;
+       }
+
+       return msg_info;
+}
+
+static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle,
+                                                       msg_struct_t msg,
+                                                       void *user_param)
+{
+       int msg_id = 0;
+       int msg_type = 0;
+       int ret;
+
+       guint64 uid;
+
+       DBG("+\n");
+
+       if (!g_mns_proxy) {
+               DBG("MNS Client not connected");
+               return;
+       }
+
+       ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type);
+       if (ret != MSG_SUCCESS)
+               return;
+
+       if (msg_type != MSG_TYPE_SMS) {
+               DBG("Not a SMS");
+               return;
+       }
+
+       ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
+       if (ret != MSG_SUCCESS)
+               return;;
+
+       uid = __bt_add_id(msg_id);
+
+       __bt_mns_client_event_notify("NewMessage", uid,
+                                               "TELECOM/MSG/INBOX", "",
+                                               "SMS_GSM");
+
+       return;
+}
+
+static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle,
+                                                       msg_struct_t msg,
+                                                       void *user_param)
+{
+       int ret;
+       int status;
+
+       DBG("+\n");
+
+       if (!g_mns_proxy) {
+               DBG("MNS Client not connected");
+               return;
+       }
+
+       ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT,
+                                                               &status);
+       if (ret != MSG_SUCCESS)
+               return;
+
+       if (status == MSG_NETWORK_SEND_SUCCESS) {
+               DBG("MSG SENT SUCCESS !!! ");
+               __bt_mns_client_event_notify("MessageShift",
+                                       current_push_map_id,
+                                       "TELECOM/MSG/SENT",
+                                       "TELECOM/MSG/OUTBOX",
+                                       "SMS_GSM");
+
+               __bt_mns_client_event_notify("SendingSuccess",
+                                       current_push_map_id,
+                                       "TELECOM/MSG/SENT", "",
+                                       "SMS_GSM");
+       } else {
+               DBG("MSG SENT FAIL !!! [%d]", status);
+               __bt_mns_client_event_notify("SendingFailure",
+                                       current_push_map_id,
+                                       "TELECOM/MSG/OUTBOX", "",
+                                       "SMS_GSM");
+       }
+
+       return;
+}
+
+static gboolean __bluetooth_map_start_service()
+{
+       msg_error_t err;
+
+       err = msg_open_msg_handle(&g_msg_handle);
+       if (err != MSG_SUCCESS) {
+               ERR("msg_open_msg_handle error = %d\n", err);
+               return FALSE;
+       }
+
+       if (-1 == __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME))
+               __bt_add_deleted_folder();
+
+       err = msg_reg_sms_message_callback(g_msg_handle,
+                                       __bluetooth_map_msg_incoming_status_cb,
+                                       0, (void *)BT_MAP_MSG_CB);
+       if (err != MSG_SUCCESS) {
+               ERR("msg_reg_sms_message_callback error  = %d\n", err);
+               return FALSE;
+       }
+
+       err = msg_reg_sent_status_callback(g_msg_handle,
+                                       __bluetooth_map_msg_sent_status_cb,
+                                       NULL);
+       if (err != MSG_SUCCESS) {
+               ERR("msg_reg_sent_status_callback error  = %d\n", err);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void __bluetooth_map_stop_service()
+{
+       msg_error_t err =  MSG_SUCCESS;
+       int folder_id;
+
+       folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
+       if (-1 != folder_id) {
+               err = msg_delete_folder(g_msg_handle, folder_id);
+               if (err != MSG_SUCCESS)
+                       ERR("Delete folder failed");
+       }
+
+       if (NULL != g_msg_handle)
+               msg_close_msg_handle(&g_msg_handle);
+
+       g_msg_handle = NULL;
+
+       return;
+}
+
+static gboolean __bt_validate_utf8(char **text)
+{
+       DBG("+\n");
+       if (g_utf8_validate(*text, -1, NULL))
+               return TRUE;
+
+       DBG("-\n");
+       return FALSE;
+}
+
+static gboolean __bt_validate_msg_data(struct message_info *msg_info)
+{
+       if (msg_info == NULL)
+               return FALSE;
+
+       if (msg_info->subject)
+               return __bt_validate_utf8(&msg_info->subject);
+
+       if (msg_info->sender_name)
+               return __bt_validate_utf8(&msg_info->sender_name);
+
+       if (msg_info->sender_addressing)
+               return __bt_validate_utf8(&msg_info->sender_addressing);
+
+       if (msg_info->replyto_addressing)
+               return __bt_validate_utf8(&msg_info->replyto_addressing);
+
+       if (msg_info->recipient_name)
+               return __bt_validate_utf8(&msg_info->recipient_name);
+
+       if (msg_info->recipient_addressing)
+               return __bt_validate_utf8(&msg_info->recipient_addressing);
+
+       return TRUE;
+}
+
+msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt)
+{
+       msg_error_t err;
+       msg_struct_t p_req;
+
+       p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
+
+       msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id);
+       msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg);
+       msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt);
+
+       err = msg_sms_send_message(g_msg_handle, p_req);
+       if (err != MSG_SUCCESS)
+               ERR("Failed msg_sms_send_message %d", err);
+
+       msg_release_struct(&p_req);
+       return err;
+}
+
+static int __bt_push_sms(gboolean send, int folder_id, char *body,
+                                                       GSList *recepients)
+{
+       DBG("+ \n");
+       msg_struct_t msg_info = NULL;
+       msg_struct_t send_opt = NULL;
+       msg_error_t err;
+
+       int count = 0;
+       int i = 0;
+       int msg_id = -1;
+
+       msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       if (msg_info == NULL)
+               goto fail;
+
+       err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       if (body) {
+               err = msg_set_str_value(msg_info,
+                                       MSG_MESSAGE_SMS_DATA_STR,
+                                       body, strlen(body));
+               if (err != MSG_SUCCESS)
+                       goto fail;
+       } else {
+               err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
+                                                               NULL, 0);
+               if (err != MSG_SUCCESS)
+                       goto fail;
+       }
+
+       DBG("folder_id  %d\n", folder_id);
+       err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
+                                                               folder_id);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       if (recepients) {
+               count = g_slist_length(recepients);
+               DBG("Count = %d\n", count);
+
+               for (i = 0; i < count; i++) {
+                       msg_struct_t tmp_addr;
+                       char *address = (char *)g_slist_nth_data(recepients, i);
+                       if (address == NULL) {
+                               DBG("[ERROR] address is value NULL, skip");
+                               continue;
+                       }
+                       msg_list_add_item(msg_info,
+                               MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr);
+
+                       msg_set_int_value(tmp_addr,
+                               MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
+                               MSG_RECIPIENTS_TYPE_TO);
+
+                       msg_set_str_value(tmp_addr,
+                               MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
+                               address, strlen(address));
+               }
+       }
+
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+
+       err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       /* Do not keep a copy */
+       err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL,
+                                                       opt.save_copy);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       msg_id = msg_add_message(g_msg_handle, msg_info, send_opt);
+       DBG("msg_id = %d\n", msg_id);
+
+       if (send == TRUE)
+               __bt_send_sms(msg_id, msg_info, send_opt);
+
+
+fail:
+       msg_release_struct(&msg_info);
+       msg_release_struct(&send_opt);
+       DBG("-\n");
+       return msg_id;
+}
+
+static void __bt_mns_client_connect(char *address)
+{
+       GHashTable *hash;
+       GValue *addr_value;
+       GValue *tgt_value;
+       GError *error = NULL;
+       const char *session_path = NULL;
+
+       if (g_mns_proxy) {
+               DBG_SECURE("MNS Client already connected to %s", address);
+               return;
+       }
+
+       g_mns_proxy = dbus_g_proxy_new_for_name(g_connection,
+                                               OBEX_CLIENT_SERVICE,
+                                               OBEX_CLIENT_PATH,
+                                               OBEX_CLIENT_INTERFACE);
+       if (!g_mns_proxy) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                    NULL, (GDestroyNotify)g_free);
+
+       addr_value = g_new0(GValue, 1);
+       g_value_init(addr_value, G_TYPE_STRING);
+       g_value_set_string(addr_value, address);
+       g_hash_table_insert(hash, "Destination", addr_value);
+
+       tgt_value = g_new0(GValue, 1);
+       g_value_init(tgt_value, G_TYPE_STRING);
+       g_value_set_string(tgt_value, "MNS");
+       g_hash_table_insert(hash, "Target", tgt_value);
+
+       dbus_g_proxy_call(g_mns_proxy, "CreateSession", &error,
+               dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+               hash, G_TYPE_INVALID,
+               DBUS_TYPE_G_OBJECT_PATH, &session_path,
+               G_TYPE_INVALID);
+       if (error) {
+               ERR("Error [%s]", error->message);
+               g_error_free(error);
+               g_hash_table_destroy(hash);
+               g_object_unref(g_mns_proxy);
+               g_mns_proxy = NULL;
+               return;
+       }
+
+       g_mns_path = g_strdup(session_path);
+       DBG("g_mns_path = %s\n", g_mns_path);
+
+       g_hash_table_destroy(hash);
+
+       DBG("-\n");
+       return;
+}
+
+static void __bt_mns_client_disconnect()
+{
+       GError *error = NULL;
+
+       if (!g_mns_proxy) {
+               ERR("No proxy to disconnect");
+               return;
+       }
+
+       dbus_g_proxy_call(g_mns_proxy, "RemoveSession", &error,
+               DBUS_TYPE_G_OBJECT_PATH, g_mns_path,
+               G_TYPE_INVALID, G_TYPE_INVALID);
+       if (error) {
+               ERR("Error [%s]", error->message);
+               g_error_free(error);
+       }
+
+       g_free(g_mns_path);
+       g_mns_path = NULL;
+
+       g_object_unref(g_mns_proxy);
+       g_mns_proxy = NULL;
+
+       DBG("-\n");
+       return;
+}
+
+static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
+                                       gchar *folder, gchar *old_folder,
+                                       gchar *msg_type)
+{
+       DBG("+\n");
+       GError *error = NULL;
+       DBusGProxy *mns_proxy;
+
+       if (!g_mns_proxy) {
+               ERR("No client proxy");
+               return;
+       }
+
+       mns_proxy = dbus_g_proxy_new_for_name(g_connection,
+                                               OBEX_CLIENT_SERVICE,
+                                               g_mns_path,
+                                               MNS_CLIENT_INTERFACE);
+       if (mns_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       dbus_g_proxy_call(mns_proxy, "SendEvent", &error,
+               G_TYPE_STRING, event,
+               G_TYPE_UINT64, handle,
+               G_TYPE_STRING, folder,
+               G_TYPE_STRING, old_folder,
+               G_TYPE_STRING, msg_type,
+               G_TYPE_INVALID, G_TYPE_INVALID);
+       if (error) {
+               DBG("Error [%s]", error->message);
+               g_error_free(error);
+       }
+
+       DBG("-\n");
+       g_object_unref(mns_proxy);
+       return;
+}
+
+static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
+                                               DBusGMethodInvocation *context)
+{
+       GPtrArray *array = g_ptr_array_new();
+       GValue value;
+       GError *error = NULL;
+
+       char name[BT_MAP_MSG_INFO_MAX] = {0,};
+       char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
+       int i;
+       int ret;
+       gboolean msg_ret = TRUE;
+
+       msg_struct_list_s folder_list = {0,};
+       msg_struct_t p_folder;
+
+       if (g_msg_handle == NULL) {
+               msg_ret = FALSE;
+               goto done;
+       }
+
+       if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) {
+               msg_ret = FALSE;
+               goto done;
+       }
+
+       for (i = 0; i < folder_list.nCount; i++) {
+               p_folder = folder_list.msg_struct_info[i];
+               memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
+
+               ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       folder_name, BT_MAP_MSG_INFO_MAX);
+               if (ret != MSG_SUCCESS)
+                       continue;
+
+               if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE))
+                       continue;
+
+               if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME,
+                                       strlen(BT_MAP_SENT_FOLDER_NAME))) {
+                       memset(folder_name, 0, sizeof(folder_name));
+                       g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME,
+                                                       sizeof(folder_name));
+               }
+
+               g_strlcpy(name, folder_name, sizeof(name));
+               memset(&value, 0, sizeof(GValue));
+               g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
+               g_value_take_boxed(&value, dbus_g_type_specialized_construct(
+                                       DBUS_STRUCT_STRING_STRING_UINT));
+               dbus_g_type_struct_set(&value, 0, name, G_MAXUINT);
+               g_ptr_array_add(array, g_value_get_boxed(&value));
+       }
+
+done:
+
+       if (folder_list.msg_struct_info)
+               msg_release_list_struct(&folder_list);
+
+       if (msg_ret == FALSE) {
+               g_ptr_array_free(array, TRUE);
+
+               error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                               "InternalError");
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               return FALSE;
+       } else {
+               dbus_g_method_return(context, array);
+               g_ptr_array_free(array, TRUE);
+               return TRUE;
+       }
+}
+
+static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
+                                               gchar *folder_name, guint16 max,
+                                               DBusGMethodInvocation *context)
+{
+       GPtrArray *array = g_ptr_array_new();
+       GValue value;
+       GError *error = NULL;
+
+       char *folder = NULL;
+       int i = 0;
+       int ret = 0;
+       int folder_id = -1;
+       int folder_len;
+       bool read;
+       guint64 count = 0;
+       gboolean newmsg = FALSE;
+
+       msg_struct_list_s folder_list = {0,};
+       msg_struct_list_s msg_list = {0,};
+       msg_struct_t list_cond;
+
+       DBG("+");
+
+       if (g_msg_handle == NULL)
+               goto fail;
+
+       if (!folder_name)
+               goto fail;
+
+       folder_len = strlen(folder_name);
+       /* In case of parent folders send empty message listing */
+       if (!g_ascii_strncasecmp(folder_name, "/", folder_len) ||
+               !g_ascii_strncasecmp(folder_name, "/telecom", folder_len) ||
+               !g_ascii_strncasecmp(folder_name, "/telecom/msg", folder_len))
+               goto done;
+
+       folder = strrchr(folder_name, '/');
+       if (NULL == folder)
+               folder = folder_name;
+       else
+               folder++;
+
+       ret = msg_get_folder_list(g_msg_handle, &folder_list);
+       if (ret != MSG_SUCCESS)
+               goto fail;
+
+       for (i = 0; i < folder_list.nCount; i++) {
+               char f_name[BT_MAP_MSG_INFO_MAX] = {0, };
+               msg_struct_t p_folder = folder_list.msg_struct_info[i];
+
+               ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
+                                       f_name, BT_MAP_MSG_INFO_MAX);
+               if (ret  != MSG_SUCCESS)
+                       continue;
+
+               if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) {
+                       ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
+                                                               &folder_id);
+                       if (ret != MSG_SUCCESS)
+                               goto fail;
+
+                       DBG("folder_id %d \n", folder_id);
+
+                       break;
+               }
+       }
+
+       if (folder_id == -1)
+               goto fail;
+
+       list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION);
+       ret = msg_set_int_value(list_cond,
+                               MSG_LIST_CONDITION_FOLDER_ID_INT,
+                               folder_id);
+       if (ret != MSG_SUCCESS)
+               goto fail;
+
+       ret = msg_set_int_value(list_cond,
+                               MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS);
+       if (ret != MSG_SUCCESS)
+               goto fail;
+
+       ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list);
+
+       msg_release_struct(&list_cond);
+
+       if (ret != MSG_SUCCESS)
+               goto fail;
+
+       count = msg_list.nCount;
+
+       for (i = 0; i < count; i++) {
+               msg_get_bool_value(msg_list.msg_struct_info[i],
+                                       MSG_MESSAGE_READ_BOOL, &read);
+               if (read == false) {
+                       newmsg = TRUE;
+                       break;
+               }
+       }
+
+       DBG("count = %llx, newmsg = %d, max = %d", count, newmsg, max);
+
+       if (max == 0)
+               goto done;
+
+       for (i = 0; i < msg_list.nCount; i++) {
+
+               struct message_info msg_info;
+
+               memset(&value, 0, sizeof(GValue));
+               g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST);
+               g_value_take_boxed(&value, dbus_g_type_specialized_construct(
+                                               DBUS_STRUCT_MESSAGE_LIST));
+
+               msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]);
+
+               if (!__bt_validate_msg_data(&msg_info)) {
+                       __bt_message_info_free(msg_info);
+                       count--;
+                       continue;
+               }
+
+               dbus_g_type_struct_set(&value, 0, msg_info.handle,
+                                       1, msg_info.subject,
+                                       2, msg_info.datetime,
+                                       3, msg_info.sender_name,
+                                       4, msg_info.sender_addressing,
+                                       5, msg_info.recipient_name,
+                                       6, msg_info.recipient_addressing,
+                                       7, msg_info.type,
+                                       8, msg_info.size,
+                                       9, msg_info.reception_status,
+                                       10, msg_info.text,
+                                       11, msg_info.attachment_size,
+                                       12, msg_info.priority,
+                                       13, msg_info.read,
+                                       14, msg_info.sent,
+                                       15, msg_info.protect,
+                                       16, msg_info.replyto_addressing,
+                                       G_MAXUINT);
+               g_ptr_array_add(array, g_value_get_boxed(&value));
+
+               __bt_message_info_free(msg_info);
+       }
+
+done:
+       if (folder_list.msg_struct_info)
+               ret = msg_release_list_struct(&folder_list);
+
+       if (msg_list.msg_struct_info)
+               ret = msg_release_list_struct(&msg_list);
+
+       dbus_g_method_return(context, newmsg, count, array);
+       g_ptr_array_free(array, TRUE);
+       DBG("-");
+       return TRUE;
+
+fail:
+       if (folder_list.msg_struct_info)
+               ret = msg_release_list_struct(&folder_list);
+
+       if (msg_list.msg_struct_info)
+               ret = msg_release_list_struct(&msg_list);
+
+       g_ptr_array_free(array, TRUE);
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                         "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       DBG("fail -");
+       return FALSE;
+}
+
+static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
+                                               gchar *message_name,
+                                               gboolean attach,
+                                               gboolean transcode,
+                                               gboolean first_request,
+                                               DBusGMethodInvocation *context)
+{
+       DBG("+ \n");
+       char *buf = NULL;
+       int message_id = 0;
+
+       GError *error = NULL;
+
+       msg_error_t msg_err;
+       msg_struct_t msg = NULL;
+       msg_struct_t send_opt = NULL;
+
+       message_id = __bt_get_uid(message_name);
+       if (message_id == -1)
+               goto fail;
+
+       DBG("message_id %d \n", message_id);
+       DBG("attach %d \n", attach);
+       DBG("transcode %d \n", transcode);
+       DBG("first_request %d \n", first_request);
+
+       if (g_msg_handle == NULL)
+               goto fail;
+
+       msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       if (!msg)
+               goto fail;
+
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+       if (!send_opt)
+               goto fail;
+
+       msg_err = msg_get_message(g_msg_handle,
+                                       (msg_message_id_t)message_id,
+                                       msg, send_opt);
+       if (msg_err != MSG_SUCCESS)
+               goto fail;
+
+       buf = __bt_prepare_msg_bmseg(msg, attach, transcode);
+
+       dbus_g_method_return(context, FALSE, buf);
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
+       g_free(buf);
+
+       DBG("- \n");
+       return TRUE;
+
+fail:
+
+       if (msg)
+               msg_release_struct(&msg);
+
+       if (send_opt)
+               msg_release_struct(&send_opt);
+
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       DBG("fail - \n");
+       return FALSE;
+}
+
+static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
+                                       gboolean save_copy,
+                                       gboolean retry_send,
+                                       gboolean native,
+                                       gchar *folder_name,
+                                       DBusGMethodInvocation *context)
+{
+       DBG("+\n");
+       guint64 handle = 0;
+
+       DBG_SECURE("folder_name = %s\n", folder_name);
+
+       handle = __bt_add_id(-1);
+       current_push_map_id = handle;
+
+       /* FALSE : Keep messages in Sent folder */
+       /* TRUE : don't keep messages in sent folder */
+       opt.save_copy = save_copy;
+       DBG("opt.save_copy = %d\n", opt.save_copy);
+
+       /* FALSE : don't retry */
+       /* TRUE  : retry */
+       opt.retry_send = retry_send;
+       DBG("opt.retry_send = %d\n", opt.retry_send);
+
+       /* FALSE : native */
+       /* TRUE : UTF-8 */
+       opt.native = native;
+       DBG("opt.native = %d\n", opt.native);
+
+       dbus_g_method_return(context, handle);
+       DBG("-\n");
+       return TRUE;
+}
+
+static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
+                                       gchar *bmsg,
+                                       DBusGMethodInvocation *context)
+{
+       DBG("+\n");
+       int id = -1;
+       int folder_id;
+       char *body = NULL;
+       GSList *recepients = NULL;
+       gboolean send = FALSE;
+
+       GError *error = NULL;
+
+       DBG("BMSG is \n %s", bmsg);
+
+       struct bmsg_data *bmsg_info = NULL;
+
+       bmsg_info = bmsg_parse(bmsg);
+       if (!bmsg_info)
+               goto done;
+
+       folder_id = __bt_get_folder_id(bmsg_info->folder);
+       if (folder_id == -1)
+               goto done;
+
+       if (MSG_OUTBOX_ID == folder_id)
+               send = TRUE;
+
+       body = bmsg_get_msg_body(bmsg_info, opt.native);
+       if (body == NULL)
+               goto done;
+
+       recepients = bmsg_get_msg_recepients(bmsg_info);
+
+       id = __bt_push_sms(send, folder_id, body, recepients);
+       if (id == -1)
+               goto done;
+
+       __bt_update_id(current_push_map_id, id);
+
+done:
+       g_free(body);
+       g_slist_free(recepients);
+       bmsg_free_bmsg(bmsg_info);
+
+       if (id == -1) {
+               error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+               dbus_g_method_return_error(context, error);
+               g_error_free(error);
+               DBG("-\n");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context);
+       DBG("-\n");
+       return TRUE;
+}
+
+static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
+                                               DBusGMethodInvocation *context)
+{
+       int err = TRUE;
+
+       dbus_g_method_return(context, err);
+       return TRUE;
+}
+
+static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
+                                               gchar *handle,
+                                               gboolean read_status,
+                                               DBusGMethodInvocation *context)
+{
+       int msg_id;
+       GError *error = NULL;
+       msg_error_t msg_err;
+
+       DBG("+\n");
+
+       msg_id = __bt_get_uid(handle);
+       if (msg_id == -1)
+               goto fail;
+
+       DBG("msg_id = %d,  read_status = %d\n", msg_id, read_status);
+
+       msg_err = msg_update_read_status(g_msg_handle, msg_id,
+                                                       read_status);
+       if (msg_err != MSG_SUCCESS)
+               goto fail;
+
+       dbus_g_method_return(context);
+       DBG("-\n");
+       return TRUE;
+
+fail:
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+
+       ERR("fail -\n");
+       return FALSE;
+}
+
+static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
+                                               gchar *handle,
+                                               gboolean delete_status,
+                                               DBusGMethodInvocation *context)
+{
+       int msg_id = 0;
+       int folder_id;
+       int del_folder_id;
+       gchar *folder_name = NULL;
+       guint64 map_id;
+       GError *error = NULL;
+       msg_error_t err;
+       msg_struct_t msg = NULL;
+       msg_struct_t send_opt = NULL;
+
+       DBG("+\n");
+
+       msg_id = __bt_get_uid(handle);
+       if (msg_id == -1)
+               goto fail;
+
+       if (g_msg_handle == NULL)
+               goto fail;
+
+       msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
+       send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
+
+       err = msg_get_message(g_msg_handle,
+                                       (msg_message_id_t)msg_id,
+                                       msg, send_opt);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT,
+                                                       &folder_id);
+       if (err != MSG_SUCCESS)
+               goto fail;
+
+       folder_name = __bt_get_folder_name(folder_id);
+       del_folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
+       map_id = __bt_validate_uid(msg_id);
+
+       DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status);
+
+       if (-1 == del_folder_id) {
+               ERR("Delete folder not present");
+               if (delete_status == TRUE) {
+                       err = msg_delete_message(g_msg_handle, msg_id);
+                       if (err != MSG_SUCCESS)
+                               goto fail;
+               }
+
+       } else {
+               if (delete_status == TRUE) {
+                       err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id);
+                       if (err == MSG_SUCCESS) {
+                               __bt_mns_client_event_notify("MessageShift",
+                                               map_id,
+                                               "TELECOM/MSG/DELETED",
+                                               folder_name,
+                                               "SMS_GSM");
+                       }
+               } else {
+                       if (folder_id != del_folder_id) {
+                               DBG("Message not in delete folder");
+                               goto fail;
+                       }
+
+                       err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID);
+                       if (err == MSG_SUCCESS) {
+                               __bt_mns_client_event_notify("MessageShift",
+                                               map_id,
+                                               "TELECOM/MSG/INBOX",
+                                               "TELECOM/MSG/DELETED",
+                                               "SMS_GSM");
+                       }
+               }
+       }
+
+       g_free(folder_name);
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
+       dbus_g_method_return(context);
+       DBG("-\n");
+       return TRUE;
+
+fail:
+       g_free(folder_name);
+       msg_release_struct(&msg);
+       msg_release_struct(&send_opt);
+
+       error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
+                                                       "InternalError");
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+       ERR("fail -\n");
+       return FALSE;
+}
+
+static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
+                                               gchar *remote_addr,
+                                               gboolean status,
+                                               DBusGMethodInvocation *context)
+{
+       DBG_SECURE("remote_addr = %s \n", remote_addr);
+
+       if (status == TRUE)
+               __bt_mns_client_connect(remote_addr);
+       else
+               __bt_mns_client_disconnect();
+
+       return TRUE;
+}
+
+static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
+                                       DBusGMethodInvocation *context)
+{
+       DBG("MAP agent terminate request received");
+       g_main_loop_quit(g_mainloop);
+       return TRUE;
+}
+
+int main(void)
+{
+       BluetoothMapAgent *bluetooth_map_obj = NULL;
+       DBusGProxy *bus_proxy = NULL;
+       guint result = 0;
+       int ret;
+       GError *error = NULL;
+       DBG("Starting Bluetooth MAP agent");
+
+       g_type_init();
+
+       g_mainloop = g_main_loop_new(NULL, FALSE);
+
+       if (g_mainloop == NULL) {
+               ERR("Couldn't create GMainLoop\n");
+               return EXIT_FAILURE;
+       }
+
+       g_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+
+       if (error != NULL) {
+               ERR("Couldn't connect to system bus[%s]\n", error->message);
+               g_error_free(error);
+               return EXIT_FAILURE;
+       }
+
+       bus_proxy = dbus_g_proxy_new_for_name(g_connection, DBUS_SERVICE_DBUS,
+                                               DBUS_PATH_DBUS,
+                                               DBUS_INTERFACE_DBUS);
+       if (bus_proxy == NULL) {
+               ERR("Failed to get a proxy for D-Bus\n");
+               goto failure;
+       }
+
+       if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
+                                       BT_MAP_SERVICE_NAME, G_TYPE_UINT, 0,
+                                       G_TYPE_INVALID, G_TYPE_UINT, &result,
+                                       G_TYPE_INVALID)) {
+               if (error != NULL) {
+                       ERR("RequestName RPC failed[%s]\n", error->message);
+                       g_error_free(error);
+               }
+               goto failure;
+       }
+
+       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+               ERR("Failed to get the primary well-known name.\n");
+               goto failure;
+       }
+
+       g_object_unref(bus_proxy);
+       bus_proxy = NULL;
+
+       bluetooth_map_obj = g_object_new(BLUETOOTH_MAP_TYPE_AGENT, NULL);
+
+       /* Registering it on the D-Bus */
+       dbus_g_connection_register_g_object(g_connection,
+                                               BT_MAP_SERVICE_OBJECT_PATH,
+                                               G_OBJECT(bluetooth_map_obj));
+
+       if (__bluetooth_map_start_service() == FALSE)
+               goto failure;
+
+       g_tapi_handle = tel_init(NULL);
+       if (!g_tapi_handle)
+               goto failure;
+
+       ret = tel_get_sms_sca(g_tapi_handle, 0, __bt_get_sms_sca, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               ERR("TAPI err = %d", ret);
+               goto failure;
+       }
+
+       g_main_loop_run(g_mainloop);
+
+ failure:
+
+       __bt_remove_list(id_list);
+
+       tel_deinit(g_tapi_handle);
+       g_free(g_sca_info);
+
+       __bt_mns_client_disconnect();
+
+       if (bus_proxy)
+               g_object_unref(bus_proxy);
+       if (bluetooth_map_obj)
+               g_object_unref(bluetooth_map_obj);
+       if (g_connection)
+               dbus_g_connection_unref(g_connection);
+
+       __bluetooth_map_stop_service();
+       DBG("Bluetooth MAP agent Terminated successfully\n");
+       return EXIT_FAILURE;
+}
diff --git a/wearable/map-agent/bluetooth_map_agent.h b/wearable/map-agent/bluetooth_map_agent.h
new file mode 100644 (file)
index 0000000..1e99a35
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Bluetooth-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_PB_AGENT_H_
+#define __DEF_BT_PB_AGENT_H_
+
+#include <unistd.h>
+#include <dlog.h>
+
+#include <stdio.h>
+
+#include <dbus/dbus-glib.h>
+
+#define BT_MAP_AGENT_ERROR (__bt_map_agent_error_quark())
+
+typedef enum {
+       BT_MAP_AGENT_ERROR_INTERNAL,
+       BT_MAP_AGENT_ERROR_CANCEL,
+} bt_map_agent_error_t;
+
+#define BT_MAP_SERVICE_OBJECT_PATH "/org/bluez/map_agent"
+#define BT_MAP_SERVICE_NAME "org.bluez.map_agent"
+#define BT_MAP_SERVICE_INTERFACE "org.bluez.MapAgent"
+
+#undef LOG_TAG
+#define LOG_TAG "BT_MAP_AGENT"
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+#ifdef _SECURE_LOG
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+#else /* _SECURE_LOG */
+#define DBG_SECURE(...) (0)
+#define ERR_SECURE(...) (0)
+#endif /* _SECURE_LOG */
+
+
+#endif /* __DEF_BT_AGENT_H_ */
diff --git a/wearable/map-agent/bluetooth_map_agent.xml b/wearable/map-agent/bluetooth_map_agent.xml
new file mode 100644 (file)
index 0000000..977418b
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<node name="/">
+       <interface name="org.bluez.MapAgent">
+               <method name="GetFolderTree">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="a(s)" name="folder_list" direction="out"/>
+               </method>
+               <method name="GetMessageList">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="folder_name"/>
+                       <arg type="q" name="max"/>
+                       <arg type="b" name="newmessage" direction="out"/>
+                       <arg type="t" name="count" direction="out"/>
+                       <arg type="a(ssssssssssbsbbbbs)" name="msg_list" direction="out"/>
+               </method>
+               <method name="GetMessage">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="messgae_name"/>
+                       <arg type="b" name="attach"/>
+                       <arg type="b" name="transcode"/>
+                       <arg type="b" name="first_request"/>
+                       <arg type="b" name="fraction_deliver" direction="out"/>
+                       <arg type="s" name="msg_body" direction="out"/>
+               </method>
+               <method name="PushMessage">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="b" name="save_copy"/>
+                       <arg type="b" name="retry_send"/>
+                       <arg type="b" name="native"/>
+                       <arg type="s" name="folder_name"/>
+                       <arg type="t" name="handle" direction="out"/>
+               </method>
+               <method name="PushMessageData">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="bmsg"/>
+               </method>
+               <method name="UpdateMessage">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+               <method name="SetReadStatus">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="handle"/>
+                       <arg type="b" name="read_status"/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+               <method name="SetDeleteStatus">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="handle"/>
+                       <arg type="b" name="delete_status"/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+               <method name="NotiRegistration">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="remote_addr"/>
+                       <arg type="b" name="status"/>
+                       <arg type="u" name="update_err" direction="out"/>
+               </method>
+               <method name="DestroyAgent">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+               </method>
+       </interface>
+</node>
diff --git a/wearable/map-agent/map_bmessage.c b/wearable/map-agent/map_bmessage.c
new file mode 100644 (file)
index 0000000..9fde2cc
--- /dev/null
@@ -0,0 +1,689 @@
+/*
+ * Bluetooth-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include <ITapiNetText.h>
+
+#include <map_bmessage.h>
+#include <bluetooth_map_agent.h>
+
+#define CRLF_LEN 2
+#define BT_SMS_DATA_MAX_LEN 165
+
+#define BMSG_TAG "BEGIN:BMSG\r\n"
+#define VER_TAG "VERSION:"
+#define STATUS_TAG "STATUS:"
+#define TYPE_TAG "TYPE:"
+#define FOLDER_TAG "FOLDER:"
+#define VCARD_BEGIN_TAG "BEGIN:VCARD\r\n"
+#define VCARD_END_TAG "END:VCARD\r\n"
+#define VCARD_N_TAG "N:"
+#define VCARD_FN_TAG "FN:"
+#define VCARD_TEL_TAG "TEL:"
+#define VCARD_EMAIL_TAG "EMAIL:"
+#define BENV_TAG "BEGIN:BENV\r\n"
+#define BBODY_TAG "BEGIN:BBODY\r\n"
+#define MSG_TAG "BEGIN:MSG\r\n"
+#define PARTID_TAG "PARTID:"
+#define ENCODING_TAG "ENCODING:"
+#define CHARSET_TAG "CHARSET:"
+#define LANGUAGE_TAG "LANGUAGE:"
+#define LENGTH_TAG "LENGTH:"
+
+static guint8 g_enc_lvl = 1;
+
+void print_bmsg(struct bmsg_data *bmsg)
+{
+       if (bmsg == NULL)
+               return;
+
+       struct benv_data *env_data = NULL;
+
+       DBG("bmsg->version = %s", bmsg->version);
+       DBG("bmsg->status = %s", bmsg->status);
+       DBG("bmsg->type = %s", bmsg->type);
+       DBG_SECURE("bmsg->folder = %s", bmsg->folder);
+
+       if (bmsg->originator_vcard_data) {
+               DBG_SECURE("bmsg->originator_vcard_data->version = %s",
+                                               bmsg->originator_vcard_data->version);
+               DBG_SECURE("bmsg->originator_vcard_data->n = %s",
+                                               bmsg->originator_vcard_data->n);
+       }
+
+       int i = 0;
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       while (env_data != NULL) {
+
+               DBG("env_data = %d", env_data->encapsulation_level);
+               int k = 0;
+               struct bmsg_vcard *rvcard;
+
+               rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+
+               while (rvcard != NULL) {
+                       k++;
+
+                       if (rvcard->version != NULL)
+                               DBG("vcard->version = %s\n", rvcard->version);
+                       if (rvcard->n != NULL)
+                               DBG_SECURE("vcard->n = %s\n", rvcard->n);
+                       if (rvcard->fn != NULL)
+                               DBG_SECURE("vcard->fn = %s\n", rvcard->fn);
+                       if (rvcard->tel != NULL)
+                               DBG_SECURE("vcard->tel = %s\n", rvcard->tel);
+                       if (rvcard->email != NULL)
+                               DBG("vcard->email = %s\n", rvcard->email);
+
+                       rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               }
+
+               if (env_data->body_content != NULL) {
+                       DBG_SECURE("env_data->body_content->length = %"
+                                               G_GUINT64_FORMAT "\n",
+                                               env_data->body_content->length);
+                       DBG_SECURE("env_data->body_content->msg = %s\n",
+                                               env_data->body_content->msg);
+               }
+
+               i++;
+
+               if (i > 2)
+                       break;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+}
+
+static gchar *__bt_unpack_gsm7bit_msg(const char* pdu, int in_len)
+{
+       int i;
+       int pos = 0;
+       int shift = 0;
+       gchar data[BT_SMS_DATA_MAX_LEN + 1] = {0,};
+
+       for (i = 0; i < in_len; i++) {
+               if (shift == 0) {
+                       data[i] = pdu[pos] & 0x7F;
+
+                       shift = 7;
+                       pos++;
+               } else {
+                       data[i] = (pdu[pos - 1] >> shift) |
+                                               (pdu[pos] << (8 - shift));
+                       data[i] &= 0x7F;
+
+                       shift--;
+                       if (shift > 0)
+                               pos++;
+               }
+       }
+
+       DBG_SECURE("msg = %s\n", data);
+       return g_strdup(data);
+}
+
+static gchar *__bt_get_msg_body_from_pdu(gchar *pdu, guint64 pdu_len)
+{
+       int index = 0;
+       int i;
+       int j = 0;
+       int dcs;
+       int udh = 0;
+       int coding_scheme;
+       int phone_num_len = 0;
+       char temp[3];
+       char msg_data[BT_SMS_DATA_MAX_LEN + 1] = {0,};
+       unsigned char pdu_data[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,};
+
+       for (i = 0; i < (pdu_len - 1);) {
+               snprintf(temp, sizeof(temp), "%c%c", pdu[i], pdu[i+1]);
+
+               pdu_data[j] = g_ascii_strtoull(temp, NULL, 16);
+               DBG("pdu_data = %02x\n", pdu_data[j]);
+               j++;
+               i = i + 2;
+       }
+
+       DBG("pdu[%d] = %x\n", index, pdu_data[index]);
+       if (pdu[index] == 0x00)
+               index++;
+       else
+               index = index + pdu_data[index];
+
+       /* TP-MTI */
+       index = index + 1;
+
+       if (pdu_data[index] & 0x40)
+               udh = 1;
+
+       DBG("udh = %d", udh);
+
+       /* TP-MR */
+       index = index + 1;
+
+       /* phone number length */
+       index = index + 1;
+       DBG("pdu[%d] = %x\n", index, pdu_data[index]);
+
+       if ((pdu_data[index] % 2) == 0)
+               phone_num_len = pdu_data[index] / 2;
+       else
+               phone_num_len = pdu_data[index] / 2 + 1;
+
+       DBG("phone_num_len [%d]\n", phone_num_len);
+
+       /* phone number type */
+       index = index + 1;
+
+       /* phone_num_len/2 encoded phone num length */
+       index = index + phone_num_len;
+
+       /* TP-PID */
+       index = index + 1;
+
+       /* TP-DCS */
+       index = index + 1;
+
+       dcs = pdu_data[index];
+       coding_scheme = (dcs & 0x0C) >> 2;
+       DBG("coding_scheme = %d\n", coding_scheme);
+
+       /* TP-VP */
+       index = index + 1;
+
+       /* TP-UDL */
+       index = index + 1;
+       int udl = pdu_data[index];
+       DBG("udl = %x\n", udl);
+
+       /* message body */
+       index = index + 1;
+
+       memcpy(msg_data, (void*)&pdu_data[index], udl);
+
+       return __bt_unpack_gsm7bit_msg(msg_data, udl);
+}
+
+static gchar *__bt_get_valid_number(gchar* num)
+{
+       int len;
+       int i;
+       int j;
+       gchar *valid_num;
+
+       if (!num)
+               return NULL;
+
+       len = strlen(num);
+
+       valid_num = g_malloc0(len + 1);
+
+       for (i = 0, j = 0; i < len; i++) {
+
+               if (num[i] != '-') {
+                       valid_num[j] = num[i];
+                       j++;
+               }
+       }
+
+       valid_num[j] = '\0';
+
+       return valid_num;
+}
+
+char *bmsg_get_msg_folder(struct bmsg_data *bmsg)
+{
+       return g_strdup(bmsg->folder);
+}
+
+char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf)
+{
+       DBG("+");
+       struct benv_data *env_data;
+       int i = 0;
+
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+
+       while (env_data != NULL) {
+               if (env_data->body_content != NULL) {
+                       DBG_SECURE("env_data->body_content->msg = %s\n",
+                                               env_data->body_content->msg);
+                       DBG_SECURE("env_data->body_content->length = %"
+                                               G_GUINT64_FORMAT "\n",
+                                               env_data->body_content->length);
+
+                       if (utf == FALSE) {
+                               return __bt_get_msg_body_from_pdu(
+                                               env_data->body_content->msg,
+                                               env_data->body_content->length);
+                       } else {
+                               return g_strndup(
+                                               env_data->body_content->msg,
+                                               env_data->body_content->length);
+                       }
+               }
+
+               i++;
+               if (i > 2)
+                       break;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+
+       DBG("-");
+       return NULL;
+}
+
+GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg)
+{
+       DBG("+");
+       struct benv_data *env_data;
+       GSList *receiver = NULL;
+       int i = 0;
+
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+
+       while (env_data != NULL) {
+
+               DBG("env_data = %d", env_data->encapsulation_level);
+               int k = 0;
+               struct bmsg_vcard *rvcard;
+
+               rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               while (rvcard != NULL) {
+                       k++;
+
+                       if (rvcard->tel != NULL) {
+                               DBG_SECURE("vcard->tel = %s\n", rvcard->tel);
+                               receiver = g_slist_append(receiver,
+                                                               rvcard->tel);
+                       }
+
+                       rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               }
+
+               i++;
+               if (i > 2)
+                       break;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+       DBG("-");
+       return receiver;
+}
+
+void bmsg_free_vcard_data(struct bmsg_vcard *vcard_data)
+{
+       DBG("+");
+       if (vcard_data == NULL)
+               return;
+
+       g_free(vcard_data->version);
+       g_free(vcard_data->n);
+       g_free(vcard_data->fn);
+       g_free(vcard_data->tel);
+       g_free(vcard_data->email);
+       g_free(vcard_data);
+       DBG("-");
+       return;
+}
+
+void bmsg_free_bmsg(struct bmsg_data *bmsg)
+{
+       DBG("+");
+       struct benv_data *env_data;
+       int i = 0;
+
+       if (bmsg == NULL)
+               return;
+
+       g_free(bmsg->version);
+       g_free(bmsg->status);
+       g_free(bmsg->type);
+       g_free(bmsg->folder);
+       bmsg_free_vcard_data(bmsg->originator_vcard_data);
+
+       if (bmsg->envelope_data == NULL)
+               goto done;
+
+       if (bmsg->envelope_data->env_data == NULL)
+               goto done;
+
+       env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       while (env_data != NULL) {
+
+               DBG("env_data = %d", env_data->encapsulation_level);
+               int k = 0;
+               struct bmsg_vcard *rvcard;
+
+               rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+
+               while (rvcard != NULL) {
+                       k++;
+                       bmsg_free_vcard_data(rvcard);
+                       rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
+               }
+
+               if (env_data->body_content != NULL) {
+                       g_free(env_data->body_content->encoding);
+                       g_free(env_data->body_content->charset);
+                       g_free(env_data->body_content->language);
+                       g_free(env_data->body_content->msg);
+                       g_free(env_data->body_content);
+               }
+
+               g_free(env_data);
+               i++;
+
+               env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
+       }
+
+       DBG("-");
+done:
+       g_free(bmsg);
+}
+
+gchar *bmsg_get_parse_sub_block(char **sub_block_data, char *element)
+{
+       DBG("+");
+       gchar *start;
+       gchar *end;
+       gchar *block_start;
+       gchar *block_end;
+       gchar *sub_block = NULL;
+       size_t offset;
+       size_t len;
+
+       DBG("");
+
+       start = g_strdup_printf("BEGIN:%s\r\n", element);
+       end = g_strdup_printf("END:%s\r\n", element);
+       offset = strlen(start);
+
+       block_start = g_strstr_len(*sub_block_data, offset, start);
+       if (block_start == NULL)
+               goto done;
+
+       if (!g_strcmp0(start, VCARD_BEGIN_TAG))
+               block_end = g_strstr_len(*sub_block_data, -1,  end);
+       else
+               block_end = g_strrstr(*sub_block_data, end);
+
+       if (block_end == NULL)
+               goto done;
+
+       len = block_end - block_start - offset;
+       sub_block = g_strndup(block_start + offset, len);
+       *sub_block_data = *sub_block_data + strlen(sub_block) + strlen(start) +
+                                                                strlen(end);
+done:
+       g_free(start);
+       g_free(end);
+       DBG("-");
+       return sub_block;
+}
+
+gchar *bmsg_get_tag_data(char **block_data, char *element)
+{
+       DBG("+");
+       gchar *end = "\r\n";
+       gchar *block_start;
+       gchar *block_end;
+       gchar *sub_block;
+       size_t offset;
+       size_t len;
+
+       DBG("");
+
+       if (*block_data == NULL || element == NULL)
+               return NULL;
+
+       block_start = g_strstr_len(*block_data, -1, element);
+       if (block_start == NULL)
+               return NULL;
+
+       offset = strlen(element);
+
+       block_end = g_strstr_len(block_start+offset, -1, end);
+       if (block_end == NULL)
+               return NULL;
+
+       len = block_end - block_start - offset;
+       sub_block = g_strndup(block_start + offset, len);
+       *block_data = *block_data + offset + len + CRLF_LEN;
+       DBG("-");
+       return sub_block;
+}
+
+struct bmsg_bbody *bmsg_get_bbody_data(gchar *block_data)
+{
+       DBG("+");
+       gchar *bbody_block_data_start;
+       gchar *temp;
+       struct bmsg_bbody *bbody;
+       DBG("");
+
+       bbody_block_data_start = block_data;
+
+       bbody = g_new0(struct bmsg_bbody, 1);
+
+       temp = bmsg_get_tag_data(&block_data, PARTID_TAG);
+       if (temp != NULL) {
+               bbody->part_id = (guint16)g_ascii_strtoull(temp, NULL, 10);
+               g_free(temp);
+       }
+
+       bbody->encoding = bmsg_get_tag_data(&block_data, ENCODING_TAG);
+       bbody->charset = bmsg_get_tag_data(&block_data, CHARSET_TAG);
+       bbody->language = bmsg_get_tag_data(&block_data, LANGUAGE_TAG);
+
+       temp = bmsg_get_tag_data(&block_data, LENGTH_TAG);
+
+       if (temp != NULL) {
+               bbody->length = g_ascii_strtoull(temp, NULL, 10);
+               g_free(temp);
+       }
+
+       bbody->msg = bmsg_get_parse_sub_block(&block_data, "MSG");
+
+       g_free(bbody_block_data_start);
+       DBG("-");
+       return bbody;
+}
+
+struct bmsg_vcard *bmsg_get_vcard_data(gchar *sub_block_data)
+{
+       DBG("+");
+       gchar *vcard_block_data_start;
+       gchar *num;
+       struct bmsg_vcard *vcard;
+       DBG("");
+
+       vcard_block_data_start = sub_block_data;
+
+       vcard = g_new0(struct bmsg_vcard, 1);
+
+       vcard->version = bmsg_get_tag_data(&sub_block_data, VER_TAG);
+       vcard->n = bmsg_get_tag_data(&sub_block_data, VCARD_N_TAG);
+       vcard->fn = bmsg_get_tag_data(&sub_block_data, VCARD_FN_TAG);
+       num = bmsg_get_tag_data(&sub_block_data, VCARD_TEL_TAG);
+       vcard->tel = __bt_get_valid_number(num);
+       vcard->email = bmsg_get_tag_data(&sub_block_data, VCARD_EMAIL_TAG);
+
+       g_free(vcard_block_data_start);
+       g_free(num);
+       DBG("-");
+       return vcard;
+}
+
+struct benv_data *bmsg_get_env_encapsulation_data(gchar **sub_block_data)
+{
+       DBG("+");
+       gchar *is_valid;
+       gchar *bbody_data = NULL;
+
+       is_valid = g_strstr_len(*sub_block_data, strlen(VCARD_BEGIN_TAG),
+                                                       VCARD_BEGIN_TAG);
+       if (is_valid == NULL)
+               return NULL;
+
+       if (g_enc_lvl > 3)
+               return NULL;
+
+       struct benv_data *rec_data = g_new0(struct benv_data, 1);
+
+       rec_data->encapsulation_level = g_enc_lvl;
+       g_enc_lvl++;
+
+       while (is_valid != NULL) {
+               gchar *vcard_data = NULL;
+               struct bmsg_vcard *vcard;
+
+               vcard_data = bmsg_get_parse_sub_block(sub_block_data, "VCARD");
+               if (vcard_data == NULL) {
+                       DBG("parse error\n");
+                       g_free(rec_data);
+                       return NULL;
+               }
+               vcard = bmsg_get_vcard_data(vcard_data);
+
+               rec_data->recipient_vcard = g_slist_append(
+                                               rec_data->recipient_vcard,
+                                               vcard);
+
+               is_valid = g_strstr_len(*sub_block_data,
+                                               strlen(VCARD_BEGIN_TAG),
+                                               VCARD_BEGIN_TAG);
+       }
+
+       is_valid = g_strstr_len(*sub_block_data, strlen(BBODY_TAG), BBODY_TAG);
+
+       if (!is_valid)
+               return rec_data;
+
+       bbody_data = bmsg_get_parse_sub_block(sub_block_data, "BBODY");
+       if (bbody_data == NULL) {
+               DBG("parse error\n");
+               return rec_data;
+       }
+
+       rec_data->body_content = bmsg_get_bbody_data(bbody_data);
+       DBG("-");
+       return rec_data;
+}
+
+struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data)
+{
+       DBG("+");
+       gchar *sub_block_data;
+       struct bmsg_envelope *envelope_data;
+       struct benv_data *rec_data;
+
+       envelope_data = g_new0(struct bmsg_envelope, 1);
+
+       sub_block_data = bmsg_get_parse_sub_block(block_data, "BENV");
+
+       while (sub_block_data) {
+
+               rec_data = bmsg_get_env_encapsulation_data(&sub_block_data);
+
+               while (rec_data) {
+                       envelope_data->env_data = g_slist_append(
+                                                       envelope_data->env_data,
+                                                       rec_data);
+
+                       rec_data = bmsg_get_env_encapsulation_data(
+                                                       &sub_block_data);
+               }
+               sub_block_data = bmsg_get_parse_sub_block(&sub_block_data,
+                                                                       "BENV");
+       }
+       g_free(sub_block_data);
+       DBG("-");
+       return envelope_data;
+}
+
+struct bmsg_data *bmsg_parse(gchar *buf)
+{
+       DBG("+");
+       gchar *block_data;
+       gchar *sub_block_data;
+       gchar *block_data_start;
+       struct bmsg_data *bmsg;
+
+       DBG("");
+       g_enc_lvl = 1;
+
+       block_data = bmsg_get_parse_sub_block(&buf, "BMSG");
+       if (block_data == NULL)
+               return NULL;
+
+       block_data_start = block_data;
+
+       bmsg = g_new0(struct bmsg_data, 1);
+
+       bmsg->version = bmsg_get_tag_data(&block_data, VER_TAG);
+       if (bmsg->version == NULL)
+               goto parse_fail;
+
+       bmsg->status = bmsg_get_tag_data(&block_data, STATUS_TAG);
+       if (bmsg->status == NULL)
+               goto parse_fail;
+
+       bmsg->type = bmsg_get_tag_data(&block_data, TYPE_TAG);
+       if (bmsg->type == NULL)
+               goto parse_fail;
+
+       bmsg->folder = bmsg_get_tag_data(&block_data, FOLDER_TAG);
+       if (bmsg->folder == NULL)
+               goto parse_fail;
+
+       sub_block_data = bmsg_get_parse_sub_block(&block_data, "VCARD");
+       if (sub_block_data != NULL) {
+               bmsg->originator_vcard_data = bmsg_get_vcard_data(sub_block_data);
+               if (bmsg->originator_vcard_data == NULL)
+                       goto parse_fail;
+       }
+
+       bmsg->envelope_data = bmsg_get_envelope_data(&block_data);
+       if (bmsg->envelope_data == NULL)
+               goto parse_fail;
+
+       g_free(block_data_start);
+
+       DBG("Parse done");
+       print_bmsg(bmsg);
+       DBG("-");
+       return bmsg;
+
+parse_fail:
+       DBG("Parse fail");
+       bmsg_free_bmsg(bmsg);
+
+       return NULL;
+}
+
diff --git a/wearable/map-agent/map_bmessage.h b/wearable/map-agent/map_bmessage.h
new file mode 100644 (file)
index 0000000..860f86f
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Bluetooth-agent
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ #ifndef __BMSG_H
+#define __BMSG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bmsg_vcard {
+       gchar *version;
+       gchar *n;
+       gchar *fn;
+       gchar *tel;
+       gchar *email;
+};
+
+struct bmsg_bbody {
+       guint16 part_id;
+       gchar *encoding;
+       gchar *charset;
+       gchar *language;
+       guint64 length;
+       gchar *msg;
+};
+
+struct benv_data {
+       guint8 encapsulation_level;
+       GSList *recipient_vcard;
+       struct bmsg_bbody *body_content;
+};
+
+struct bmsg_envelope {
+       GSList *env_data;       /* Add benv_data here*/
+};
+
+struct bmsg_data {
+       gchar *version;
+       gchar *status;
+       gchar *type;
+       gchar *folder;
+       struct bmsg_vcard *originator_vcard_data;
+       struct bmsg_envelope *envelope_data;
+};
+
+struct bmsg_data * bmsg_parse(gchar *buf);
+char *bmsg_get_msg_folder(struct bmsg_data *bmsg);
+char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf);
+GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg);
+void bmsg_free_bmsg(struct bmsg_data *bmsg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BMSG_H */
diff --git a/wearable/map-agent/org.bluez.map_agent.service b/wearable/map-agent/org.bluez.map_agent.service
new file mode 100644 (file)
index 0000000..3a5a867
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.bluez.map_agent
+Exec=/usr/bin/bluetooth-map-agent
diff --git a/wearable/pb-agent/CMakeLists.txt b/wearable/pb-agent/CMakeLists.txt
new file mode 100644 (file)
index 0000000..73ae41c
--- /dev/null
@@ -0,0 +1,30 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bluetooth-pb-agent C)
+
+SET(SRCS bluetooth_pb_agent.c bluetooth_pb_vcard.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_pb_agent
+               REQUIRED
+               dbus-glib-1 dlog contacts-service2 tapi vconf capi-media-image-util libexif)
+
+FOREACH(flag ${pkgs_pb_agent_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}"
+               ARGS "--prefix=bluetooth_pb \\
+               ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_pb_agent.xml \\
+               --mode=glib-server \\
+               --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_pb_agent_glue.h")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_pb_agent_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.bluez.pb_agent.service
+               DESTINATION share/dbus-1/services)
diff --git a/wearable/pb-agent/bluetooth_pb_agent.c b/wearable/pb-agent/bluetooth_pb_agent.c
new file mode 100644 (file)
index 0000000..550759c
--- /dev/null
@@ -0,0 +1,2111 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *              Jaekyun Lee <jkyun.leek@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <contacts.h>
+
+#include <TapiUtility.h>
+#include <ITapiSim.h>
+
+#include "bluetooth_pb_agent.h"
+#include "bluetooth_pb_vcard.h"
+
+#define BLUETOOTH_PB_AGENT_TIMEOUT 600
+
+static gchar *bluetooth_pb_agent_folder_list[] = {
+       "/telecom/pb",
+       "/telecom/ich",
+       "/telecom/och",
+       "/telecom/mch",
+       "/telecom/cch",
+       NULL
+};
+
+typedef enum {
+       TELECOM_PB = 0,
+       TELECOM_ICH,
+       TELECOM_OCH,
+       TELECOM_MCH,
+       TELECOM_CCH,
+       TELECOM_NONE
+} PhoneBookType;
+
+typedef struct {
+       GObject parent;
+
+       DBusGConnection *bus;
+       DBusGProxy *proxy;
+
+       TapiHandle *tapi_handle;
+       gchar *tel_number;
+       guint timeout_id;
+
+       PhoneBookType pb_type;
+} BluetoothPbAgent;
+
+typedef struct {
+       GObjectClass parent;
+
+       void (*clear) (BluetoothPbAgent *agent);
+} BluetoothPbAgentClass;
+
+enum {
+       CLEAR,
+       LAST_SIGNAL
+};
+
+GType bluetooth_pb_agent_get_type(void);
+
+#define BLUETOOTH_PB_TYPE_AGENT (bluetooth_pb_agent_get_type())
+
+#define BLUETOOTH_PB_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_CAST((object), \
+       BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgent))
+#define BLUETOOTH_PB_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST((klass), \
+       BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgentClass))
+#define BLUETOOTH_IS_PB_AGENT(object) \
+       (G_TYPE_CHECK_INSTANCE_TYPE((object), \
+       BLUETOOTH_PB_TYPE_AGENT))
+#define BLUETOOTH_IS_PB_AGENT_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE((klass), \
+       BLUETOOTH_PB_TYPE_AGENT))
+#define BLUETOOTH_PB_AGENT_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS((obj), \
+       BLUETOOTH_PB_TYPE_AGENT , BluetoothPbAgentClass))
+
+G_DEFINE_TYPE(BluetoothPbAgent, bluetooth_pb_agent, G_TYPE_OBJECT)
+
+#define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", G_TYPE_STRING, \
+                                                       G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID))
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GMainLoop *mainloop = NULL;
+
+static void bluetooth_pb_agent_finalize(GObject *obj);
+
+static void bluetooth_pb_agent_clear(BluetoothPbAgent *agent);
+
+/* Dbus messages */
+static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
+                                               const gchar ***folder_list,
+                                               GError **error);
+
+static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
+                                       const char *name,
+                                       guint64 filter,
+                                       guint8 format,
+                                       guint16 max_list_count,
+                                       guint16 list_start_offset,
+                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
+                                               const gchar *folder,
+                                               const gchar *id,
+                                               guint64 filter,
+                                               guint8 format,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       gint32 start_index,
+                                       gint32 end_index,
+                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *agent,
+                                                       const gchar *command,
+                                                       const gchar *find_text,
+                                                       DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
+                                               gchar *path,
+                                               DBusGMethodInvocation *context);
+
+static gboolean bluetooth_pb_add_contact (BluetoothPbAgent *agent,
+                                       const char *filename,
+                                       GError **error);
+
+static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
+                                       DBusGMethodInvocation *context);
+
+static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
+                                       gint code,
+                                       const gchar *message);
+
+static PhoneBookType __bluetooth_pb_get_pb_type(const char *name);
+
+static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name);
+
+static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
+                                               gint *match,
+                                               gint size);
+
+static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
+                                               gint size);
+
+static contacts_query_h __bluetooth_pb_query_person(void);
+
+static contacts_query_h __bluetooth_pb_query_person_number(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_missed(void);
+
+static contacts_query_h __bluetooth_pb_query_phone_log_combined(void);
+
+static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
+                               guint *count);
+
+static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count);
+
+static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record);
+
+static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               guint64 filter,
+                               guint8 format,
+                               guint16 max_list_count,
+                               guint16 list_start_offset,
+                               GPtrArray *vcards);
+
+static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array);
+
+static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
+                                       PhoneBookType pb_type,
+                                       const gchar *find_text,
+                                       GPtrArray *ptr_array);
+
+static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
+                                               const gchar *name,
+                                               const gchar *number,
+                                               gint handle);
+
+static void __bluetooth_pb_list_ptr_array_free(gpointer data);
+
+static void __bluetooth_pb_agent_signal_handler(int signum);
+
+static void __bluetooth_pb_contact_changed(const gchar *view_uri,
+                                       void *user_data);
+
+static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent);
+
+static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data);
+
+static void __bluetooth_pb_tel_callback(TapiHandle *handle,
+                                       int result,
+                                       void *data,
+                                       void *user_data);
+
+static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent);
+
+#include "bluetooth_pb_agent_glue.h"
+
+static void bluetooth_pb_agent_init(BluetoothPbAgent *agent)
+{
+       agent->bus = NULL;
+       agent->proxy = NULL;
+       agent->tapi_handle = NULL;
+       agent->tel_number = NULL;
+       agent->timeout_id = 0;
+       agent->pb_type = TELECOM_NONE;
+}
+
+static void bluetooth_pb_agent_class_init(BluetoothPbAgentClass *klass)
+{
+       GObjectClass *object_class = (GObjectClass *) klass;
+
+       klass->clear = bluetooth_pb_agent_clear;
+
+       object_class->finalize = bluetooth_pb_agent_finalize;
+
+       signals[CLEAR] = g_signal_new("clear",
+                       G_TYPE_FROM_CLASS(klass),
+                       G_SIGNAL_RUN_LAST,
+                       G_STRUCT_OFFSET(BluetoothPbAgentClass, clear),
+                       NULL, NULL,
+                       g_cclosure_marshal_VOID__VOID,
+                       G_TYPE_NONE, 0);
+
+       dbus_g_object_type_install_info(BLUETOOTH_PB_TYPE_AGENT,
+                                       &dbus_glib_bluetooth_pb_object_info);
+}
+
+static void bluetooth_pb_agent_finalize(GObject *obj)
+{
+       BluetoothPbAgent *agent  = BLUETOOTH_PB_AGENT(obj);
+
+       DBG("+\n");
+
+       if (agent->tapi_handle) {
+               tel_deinit(agent->tapi_handle);
+               agent->tapi_handle = NULL;
+       }
+
+       if (agent->tel_number) {
+               g_free(agent->tel_number);
+               agent->tel_number = NULL;
+       }
+
+       if(agent->timeout_id) {
+               g_source_remove(agent->timeout_id);
+               agent->timeout_id = 0;
+       }
+
+       if (agent->proxy) {
+               g_object_unref(agent->proxy);
+               agent->proxy = NULL;
+       }
+
+       if (agent->bus) {
+               dbus_g_connection_unref(agent->bus);
+               agent->bus = NULL;
+       }
+
+
+       G_OBJECT_CLASS(bluetooth_pb_agent_parent_class)->finalize(obj);
+}
+
+static void bluetooth_pb_agent_clear(BluetoothPbAgent *agent)
+{
+       DBG("+\n");
+
+       agent->pb_type = TELECOM_NONE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_folder_list(BluetoothPbAgent *agent,
+                                               const gchar ***folder_list,
+                                               GError **error)
+{
+       gint size;
+       gint i;
+       gchar **folder;
+
+       size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list);
+       folder = g_new0(gchar *, size);
+
+       for (i = 0; i < size; i++)
+               folder[i] = g_strdup(bluetooth_pb_agent_folder_list[i]);
+
+       *folder_list = (const gchar **)folder;
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook(BluetoothPbAgent *agent,
+                                       const char *name,
+                                       guint64 filter,
+                                       guint8 format,
+                                       guint16 max_list_count,
+                                       guint16 list_start_offset,
+                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+       GPtrArray *vcards = NULL;
+       gchar **vcards_str = NULL;
+
+       guint new_missed_call = 0;
+
+       DBG_SECURE("name: %s filter: %lld format: %d max_list_count: %d list_start_offset: %d\n",
+                       name, filter, format, max_list_count, list_start_offset);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_pb_type(name);
+
+       if (pb_type == TELECOM_NONE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       vcards = g_ptr_array_new();
+
+       if (max_list_count > 0) {
+               __bluetooth_pb_get_vcards(agent, pb_type,
+                               filter, format,
+                               max_list_count, list_start_offset,
+                               vcards);
+
+       }
+
+       g_ptr_array_add(vcards, NULL);
+
+       vcards_str = (gchar **) g_ptr_array_free(vcards, FALSE);
+
+       dbus_g_method_return(context, vcards_str, new_missed_call);
+
+       g_strfreev(vcards_str);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_size(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       guint new_missed_call = 0;
+       guint count = 0;
+
+       DBG_SECURE("name: %s\n", name);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_pb_type(name);
+
+       if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       /* for owner */
+       if (pb_type == TELECOM_PB)
+               count++;
+
+       __bluetooth_pb_get_count_new_missed_call(&new_missed_call);
+
+       dbus_g_method_return(context, count, new_missed_call);
+
+       return TRUE;
+}
+
+
+static gboolean bluetooth_pb_get_phonebook_list(BluetoothPbAgent *agent,
+                                               const char *name,
+                                               DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       GPtrArray *ptr_array;
+
+       DBG_SECURE("name: %s\n", name);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_pb_type(name);
+
+       if (pb_type == TELECOM_NONE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
+
+       __bluetooth_pb_get_list(agent, pb_type, ptr_array);
+
+       dbus_g_method_return(context, ptr_array);
+
+       if (ptr_array)
+               g_ptr_array_free(ptr_array, TRUE);
+
+       return TRUE;
+}
+
+
+static gboolean bluetooth_pb_get_phonebook_entry(BluetoothPbAgent *agent,
+                                               const gchar *folder,
+                                               const gchar *id,
+                                               guint64 filter,
+                                               guint8 format,
+                                               DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       gint handle = 0;
+       gchar *str = NULL;
+
+       const gchar *attr = NULL;
+
+       DBG_SECURE("folder: %s id: %s filter: %ld format: %d\n",
+                       folder, id, filter, format);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       if (!g_str_has_suffix(id, ".vcf")) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "invalid vcf file");
+               return FALSE;
+       }
+
+       handle = (gint)g_ascii_strtoll(id, NULL, 10);
+
+       pb_type = __bluetooth_pb_get_pb_type(folder);
+
+       if (pb_type == TELECOM_NONE) {
+               __bluetooth_pb_dbus_return_error(context,
+                               G_FILE_ERROR_INVAL,
+                               "unsupported name defined");
+               return FALSE;
+       }
+
+       /* create index cache */
+       __bluetooth_pb_get_list(agent, pb_type, NULL);
+
+       switch(pb_type) {
+       case TELECOM_PB:
+               if (handle == 0) {
+                       str = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
+                                                               filter, format);
+               } else {
+                       str = _bluetooth_pb_vcard_contact(handle, filter, format);
+               }
+               break;
+       case TELECOM_ICH:
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "RECEIVED");
+               break;
+       case TELECOM_OCH:
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "DIALED");
+               break;
+       case TELECOM_MCH:
+               str = _bluetooth_pb_vcard_call(handle, filter, format, "MISSED");
+               break;
+       case TELECOM_CCH: {
+               contacts_record_h record = NULL;
+
+               gint status;
+
+               status = contacts_db_get_record(_contacts_phone_log._uri,
+                               handle, &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       break;
+
+               attr = __bluetooth_pb_phone_log_get_log_type(record);
+               str = _bluetooth_pb_vcard_call(handle, filter, format, attr);
+
+               contacts_record_destroy(record, TRUE);
+               break;
+       }
+       default:
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context, str);
+       g_free(str);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_size_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+       guint count = 0;
+
+       DBG("command: %s\n", command);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(command);
+
+       if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context, count);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_entries_at(BluetoothPbAgent *agent,
+                                       const gchar *command,
+                                       gint start_index,
+                                       gint end_index,
+                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       GPtrArray *ptr_array = NULL;
+
+       DBG("command: %s, start_index: %d, end_index: %d\n",
+                       command, start_index, end_index);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(command);
+
+       if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
+
+       __bluetooth_pb_get_list_number(agent, pb_type,
+                       start_index, end_index,
+                       ptr_array);
+
+       dbus_g_method_return(context, ptr_array);
+
+       if (ptr_array)
+               g_ptr_array_free(ptr_array, TRUE);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_phonebook_entries_find_at(BluetoothPbAgent *agent,
+                                                       const gchar *command,
+                                                       const gchar *find_text,
+                                                       DBusGMethodInvocation *context)
+{
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       GPtrArray *ptr_array = NULL;
+
+       DBG("command: %s, find text: %s\n", command, find_text);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(command);
+
+       if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       ptr_array = g_ptr_array_new_with_free_func(__bluetooth_pb_list_ptr_array_free);
+
+       __bluetooth_pb_get_list_name(agent, pb_type,
+                       find_text, ptr_array);
+
+       dbus_g_method_return(context, ptr_array);
+
+       if (ptr_array)
+               g_ptr_array_free(ptr_array, TRUE);
+
+       return TRUE;
+}
+
+static gboolean bluetooth_pb_get_total_object_count(BluetoothPbAgent *agent,
+                                       gchar *path, DBusGMethodInvocation *context)
+{
+       guint count = 0;
+       PhoneBookType pb_type = TELECOM_NONE;
+
+       DBG("%s() %d\n", __FUNCTION__, __LINE__);
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       pb_type = __bluetooth_pb_get_storage_pb_type(path);
+
+       if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
+               __bluetooth_pb_dbus_return_error(context,
+                                       G_FILE_ERROR_INVAL,
+                                       "unsupported name defined");
+               return FALSE;
+       }
+
+       dbus_g_method_return(context, count);
+
+       DBG("%s() %d\n", __FUNCTION__, __LINE__);
+
+       return TRUE;
+}
+
+
+#if 0
+static int __bluetooth_pb_agent_read_file(const char *file_path, char **stream)
+{
+       FILE *fp = NULL;
+       int read_len = -1;
+       int received_file_size = 0;
+       struct stat file_attr;
+
+       if (file_path == NULL || stream == NULL) {
+               DBG("Invalid data \n");
+               return -1;
+       }
+
+       DBG_SECURE("file_path = %s\n", file_path);
+
+       if ((fp = fopen(file_path, "r+")) == NULL) {
+               ERR_SECURE("Cannot open %s\n", file_path);
+               return -1;
+       }
+
+       if (fstat(fileno(fp), &file_attr) == 0) {
+               received_file_size = file_attr.st_size;
+               DBG("file_attr.st_size = %d, size = %d\n", file_attr.st_size, received_file_size);
+
+               if (received_file_size <= 0) {
+                       ERR_SECURE("Some problem in the file size [%s]  \n", file_path);
+                       fclose(fp);
+                       fp = NULL;
+                       return -1;
+               }
+
+               *stream = (char *)malloc(sizeof(char) * received_file_size);
+               if (NULL == *stream) {
+                       fclose(fp);
+                       fp = NULL;
+                       return -1;
+               }
+       } else {
+               ERR_SECURE("Some problem in the file [%s]  \n", file_path);
+               fclose(fp);
+               fp = NULL;
+               return -1;
+       }
+
+       read_len = fread(*stream, 1, received_file_size, fp);
+
+       if (read_len == 0) {
+               if (fp != NULL) {
+                       fclose(fp);
+                       fp = NULL;
+               }
+               DBG_SECURE("Cannot open %s\n", file_path);
+               return -1;
+       }
+
+       if (fp != NULL) {
+               fclose(fp);
+               fp = NULL;
+       }
+       return 0;
+}
+#endif
+
+static gboolean bluetooth_pb_add_contact(BluetoothPbAgent *agent, const char *filename,
+                                        GError **error)
+{
+       /* Contact API is changed, Temporary blocked */
+#if 0
+       CTSstruct *contact_record = NULL;
+       GSList *numbers_list = NULL, *cursor;
+       int is_success = 0;
+       int is_duplicated = 0;
+       int err = 0;
+       char *stream = NULL;
+
+       DBG_SECURE("file_path = %s\n", filename);
+
+       err = contacts_svc_connect();
+       DBG("contact_db_service_connect fucntion call [error] = %d \n", err);
+
+       err = __bluetooth_pb_agent_read_file(filename, &stream);
+
+       if (err != 0) {
+               contacts_svc_disconnect();
+               DBG("contacts_svc_disconnect fucntion call [error] = %d \n", err);
+
+               if (NULL != stream) {
+                       free(stream);
+                       stream = NULL;
+               }
+               return FALSE;
+       }
+
+       is_success = contacts_svc_get_contact_from_vcard((const void *)stream, &contact_record);
+
+       DBG("contacts_svc_get_contact_from_vcard fucntion call [is_success] = %d \n", is_success);
+
+       if (0 == is_success) {
+               contacts_svc_struct_get_list(contact_record, CTS_CF_NUMBER_LIST, &numbers_list);
+               cursor = numbers_list;
+
+               for (; cursor; cursor = g_slist_next(cursor)) {
+                       if (contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER,
+                                                       contacts_svc_value_get_str(cursor->data,
+                                                               CTS_NUM_VAL_NUMBER_STR)) > 0) {
+                               DBG("is_duplicated\n");
+                               is_duplicated = TRUE;
+                       }
+               }
+
+               if (is_duplicated == FALSE) {
+                       contacts_svc_insert_contact(0, contact_record);
+               }
+       } else {
+               DBG("Fail \n");
+       }
+
+       err = contacts_svc_disconnect();
+       DBG("contacts_svc_disconnect fucntion call [error] = %d \n", err);
+
+       if (NULL != stream) {
+               free(stream);
+               stream = NULL;
+       }
+#endif
+
+       return TRUE;
+}
+
+static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context,
+                                       gint code,
+                                       const gchar *message)
+{
+       GQuark quark;
+       GError *error = NULL;
+
+       quark = g_type_qname(bluetooth_pb_agent_get_type());
+       error = g_error_new_literal(quark, code, message);
+
+       DBG("%s\n", message);
+
+       dbus_g_method_return_error(context, error);
+       g_error_free(error);
+}
+
+static PhoneBookType __bluetooth_pb_get_pb_type(const char *name)
+{
+       gchar *suffix = ".vcf";
+       gint len;
+       gint size;
+       gint i;
+
+       if (name == NULL)
+               return TELECOM_NONE;
+
+       len = strlen(name);
+
+       if (g_str_has_suffix(name, suffix))
+               len -= strlen(suffix);
+
+       size = G_N_ELEMENTS(bluetooth_pb_agent_folder_list) - 1;
+       for (i = 0; i < size; i++) {
+               if (strncmp(name, bluetooth_pb_agent_folder_list[i], len) == 0)
+                       return i;
+       }
+
+       return TELECOM_NONE;
+}
+
+static PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name)
+{
+       if (name == NULL)
+               return TELECOM_NONE;
+
+       if (g_strcmp0(name, "\"ME\"") == 0 )
+               return TELECOM_PB;
+
+       if (g_strcmp0(name, "\"RC\"") == 0)
+               return TELECOM_ICH;
+
+       if (g_strcmp0(name, "\"DC\"") == 0)
+               return TELECOM_OCH;
+
+       if (g_strcmp0(name, "\"MC\"") == 0)
+               return TELECOM_MCH;
+
+       return TELECOM_NONE;
+}
+
+static gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter,
+                                               gint *match,
+                                               gint size)
+{
+       gint i;
+       gint status;
+
+       for (i = 0; i < size; i++) {
+
+               if ( i > 0) {
+                       status = contacts_filter_add_operator(filter,
+                                       CONTACTS_FILTER_OPERATOR_OR);
+
+                       if (status != CONTACTS_ERROR_NONE)
+                               return status;
+               }
+
+               status = contacts_filter_add_int(filter,
+                               _contacts_phone_log.log_type,
+                               CONTACTS_MATCH_EQUAL,
+                               match[i]);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return status;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log(gint *match,
+                                               gint size)
+{
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_phone_log._uri,
+                               &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = __bluetooth_pb_phone_log_filter_append(filter, match, size);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = contacts_query_set_filter(query, filter);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       status = contacts_query_set_sort(query,
+                       _contacts_phone_log.log_time,
+                       false);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_filter_destroy(filter);
+               contacts_query_destroy(query);
+               return NULL;
+       }
+
+       contacts_filter_destroy(filter);
+
+       return query;
+}
+
+static contacts_query_h __bluetooth_pb_query_person(void)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_person._uri,
+                       &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       return query;
+}
+
+static contacts_query_h __bluetooth_pb_query_person_number(void)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+
+       status = contacts_query_create(_contacts_person_number._uri,
+                               &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       return query;
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void)
+{
+       gint size = 2;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void)
+{
+       gint size = 2;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
+               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_missed(void)
+{
+       gint size = 4;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static contacts_query_h __bluetooth_pb_query_phone_log_combined(void)
+{
+       gint size = 8;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING,
+               CONTACTS_PLOG_TYPE_VOICE_OUTGOING,
+               CONTACTS_PLOG_TYPE_VIDEO_OUTGOING,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN
+       };
+
+       return __bluetooth_pb_query_phone_log(match, size);
+}
+
+static gboolean __bluetooth_pb_get_count(PhoneBookType pb_type,
+                               guint *count)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+       gint signed_count;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person();
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               break;
+       default:
+               return FALSE;
+       }
+
+       if (query == NULL)
+               return FALSE;
+
+       status = contacts_db_get_count_with_query(query, &signed_count);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return FALSE;
+       }
+
+       contacts_query_destroy(query);
+
+       if (signed_count < 0)
+               signed_count = 0;
+
+       *count = (gint) signed_count;
+
+       return TRUE;
+}
+
+static gboolean __bluetooth_pb_get_count_new_missed_call(guint *count)
+{
+       contacts_query_h query = NULL;
+
+       gint status;
+       gint signed_count;
+
+       gint size = 2;
+       gint match[] = {
+               CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
+               CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN
+       };
+
+       query = __bluetooth_pb_query_phone_log(match, size);
+
+       if (query == NULL)
+               return FALSE;
+
+       status = contacts_db_get_count_with_query(query, &signed_count);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_query_destroy(query);
+               return FALSE;
+       }
+
+       contacts_query_destroy(query);
+
+       if (signed_count < 0)
+               signed_count = 0;
+
+       *count = (guint)signed_count;
+
+       return TRUE;
+}
+
+static const char *__bluetooth_pb_phone_log_get_log_type(contacts_record_h record)
+{
+       gint status;
+       gint log_type;
+
+       status = contacts_record_get_int(record,
+                       _contacts_phone_log.log_type,
+                       &log_type);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       switch (log_type) {
+       case CONTACTS_PLOG_TYPE_VOICE_INCOMMING:
+       case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING:
+               return "RECEIVED";
+       case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
+       case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
+               return "DIALED";
+       case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN:
+       case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN:
+       case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN:
+       case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN:
+               return "MISSED";
+       default:
+               return NULL;
+       }
+}
+
+static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               guint64 filter,
+                               guint8 format,
+                               guint16 max_list_count,
+                               guint16 list_start_offset,
+                               GPtrArray *vcards)
+{
+       contacts_list_h record_list = NULL;
+       contacts_query_h query = NULL;
+
+       gint status;
+
+       gint limit;
+       gint offset;
+
+       guint property_id = 0;
+
+       const char *attr = NULL;
+
+       gboolean get_log = FALSE;
+
+       /* contact offset is n - 1 of PBAP */
+       offset = (gint)list_start_offset - 1;
+
+       if ( max_list_count >= 65535)
+               limit = -1;     /* contact limit -1 means unrestricted */
+       else
+               limit = (gint)max_list_count;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               /* for owner */
+               if (list_start_offset == 0) {
+                       char *vcard;
+
+                       vcard = _bluetooth_pb_vcard_contact_owner(agent->tel_number,
+                                                               filter, format);
+                       if (vcard)
+                               g_ptr_array_add(vcards, vcard);
+
+                       offset = 0;
+
+                       if (limit > 0)
+                               limit--;
+               }
+
+               query = __bluetooth_pb_query_person();
+               property_id = _contacts_person.id;
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               property_id = _contacts_phone_log.id;
+               attr = "RECEIVED";
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               property_id = _contacts_phone_log.id;
+               attr = "DIALED";
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               property_id = _contacts_phone_log.id;
+               attr = "MISSED";
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               property_id = _contacts_phone_log.id;
+               get_log = TRUE;
+               break;
+       default:
+               return;
+       }
+
+       status = contacts_db_get_records_with_query(query, offset, limit, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               contacts_query_destroy(query);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               contacts_query_destroy(query);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gint id;
+
+               gchar *vcard = NULL;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list, &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+               id = 0;
+               status = contacts_record_get_int(record, property_id, &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (property_id == _contacts_person.id)
+                       vcard = _bluetooth_pb_vcard_contact(id, filter, format);
+               else {
+                       if (get_log)
+                               attr = __bluetooth_pb_phone_log_get_log_type(record);
+
+                       vcard = _bluetooth_pb_vcard_call(id, filter, format, attr);
+               }
+
+               if (vcard)
+                       g_ptr_array_add(vcards, vcard);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+       contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       /* Add owner */
+       if (ptr_array) {
+               gchar *tmp;
+               gchar *name;
+
+               tmp = _bluetooth_pb_owner_name();
+               name = g_strdup_printf("%s;;;;", tmp);
+               g_free(tmp);
+
+               __bluetooth_pb_list_ptr_array_add(ptr_array,
+                               name, agent->tel_number, 0);
+
+               g_free(name);
+       }
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gint id;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_person.id,
+                               &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               /* create list */
+               if (ptr_array) {
+                       gchar *name;
+                       gchar *number;
+
+                       name = _bluetooth_pb_name_from_person_id(id);
+                       number = _bluetooth_pb_number_from_person_id(id);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       name, number, id);
+
+                       g_free(name);
+                       g_free(number);
+               }
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent,
+                                       contacts_query_h query,
+                                       GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gint id;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_phone_log.id,
+                               &id);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               /* create list */
+               if (ptr_array) {
+                       gchar *name;
+                       gchar *number;
+
+                       name = _bluetooth_pb_name_from_phonelog_id(id);
+
+                       number = NULL;
+                       contacts_record_get_str_p(record,
+                                       _contacts_phone_log.address,
+                                       &number);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       name, number, id);
+
+                       g_free(name);
+               }
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+
+static void __bluetooth_pb_get_list(BluetoothPbAgent *agent,
+                               PhoneBookType pb_type,
+                               GPtrArray *ptr_array)
+{
+       contacts_query_h query;
+
+       /* no requires refresh cache */
+       if (ptr_array == NULL && agent->pb_type == pb_type)
+               return;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person();
+               __bluetooth_pb_get_contact_list(agent, query, ptr_array);
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_phone_log_list(agent, query, ptr_array);
+               break;
+       default:
+               return;
+       }
+
+       agent->pb_type = pb_type;
+
+       if (query)
+               contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       gint i;
+
+       gint from;
+       gint to;
+       gint offset;
+
+       from = start_index;
+       to = end_index;
+
+       if (from < 1)
+               from = 1;
+
+       if (to < 1)
+               to = 1;
+
+       offset = to - from + 1;
+       if (offset <= 0)
+               return;
+
+       i = from;
+
+       status = contacts_db_get_records_with_query(query,
+                       from - 1 , offset,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gchar *display_name;
+               gchar *number;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               display_name = NULL;
+               number = NULL;
+
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.display_name,
+                               &display_name);
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.number,
+                               &number);
+
+               __bluetooth_pb_list_ptr_array_add(ptr_array,
+                               display_name, number, i);
+
+               i++;
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       gint i;
+
+       gint from;
+       gint to;
+       gint offset;
+
+       from = start_index;
+       to = end_index;
+
+       if (from < 1)
+               from = 1;
+
+       if (to < 1)
+               to = 1;
+
+       offset = to - from + 1;
+       if (offset <= 0)
+               return;
+
+       i = from;
+
+       status = contacts_db_get_records_with_query(query,
+                       from - 1 , offset,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record = NULL;
+
+               gint id;
+
+               gchar *display_name;
+               gchar *number;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_phone_log.id,
+                               &id);
+
+               display_name = _bluetooth_pb_fn_from_phonelog_id(id);
+
+               number = NULL;
+               contacts_record_get_str_p(record,
+                               _contacts_phone_log.address,
+                               &number);
+
+
+               __bluetooth_pb_list_ptr_array_add(ptr_array,
+                               display_name, number, i);
+
+               i++;
+
+               g_free(display_name);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_list_number(BluetoothPbAgent *agent,
+                                               PhoneBookType pb_type,
+                                               gint start_index,
+                                               gint end_index,
+                                               GPtrArray *ptr_array)
+{
+       contacts_query_h query;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person_number();
+               __bluetooth_pb_get_contact_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_phone_log_list_number(agent, query,
+                               start_index, end_index, ptr_array);
+               break;
+       default:
+               return;
+       }
+
+       if (query)
+               contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+       gint i = 1;
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1, &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record;
+
+               gchar *display_name;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               display_name = NULL;
+               contacts_record_get_str_p(record,
+                               _contacts_person_number.display_name,
+                               &display_name);
+
+               if (g_str_has_prefix(display_name, find_text)) {
+                       gchar *number;
+
+                       number = NULL;
+                       contacts_record_get_str_p(record,
+                                       _contacts_person_number.number,
+                                       &number);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       display_name, number, i);
+               }
+
+               i++;
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent,
+                                               contacts_query_h query,
+                                               const gchar *find_text,
+                                               GPtrArray *ptr_array)
+{
+       contacts_list_h record_list = NULL;
+
+       gint status;
+
+       gint i = 1;
+
+       status = contacts_db_get_records_with_query(query,
+                       -1, -1,
+                       &record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_list_destroy(record_list, TRUE);
+               return;
+       }
+
+       do {
+               contacts_record_h record = NULL;
+
+               gint id;
+
+               gchar *display_name;
+
+               record = NULL;
+               status = contacts_list_get_current_record_p(record_list,
+                               &record);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               id = 0;
+               status = contacts_record_get_int(record,
+                               _contacts_phone_log.id,
+                               &id);
+
+               display_name = _bluetooth_pb_fn_from_phonelog_id(id);
+
+               if (g_str_has_prefix(display_name, find_text)) {
+                       gchar *number = NULL;
+
+                       number = NULL;
+                       contacts_record_get_str_p(record,
+                                       _contacts_phone_log.address,
+                                       &number);
+
+                       __bluetooth_pb_list_ptr_array_add(ptr_array,
+                                       display_name, number, i);
+               }
+
+               i++;
+
+               g_free(display_name);
+
+       } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE);
+
+       contacts_list_destroy(record_list, TRUE);
+}
+
+static void __bluetooth_pb_get_list_name(BluetoothPbAgent *agent,
+                                       PhoneBookType pb_type,
+                                       const gchar *find_text,
+                                       GPtrArray *ptr_array)
+{
+       contacts_query_h query;
+
+       switch (pb_type) {
+       case TELECOM_PB:
+               query = __bluetooth_pb_query_person_number();
+               __bluetooth_pb_get_contact_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_ICH:
+               query = __bluetooth_pb_query_phone_log_incoming();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_OCH:
+               query = __bluetooth_pb_query_phone_log_outgoing();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_MCH:
+               query = __bluetooth_pb_query_phone_log_missed();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       case TELECOM_CCH:
+               query = __bluetooth_pb_query_phone_log_combined();
+               __bluetooth_pb_get_phone_log_list_name(agent, query,
+                               find_text, ptr_array);
+               break;
+       default:
+               return;
+       }
+
+       if (query)
+               contacts_query_destroy(query);
+}
+
+static void __bluetooth_pb_list_ptr_array_add(GPtrArray *ptr_array,
+                                               const gchar *name,
+                                               const gchar *number,
+                                               gint handle)
+{
+       GValue value = { 0, };
+
+       g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
+       g_value_take_boxed(&value,
+                       dbus_g_type_specialized_construct(DBUS_STRUCT_STRING_STRING_UINT));
+
+       dbus_g_type_struct_set(&value,
+                               0, g_strdup(name),
+                               1, g_strdup(number),
+                               2, handle,
+                               G_MAXUINT);
+
+       g_ptr_array_add(ptr_array, g_value_get_boxed(&value));
+}
+
+static void __bluetooth_pb_list_ptr_array_free(gpointer data)
+{
+       GValue value = { 0, };
+
+       gchar *name = NULL;
+       gchar *number = NULL;
+
+       if(data == NULL)
+               return;
+
+       g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
+       g_value_set_boxed(&value, data);
+
+       dbus_g_type_struct_get(&value,
+                       0, &name,
+                       1, &number,
+                       G_MAXUINT);
+
+       g_free(name);
+       g_free(number);
+}
+
+static void __bluetooth_pb_agent_signal_handler(int signum)
+{
+       if (mainloop) {
+               g_main_loop_quit(mainloop);
+       } else {
+               DBG("Terminate Bluetooth PBAP agent");
+               exit(0);
+       }
+}
+
+
+static void __bluetooth_pb_contact_changed(const gchar *view_uri,
+                                       void *user_data)
+{
+       BluetoothPbAgent *agent;
+
+       g_return_if_fail(BLUETOOTH_IS_PB_AGENT(user_data));
+       agent = BLUETOOTH_PB_AGENT(user_data);
+
+       g_signal_emit(agent, signals[CLEAR], 0);
+       g_object_unref(agent);
+}
+
+static void __bluetooth_pb_agent_timeout_add_seconds(BluetoothPbAgent *agent)
+{
+       g_return_if_fail(BLUETOOTH_IS_PB_AGENT(agent));
+
+       if(agent->timeout_id)
+               g_source_remove(agent->timeout_id);
+
+       agent->timeout_id = g_timeout_add_seconds(BLUETOOTH_PB_AGENT_TIMEOUT,
+                               __bluetooth_pb_agent_timeout_calback,
+                               agent);
+}
+
+static gboolean __bluetooth_pb_agent_timeout_calback(gpointer user_data)
+{
+       BluetoothPbAgent *agent;
+
+       g_return_val_if_fail(BLUETOOTH_IS_PB_AGENT(user_data), FALSE);
+
+       agent = BLUETOOTH_PB_AGENT(user_data);
+       agent->timeout_id = 0;
+
+       if (mainloop)
+               g_main_loop_quit(mainloop);
+
+       return FALSE;
+}
+
+static void __bluetooth_pb_tel_callback(TapiHandle *handle,
+                                       int result,
+                                       void *data,
+                                       void *user_data)
+{
+       BluetoothPbAgent *agent;
+       TelSimMsisdnList_t *number;
+
+       g_return_if_fail(BLUETOOTH_IS_PB_AGENT(user_data));
+
+       agent = BLUETOOTH_PB_AGENT(user_data);
+
+       __bluetooth_pb_agent_dbus_init(agent);
+
+       if (data != NULL) {
+               number = (TelSimMsisdnList_t *)data;
+               agent->tel_number = g_strdup(number->list[0].num);
+       }
+
+       tel_deinit(agent->tapi_handle);
+       agent->tapi_handle = NULL;
+}
+
+static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent)
+{
+       guint result = 0;
+       GError *error = NULL;
+
+       agent->bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+
+       if (error != NULL) {
+               DBG("Couldn't connect to system bus[%s]\n", error->message);
+               g_error_free(error);
+               return;
+       }
+
+       agent->proxy = dbus_g_proxy_new_for_name(agent->bus,
+                       DBUS_SERVICE_DBUS,
+                       DBUS_PATH_DBUS,
+                       DBUS_INTERFACE_DBUS);
+
+       if (agent->proxy == NULL) {
+               DBG("Failed to get a proxy for D-Bus\n");
+               return;
+       }
+
+       if (!dbus_g_proxy_call(agent->proxy,
+                               "RequestName", &error,
+                               G_TYPE_STRING, BT_PB_SERVICE_NAME,
+                               G_TYPE_UINT, 0,
+                               G_TYPE_INVALID,
+                               G_TYPE_UINT, &result,
+                               G_TYPE_INVALID)) {
+               if (error != NULL) {
+                       DBG("RequestName RPC failed[%s]\n", error->message);
+                       g_error_free(error);
+               }
+
+               g_object_unref(agent->proxy);
+               agent->proxy = NULL;
+
+               return;
+       }
+       DBG("result : %d %d\n", result, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+       if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+               DBG("Failed to get the primary well-known name.\n");
+
+               g_object_unref(agent->proxy);
+               agent->proxy = NULL;
+
+               return;
+       }
+
+       g_object_unref(agent->proxy);
+       agent->proxy = NULL;
+
+       dbus_g_connection_register_g_object(agent->bus,
+                       BT_PB_SERVICE_OBJECT_PATH,
+                       G_OBJECT(agent));
+}
+
+static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent,
+                                       DBusGMethodInvocation *context)
+{
+       g_main_loop_quit(mainloop);
+       return TRUE;
+}
+
+int main(void)
+{
+       BluetoothPbAgent *agent;
+
+       gint ret = EXIT_SUCCESS;
+       gint tapi_result;
+
+       struct sigaction sa;
+       DBG("Starting Bluetooth PBAP agent");
+
+       g_type_init();
+
+       mainloop = g_main_loop_new(NULL, FALSE);
+       if (mainloop == NULL) {
+               DBG("Couldn't create GMainLoop\n");
+               return EXIT_FAILURE;
+       }
+
+       agent = g_object_new(BLUETOOTH_PB_TYPE_AGENT, NULL);
+
+       /* connect contact */
+       if (contacts_connect2() != CONTACTS_ERROR_NONE) {
+               DBG("Can not connect contacts server\n");
+               g_object_unref(agent);
+               return EXIT_FAILURE;
+       }
+
+       if (contacts_db_add_changed_cb(_contacts_event._uri,
+                       __bluetooth_pb_contact_changed,
+                       g_object_ref(agent)) != CONTACTS_ERROR_NONE) {
+               DBG("Can not add changed callback");
+       }
+
+       /* set signal */
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_handler = __bluetooth_pb_agent_signal_handler;
+       sigaction(SIGTERM, &sa, NULL);
+       sigaction(SIGINT, &sa, NULL);
+
+       /* init tapi */
+       agent->tapi_handle = tel_init(NULL);
+       tapi_result = tel_get_sim_msisdn(agent->tapi_handle,
+                       __bluetooth_pb_tel_callback, agent);
+
+       if (tapi_result != TAPI_API_SUCCESS) {
+               __bluetooth_pb_agent_dbus_init(agent);
+       }
+
+
+       __bluetooth_pb_agent_timeout_add_seconds(agent);
+
+       g_main_loop_run(mainloop);
+
+       if (contacts_db_remove_changed_cb(_contacts_event._uri,
+                       __bluetooth_pb_contact_changed,
+                       g_object_ref(agent)) != CONTACTS_ERROR_NONE) {
+               DBG("Cannot remove changed callback");
+       }
+
+       g_object_unref(agent);
+
+       if (contacts_disconnect2() != CONTACTS_ERROR_NONE)
+               DBG("contacts_disconnect2 failed \n");
+
+       g_signal_emit(agent, signals[CLEAR], 0);
+
+       g_object_unref(agent);
+
+       DBG("Terminate Bluetooth PBAP agent");
+       return ret;
+}
diff --git a/wearable/pb-agent/bluetooth_pb_agent.h b/wearable/pb-agent/bluetooth_pb_agent.h
new file mode 100644 (file)
index 0000000..bdaf708
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_PB_AGENT_H_
+#define __DEF_BT_PB_AGENT_H_
+
+#include <unistd.h>
+#include <dlog.h>
+
+#include <stdio.h>
+
+#include <dbus/dbus-glib.h>
+
+#define BT_PB_SERVICE_OBJECT_PATH      "/org/bluez/pb_agent"
+#define BT_PB_SERVICE_NAME             "org.bluez.pb_agent"
+#define BT_PB_SERVICE_INTERFACE                "org.bluez.PbAgent"
+
+#undef LOG_TAG
+#define LOG_TAG "BT_PB_AGENT"
+#define DBG(fmt, args...) SLOGD(fmt, ##args)
+#define ERR(fmt, args...) SLOGE(fmt, ##args)
+
+#ifdef _SECURE_LOG
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+#else /* _SECURE_LOG */
+#define DBG_SECURE(...) (0)
+#define ERR_SECURE(...) (0)
+#endif /* _SECURE_LOG */
+
+#endif                         /* __DEF_BT_AGENT_H_ */
diff --git a/wearable/pb-agent/bluetooth_pb_agent.xml b/wearable/pb-agent/bluetooth_pb_agent.xml
new file mode 100644 (file)
index 0000000..e9f758b
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+       <interface name="org.bluez.PbAgent">
+               <method name="GetPhonebookFolderList">
+                       <arg type="as" name="folder_list" direction="out"/>
+               </method>
+
+               <method name="GetPhonebook">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="name"/>
+                       <arg type="t" name="filter"/>
+                       <arg type="y" name="format"/>
+                       <arg type="q" name="max_list_count"/>
+                       <arg type="q" name="list_start_offset"/>
+                       <arg type="as" name="phonebook" direction="out"/>
+                       <arg type="u" name="new_missed_call" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookSize">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="name"/>
+                       <arg type="u" name="phonebook_size" direction="out"/>
+                       <arg type="u" name="new_missed_call" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookList">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="name"/>
+                       <arg type="a(ssu)" name="phonebook_list" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookEntry">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="folder"/>
+                       <arg type="s" name="id"/>
+                       <arg type="t" name="filter"/>
+                       <arg type="y" name="format"/>
+                       <arg type="s" name="phonebook_entry" direction="out"/>
+               </method>
+
+               <method name="GetTotalObjectCount">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="path"/>
+                       <arg type="u" name="phonebook_size" direction="out"/>
+               </method>
+
+               <method name="AddContact">
+                       <arg type="s" name="filename"/>
+               </method>
+
+               <method name="DestroyAgent">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+               </method>
+
+               <signal name="clear"/>
+
+       </interface>
+
+       <interface name="org.bluez.PbAgent.At">
+               <method name="GetPhonebookSizeAt">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="command"/>
+                       <arg type="u" name="phonebook_size" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookEntriesAt">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="command"/>
+                       <arg type="i" name="start_index"/>
+                       <arg type="i" name="end_index"/>
+                       <arg type="a(ssu)" name="phonebook_entries" direction="out"/>
+               </method>
+
+               <method name="GetPhonebookEntriesFindAt">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="command"/>
+                       <arg type="s" name="find_text" />
+                       <arg type="a(ssu)" name="phonebook_entries" direction="out"/>
+               </method>
+       </interface>
+</node>
diff --git a/wearable/pb-agent/bluetooth_pb_vcard.c b/wearable/pb-agent/bluetooth_pb_vcard.c
new file mode 100644 (file)
index 0000000..e9979ff
--- /dev/null
@@ -0,0 +1,2779 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *              Jaekyun Lee <jkyun.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <time.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <vconf.h>
+#include <dlog.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <contacts.h>
+#include <image_util.h>
+#include <libexif/exif-data.h>
+#include <unistd.h>
+
+#include "bluetooth_pb_vcard.h"
+
+#define BT_PB_AGENT    "BT_PB_AGENT"
+#define DBG(fmt, args...) SLOG(LOG_DEBUG, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
+#define ERR(fmt, args...) SLOG(LOG_ERROR, BT_PB_AGENT, "%s():%d "fmt, __func__, __LINE__, ##args)
+
+#ifdef _SECURE_LOG
+#define DBG_SECURE(fmt, args...) SECURE_SLOGD(fmt, ##args)
+#define ERR_SECURE(fmt, args...) SECURE_SLOGE(fmt, ##args)
+#else /* _SECURE_LOG */
+#define DBG_SECURE(...) (0)
+#define ERR_SECURE(...) (0)
+#endif /* _SECURE_LOG */
+
+
+#define VCARD_FORMAT_2_1 0x0
+#define VCARD_FORMAT_3_0 0x1
+
+#define VCARD_VERSION  (0x1)
+#define VCARD_FN       (0x1 << 1)
+#define VCARD_N                (0x1 << 2)
+#define VCARD_PHOTO    (0x1 << 3)
+#define VCARD_BDAY     (0x1 << 4)
+#define VCARD_ADR      (0x1 << 5)
+#define VCARD_LABEL    (0x1 << 6)      /* not supported */
+#define VCARD_TEL      (0x1 << 7)
+#define VCARD_EMAIL    (0x1 << 8)
+#define VCARD_MAILER   (0x1 << 9)      /* not supported */
+#define VCARD_TZ       (0x1 << 10)     /* not supported */
+#define VCARD_GEO      (0x1 << 11)     /* not supported */
+#define VCARD_TITLE    (0x1 << 12)
+#define VCARD_ROLE     (0x1 << 13)
+#define VCARD_LOGO     (0x1 << 14)     /* not supported */
+#define VCARD_AGENT    (0x1 << 15)     /* not supported */
+#define VCARD_ORG      (0x1 << 16)
+#define VCARD_NOTE     (0x1 << 17)
+#define VCARD_REV      (0x1 << 18)
+#define VCARD_SOUND    (0x1 << 19)     /* not supported */
+#define VCARD_URL      (0x1 << 20)
+#define VCARD_UID      (0x1 << 21)
+#define VCARD_KEY      (0x1 << 22)     /* not supported */
+#define VCARD_NICKNAME (0x1 << 23)
+#define VCARD_CATEGORIES       (0x1 << 24)     /* not supported */
+#define VCARD_PROID    (0x1 << 25)     /* not supported */
+#define VCARD_CLASS    (0x1 << 26)     /* not supported */
+#define VCARD_SORT_STRING      (0x1 << 27)     /* not supported */
+#define VCARD_X_IRMC_CALL_DATETIME     (0x1 << 28)
+
+#define QP_ENC_LEN     3
+#define LINEBREAK_LEN  75
+
+typedef struct {
+       const char *src;
+       const char *dest;
+       int ret;
+       contacts_record_h person;
+       GString *string;
+} bt_image_info_t;
+
+gchar dest_thumb_path[255];
+#define PBAP_IMAGE_THUMB_SIZE 48
+#define PBAP_THMB_PATH "_thumb"
+#define PBAP_THUMB_FILE_SIZE 4096
+#define PBAP_IMAGE_ENCODE_QUALITY      90
+#define PBAP_SECURITY_FILE_GROUP 6005
+#define PBAP_SECURITY_DEFAULT_PERMISSION 0660
+#define PBAP_SECURITY_DIR_DEFAULT_PERMISSION 0770
+#define PBAP_SECURITY_IMAGE_PERMISSION 0440
+
+static gchar *__bluetooth_pb_vcard_escape(const gchar *str);
+
+static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
+                                       const gchar *delimeter);
+
+static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str);
+
+static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
+                                               gint len);
+
+static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
+                                                       const gchar *str,
+                                                       gint len,
+                                                       gint *line_pos);
+
+static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
+                                                       gchar ch,
+                                                       gint *line_pos);
+
+static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
+                                               const gchar *str,
+                                               gint len,
+                                               gint *line_pos);
+
+static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str);
+
+static void __bluetooth_pb_vcard_append_param_v21(GString *string,
+                                                const gchar *param);
+
+static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
+                                       const gchar *name,
+                                       const gchar *param,
+                                       const gchar *value);
+
+static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
+                                                       const gchar *name,
+                                                       const gchar *param,
+                                                       const gchar *value,
+                                                       gsize len,
+                                                       gboolean folding);
+
+static void __bluetooth_pb_vcard_append_n_v21(GString *string,
+                                       contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
+                                       contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
+                                               contacts_record_h conatct);
+
+static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
+                                       contacts_record_h person);
+
+static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
+                                               contacts_record_h person);
+
+static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_email_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_title_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_role_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_org_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_note_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_url_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
+                                               contacts_record_h contact);
+
+static void __bluetooth_pb_vcard_append_v30(GString *string,
+                                       const gchar *name,
+                                       const gchar *param,
+                                       const gchar *value);
+
+static void __bluetooth_pb_vcard_remove_v30(GString *string,
+                                       const gchar *property_name);
+
+static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
+                                       guint64 filter);
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args);
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args);
+
+static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       guint8 format,
+                                                       const gchar *first_name,
+                                                       ...);
+
+static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
+                                               guint filter,
+                                               const gchar *attr);
+
+static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
+                                               guint filter,
+                                               const gchar *attr);
+
+static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
+                                       guint filter,
+                                       guint8 format,
+                                       const gchar *attr);
+
+static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
+                                               int *field,
+                                               gint field_size);
+
+static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number);
+
+static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename);
+
+static gchar **__bluetooth_pb_contact_addr(contacts_record_h address);
+
+static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address);
+
+static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id);
+
+static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact);
+
+static gchar *__bluetooth_pb_phonetic_first_from_contact(contacts_record_h contact);
+
+static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact);
+
+static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id);
+
+
+static gchar *__bluetooth_pb_vcard_escape(const gchar *str)
+{
+       GString *escaped;
+
+       gchar *st = NULL;
+       gchar *pos = NULL;
+
+       if (str == NULL)
+               return NULL;
+
+       escaped = g_string_new(NULL);
+
+       st = (gchar *)str;
+       pos = st;
+
+       while (*pos != '\0') {
+               if (*pos == ';') {
+                       g_string_append_len(escaped, st, (pos - st));
+                       g_string_append(escaped, "\\;");
+
+                       pos++;
+                       st = pos;
+               } else {
+                       pos++;
+               }
+       }
+
+       g_string_append_len(escaped, st, (pos - st));
+       return g_string_free(escaped, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_strv_concat(gchar **strv,
+                                       const gchar *separator)
+{
+       GString *string = g_string_new(NULL);
+       gint i;
+
+       for (i = 0; strv[i] != NULL; i++) {
+               if (i > 0)
+                       g_string_append(string, ";");
+
+               g_string_append(string, strv[i]);
+       }
+
+       return g_string_free(string, FALSE);
+}
+
+static gboolean __bluetooth_pb_vcard_qp_encode_check(const gchar *str)
+{
+       gchar *pos = NULL;
+
+       if (str == NULL)
+               return FALSE;
+
+       pos = (gchar *)str;
+       while (*pos != '\0') {
+               /* ascii code ' ' : 32, '~' : 126 */
+               if ((guchar)*pos < ' ' || (guchar)*pos > '~')
+                       return TRUE;
+
+               pos++;
+       }
+       return FALSE;
+}
+
+/* get string length, which convert to quoted-printable encoding */
+static gint __bluetooth_pb_vcard_qp_encode_strlen(const gchar *str,
+                                               gint len)
+{
+       gchar *pos;
+
+       gint count = 0;
+       gint length = len;
+
+       if (str == NULL)
+               return 0;
+
+       if (strlen(str) < len)
+               length = -1;
+
+       pos = (gchar *)str;
+
+       while (*pos != '\0' && (((pos - str) < length) || length < 0)) {
+               if ((guchar)*pos == '\t') {
+                       count++;
+                       pos++;
+                       continue;
+               }
+
+               if ((guchar)*pos < ' ' || (guchar)*pos == '=') {
+                       count += QP_ENC_LEN;
+                       pos++;
+                       continue;
+               }
+
+               /* check no-ascii utf-8 character */
+               if ((guchar)*pos > '~') {
+
+                       gchar *next;
+
+                       next = g_utf8_next_char(pos);
+
+                       count += QP_ENC_LEN * (next - pos);
+                       pos = next;
+                       continue;
+               }
+
+               pos++;
+               count++;
+       }
+
+       return count;
+}
+
+/* convert to quoted printable code */
+static void __bluetooth_pb_vcard_qp_encode_append_to_hex(GString *string,
+                                                       const gchar *str,
+                                                       gint len,
+                                                       gint *line_pos)
+{
+       int i;
+
+       if (str == NULL || len == 0)
+               return;
+
+       /* add soft linebreak when it exceed */
+       if ((*line_pos + (QP_ENC_LEN * len) > LINEBREAK_LEN)) {
+               g_string_append(string, "=\r\n");
+               *line_pos = 0;
+       }
+
+       for (i = 0; i < len; i++) {
+               g_string_append_printf(string, "=%02X", (guchar)*(str+i));
+               *line_pos += QP_ENC_LEN;
+       }
+}
+
+/* append plain visiable ascii character */
+static void __bluetooth_pb_vcard_qp_encode_append_printable_c(GString *string,
+                                                       gchar ch,
+                                                       gint *line_pos)
+{
+       /* add soft linebreak when it exceed */
+       if (*line_pos + 1 > LINEBREAK_LEN) {
+               g_string_append(string, "=\r\n");
+               *line_pos = 0;
+       }
+       g_string_append_c(string, ch);
+       (*line_pos)++;
+}
+
+static void __bluetooth_pb_vcard_qp_encode_append(GString *string,
+                                               const gchar *str,
+                                               gint len,
+                                               gint *line_pos)
+{
+       gint length;
+       gint encode_len;
+
+       gint i = 0;
+
+       if (string == NULL)
+               return;
+
+       encode_len = __bluetooth_pb_vcard_qp_encode_strlen(str, len);
+
+       /* add soft linebreak when it exceed */
+       if (((*line_pos + encode_len) > LINEBREAK_LEN) && (*line_pos > 1)) {
+               g_string_append(string, "=\r\n");
+               *line_pos = 0;
+       }
+
+       length = strlen(str);
+       if (length > len)
+               length = len;
+
+       while (i < len) {
+               gchar *pos;
+
+               pos = ((gchar *)str) + i;
+
+               /* converts invisiable character and escape character '='
+                       to quoted-printable */
+               if ((guchar)*pos != '\t' &&
+                               ((guchar)*pos < ' ' || (guchar)*pos == '=')) {
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
+                                                       pos, 1, line_pos);
+                       i++;
+
+                       continue;
+               }
+
+               /* converts non-ascii utf-8 character to quoted-printable */
+               if ((guchar)*pos > '~') {
+                       gchar *next;
+                       int ch_len;
+
+                       next = g_utf8_next_char(pos);
+
+                       ch_len = next - pos;
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(string,
+                                                       pos, ch_len, line_pos);
+                       i += ch_len;
+
+                       continue;
+               }
+
+               __bluetooth_pb_vcard_qp_encode_append_printable_c(string, *pos,
+                                                               line_pos);
+               i++;
+       }
+}
+
+static gchar *__bluetooth_pb_vcard_qp_encode(const gchar *str)
+{
+       GString *enc;
+
+       gchar *st_pos;
+       gchar *pos;
+
+       gint line_pos = 0;
+
+       if (str == NULL)
+               return NULL;
+
+       enc = g_string_new(NULL);
+
+       st_pos = (gchar *)str;
+       pos = (gchar *)str;
+
+       while (*pos != '\0') {
+               /* split string with given delimeter ' ' or '\t' */
+               if (*pos == ' ' || *pos == '\t') {
+                       __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
+                                       (pos - st_pos), &line_pos);
+
+                       st_pos = pos;
+                       pos++;
+
+                       continue;
+               }
+
+               /* split string with given delimeter '\r', '\n' or
+                       '\r\n' - newline */
+               if (*pos == '\r' || *pos == '\n') {
+                       __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
+                                       (pos - st_pos), &line_pos);
+
+                       /* converts newline to qp_encode with soft linebreak
+                        for example, converts \r\n to =0D=0A=\r\n */
+                       __bluetooth_pb_vcard_qp_encode_append_to_hex(enc,
+                                                       "\r\n", 2, &line_pos);
+                       g_string_append(enc, "=\r\n ");
+
+                       line_pos = 1;
+
+                       if (*pos == '\r' && *(pos + 1) == '\n')
+                               pos += 2;
+                       else
+                               pos++;
+
+                       st_pos = pos;
+
+                       continue;
+               }
+
+               pos++;
+       }
+
+       __bluetooth_pb_vcard_qp_encode_append(enc, st_pos,
+                       (pos - st_pos), &line_pos);
+
+       return g_string_free(enc, FALSE);
+}
+
+static void __bluetooth_pb_vcard_append_param_v21(GString *string,
+                                                const gchar *param)
+{
+       gchar *pos = NULL;
+
+       if (param == NULL)
+               return;
+
+       pos = (gchar *)param;
+
+       /* trim ';' on first */
+       while (*pos != '\0') {
+               if (*pos != ';')
+                       break;
+
+               pos++;
+       }
+
+       if (*pos != '\0')
+               g_string_append_printf(string, ";%s", pos);
+}
+
+static void __bluetooth_pb_vcard_append_qp_encode_v21(GString *string,
+                                               const gchar *name,
+                                               const gchar *param,
+                                               const gchar *value)
+{
+       GString *property = NULL;
+
+       if (name == NULL)
+               return;
+
+       property = g_string_new(name);
+       __bluetooth_pb_vcard_append_param_v21(property, param);
+
+       if (__bluetooth_pb_vcard_qp_encode_check(value)) {
+               gchar *enc = NULL;
+
+               __bluetooth_pb_vcard_append_param_v21(property,
+                               "CHARSET=UTF-8");
+               __bluetooth_pb_vcard_append_param_v21(property,
+                               "ENCODING=QUOTED-PRINTABLE");
+               g_string_append(property, ":");
+
+               enc = __bluetooth_pb_vcard_qp_encode(value);
+
+               if (enc) {
+                       g_string_append(property, enc);
+                       g_free(enc);
+               }
+       } else {
+               g_string_append(property, ":");
+               if (value)
+                       g_string_append(property , value);
+       }
+
+       g_string_append_printf(string, "%s\r\n", property->str);
+
+       g_string_free(property, TRUE);
+}
+
+
+static void __bluetooth_pb_vcard_append_base64_encode_v21(GString *string,
+                                                       const gchar *name,
+                                                       const gchar *param,
+                                                       const gchar *value,
+                                                       gsize len,
+                                                       gboolean folding)
+{
+       gchar *enc = NULL;
+
+       if (name == NULL)
+               return;
+       DBG("base 64 encoding\n");
+
+       g_string_append(string, name);
+
+       __bluetooth_pb_vcard_append_param_v21(string, param);
+       __bluetooth_pb_vcard_append_param_v21(string, "ENCODING=BASE64");
+
+       g_string_append(string, ":");
+
+       if (value == NULL)
+               return;
+
+       enc = g_base64_encode((const guchar *)value, len);
+
+       if (folding == FALSE) {
+               g_string_append(string, enc);
+       } else {
+               gint enc_len = strlen(enc);
+               gint i = 0;
+
+               /* count ' ' size for folding */
+               gint fline_len = LINEBREAK_LEN - 1;
+
+               for (i = 0; (i * fline_len) < enc_len; i++) {
+                       g_string_append(string, "\r\n ");
+                       if ((i * fline_len) + fline_len > enc_len)
+                               g_string_append(string, enc + (i * fline_len));
+                       else
+                               g_string_append_len(string, enc +
+                                               (i * fline_len), fline_len);
+               }
+
+               /* some application requires more \r\n */
+               g_string_append(string, "\r\n");
+       }
+       g_string_append(string, "\r\n");
+       DBG("base 64 encoding\n");
+
+       g_free(enc);
+}
+
+static void __bluetooth_pb_vcard_append_n_v21(GString *string,
+                                       contacts_record_h contact)
+{
+       gchar *str;
+
+       str = __bluetooth_pb_name_from_contact(contact);
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "N", NULL, str);
+
+       g_free(str);
+}
+
+static void __bluetooth_pb_vcard_append_phonetic_first_v21(GString *string,
+                                       contacts_record_h contact)
+{
+       gchar *str;
+
+       str = __bluetooth_pb_phonetic_first_from_contact(contact);
+
+       if (str != NULL) {
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "SOUND", "X-IRMC-N", str);
+               g_free(str);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_tel_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint i;
+       gint status;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.number,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h number = NULL;
+
+               gchar **paramv = NULL;
+               gchar *param = NULL;
+
+               gchar *tel = NULL;
+               gchar *escaped = NULL;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, i, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tel);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tel);
+
+               paramv = __bluetooth_pb_contact_tel_param(number);
+               param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
+
+               g_strfreev(paramv);
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "TEL", param,
+                                                               escaped);
+
+               g_free(escaped);
+               g_free(param);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_fn_v21(GString *string,
+                                       contacts_record_h person)
+{
+       gint status;
+
+       gchar *fn = NULL;
+       gchar *tmp = NULL;
+
+       status = contacts_record_get_str_p(person,
+                       _contacts_person.display_name,
+                       &tmp);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       fn = __bluetooth_pb_vcard_escape(tmp);
+
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "FN", NULL, fn);
+
+       g_free(fn);
+}
+
+static image_util_rotation_e __bt_pbap_get_rotation_info(const char *path)
+{
+       ExifData *ed = NULL;
+       ExifEntry *entry;
+       image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+       int orientation = 0;
+
+       ed = exif_data_new_from_file(path);
+       if (ed == NULL) {
+               DBG("exif_data_new_from_file : ExifData is NULL");
+               return IMAGE_UTIL_ROTATION_NONE;
+       }
+
+       entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
+       if (entry) {
+               ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
+               orientation = (int)exif_get_short(entry->data, mByteOrder);
+               if (orientation < 0 || orientation > 8)
+                       orientation = 0;
+       }
+
+       exif_data_unref(ed);
+
+       switch (orientation) {
+       case 1: /* Top-left */
+               rotation = IMAGE_UTIL_ROTATION_NONE;
+               break;
+       case 2: /* Top-right */
+               rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
+               break;
+       case 3: /* Bottom-right */
+               rotation = IMAGE_UTIL_ROTATION_180;
+               break;
+       case 4: /* Bottom-left */
+               rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
+               break;
+       case 6: /* Right-top */
+               rotation = IMAGE_UTIL_ROTATION_90;
+               break;
+       case 8: /* Left-bottom */
+               rotation = IMAGE_UTIL_ROTATION_270;
+               break;
+       case 5: /* Left-top */
+       case 7: /* Right-bottom */
+       case 0:
+       default:
+               break;
+       };
+
+       return rotation;
+}
+
+
+static bool __bt_pbap_image_util_supported_jpeg_colorspace_cb(
+                       image_util_colorspace_e colorspace, void *user_data)
+{
+       unsigned char *img_target = 0;
+       unsigned char *img_source = 0;
+       gchar *type = NULL;
+       gchar *param = NULL;
+       gchar *contents = NULL;
+       int width = 0;
+       int height = 0;
+       int resized_width = 0;
+       int resized_height = 0;
+       int dest_fd = 0;
+       unsigned int size_decode = 0;
+       image_util_rotation_e rotation;
+       image_util_error_e ret = 0;
+       gsize len = 0;
+
+       bt_image_info_t *info = (bt_image_info_t *)user_data;
+       rotation = __bt_pbap_get_rotation_info(info->src);
+       ret = image_util_decode_jpeg(info->src, colorspace, &img_source, &width,
+                                                       &height, &size_decode);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               ERR("Can not decode");
+               memset(info, 0x00, sizeof(bt_image_info_t));
+               return true;
+       }
+
+       DBG("decoding completed width = %d, height = %d, size = %d\n", width,
+                                                       height, size_decode);
+       if (width > PBAP_IMAGE_THUMB_SIZE  || height > PBAP_IMAGE_THUMB_SIZE) {
+               if (width <= 0 || height <= 0) {
+                       free(img_source);
+                       ERR("image size error(%d)", PBAP_IMAGE_THUMB_SIZE);
+                       memset(info, 0x00, sizeof(bt_image_info_t));
+                       return false;
+               }
+
+               if (width > height) {
+                       resized_width = PBAP_IMAGE_THUMB_SIZE ;
+                       resized_height = height * PBAP_IMAGE_THUMB_SIZE / width;
+               } else {
+                       resized_height = PBAP_IMAGE_THUMB_SIZE;
+                       resized_width = width * PBAP_IMAGE_THUMB_SIZE / height;
+               }
+
+               if (resized_height % 8)
+                       resized_height += 8 - (resized_height % 8);
+               if (resized_width % 8)
+                       resized_width += 8 - (resized_width % 8);
+
+               DBG("original size[%d, %d] changed to resize[%d,%d]", width,
+                                       height, resized_width, resized_height);
+
+               ret = image_util_calculate_buffer_size(resized_width,
+                                                       resized_height,
+                                                       colorspace ,
+                                                       &size_decode);
+
+               img_target = g_malloc0(size_decode);
+
+               /* do resize */
+               ret = image_util_resize(img_target, &resized_width,
+                                       &resized_height, img_source, width,
+                                       height, colorspace);
+               if (ret != IMAGE_UTIL_ERROR_NONE) {
+                       ERR("image_util_resize failed(%d)", ret);
+                       g_free(img_target);
+                       free(img_source);
+                       memset(info, 0x00, sizeof(bt_image_info_t));
+                       return false;
+               }
+               free(img_source);
+       } else {
+               resized_width = width;
+               resized_height = height;
+               img_target = img_source;
+       }
+       DBG("Resized w = %d, ht = %d, size = %d\n", width, height, size_decode);
+
+       if (IMAGE_UTIL_ROTATION_NONE != rotation) {
+               int rotated_width, rotated_height;
+               unsigned char *img_rotate = 0;
+               img_rotate = g_malloc0(size_decode);
+               image_util_rotate(img_rotate, &rotated_width, &rotated_height,
+                                       rotation, img_target, resized_width,
+                                       resized_height, colorspace);
+               resized_width = rotated_width;
+               resized_height = rotated_height;
+               g_free(img_target);
+               img_target = img_rotate;
+       }
+
+       /* image encode */
+       ret = image_util_encode_jpeg(img_target, resized_width, resized_height,
+                                       colorspace, PBAP_IMAGE_ENCODE_QUALITY,
+                                       info->dest);
+       g_free(img_target);
+       if (ret != IMAGE_UTIL_ERROR_NONE) {
+               ERR("image_util_encode_jpeg failed(%d)", ret);
+               info->ret = CONTACTS_ERROR_INTERNAL;
+               goto done;
+       }
+       DBG("Encoding done\n");
+
+       dest_fd = open(info->dest, O_RDONLY);
+       if (dest_fd < 0) {
+               ERR("System : Open Failed(%d)", errno);
+               ERR_SECURE("Open : dest path(%s)", info->dest);
+               goto done;
+       }
+
+       ret = fchown(dest_fd, getuid(), PBAP_SECURITY_FILE_GROUP);
+       if (0 != ret) {
+               DBG("fchown Failed(%d)", errno);
+               DBG_SECURE("fchown : dest path(%s)", info->dest);
+               close(dest_fd);
+               goto done;
+       }
+
+       ret = fchmod(dest_fd, PBAP_SECURITY_IMAGE_PERMISSION);
+       if (0 != ret) {
+               ERR("fchmod Failed(%d)", errno);
+               ERR_SECURE("fchmod : dest path(%s)", info->dest);
+               close(dest_fd);
+               goto done;
+       }
+       close(dest_fd);
+
+       info->ret = CONTACTS_ERROR_NONE;
+       type = __bluetooth_pb_contact_photo_type(info->dest);
+       DBG("Cintact image thumb type is = %s\n", type);
+
+       if (type) {
+               param = g_strdup_printf("TYPE=%s", type);
+               g_free(type);
+       }
+
+       if (g_file_get_contents(info->dest, &contents, &len, NULL) == FALSE) {
+               ERR("can not read file contents:%s\n", info->dest);
+               goto done;
+       }
+
+       __bluetooth_pb_vcard_append_base64_encode_v21(info->string,
+                       "PHOTO", param, contents, len, TRUE);
+
+done:
+       g_free(param);
+       g_free(contents);
+       remove(info->dest);
+       memset(info, 0x00, sizeof(bt_image_info_t));
+       DBG("Cintact image thumb created successfuly\n");
+       return false;
+}
+
+static void __bluetooth_pb_vcard_append_photo_v21(GString *string,
+                                               contacts_record_h person)
+{
+       gint status;
+       gchar *filename = NULL;
+       int res = 0;
+       bt_image_info_t img_info;
+       struct stat stat_info;
+       gchar *type = NULL;
+       gchar *param = NULL;
+       gchar *contents = NULL;
+       gsize len = 0;
+       char *ptr = NULL;
+
+       DBG("PBAP +\n");
+
+       status = contacts_record_get_str_p(person,
+                       _contacts_person.image_thumbnail_path,
+                       &filename);
+
+       if (status != CONTACTS_ERROR_NONE || NULL == filename)
+               return;
+
+       stat_info.st_size = 0;
+
+       if (0 > stat(filename, &stat_info)) {
+               ERR("fstat failed, file does not exist %s", filename);
+       }
+
+       if (PBAP_THUMB_FILE_SIZE > stat_info.st_size) {
+               DBG_SECURE("File size small, so use thubnail %s\n", filename);
+
+               type = __bluetooth_pb_contact_photo_type(filename);
+               if (type) {
+                       param = g_strdup_printf("TYPE=%s", type);
+                       g_free(type);
+               }
+
+               if (g_file_get_contents(filename, &contents, &len, NULL) ==
+                                                                       FALSE) {
+                       ERR("can not read file contents:%s\n", filename);
+                       g_free(param);
+                       return;
+               }
+               DBG("Retrieved the contents of the file \n");
+               __bluetooth_pb_vcard_append_base64_encode_v21(string,
+                               "PHOTO", param, contents, len, TRUE);
+
+               g_free(param);
+               g_free(contents);
+               return;
+       }
+
+       ptr = strrchr(filename, '.');
+       if (NULL != ptr) {
+               memset(dest_thumb_path, 0x00, sizeof(dest_thumb_path));
+               g_strlcpy(dest_thumb_path, filename, ptr - filename);
+               g_strlcat(dest_thumb_path, PBAP_THMB_PATH,
+                                               sizeof(dest_thumb_path));
+               g_strlcat(dest_thumb_path, ptr, sizeof(dest_thumb_path));
+               DBG("Thumbnail path is = %s", dest_thumb_path);
+       }
+       DBG_SECURE("filename = %s Thumbnail path is = %s", filename, dest_thumb_path);
+       img_info.src = filename;
+       img_info.dest = dest_thumb_path;
+       img_info.ret = CONTACTS_ERROR_INTERNAL;
+       img_info.person = person;
+       img_info.string = string;
+
+       res = image_util_foreach_supported_jpeg_colorspace(
+               __bt_pbap_image_util_supported_jpeg_colorspace_cb, &img_info);
+       if (res != IMAGE_UTIL_ERROR_NONE) {
+               ERR("Image resizing is failed");
+       }
+       DBG("PBAP -\n");
+       return;
+}
+
+static void __bluetooth_pb_vcard_append_bday_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.event, &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h event = NULL;
+
+               gint date;
+
+               gchar *bday;
+
+               contacts_event_type_e type;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.event, i, &event);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_int(event,
+                               _contacts_event.type,
+                               (gint *) &type);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (type != CONTACTS_EVENT_TYPE_BIRTH)
+                       continue;
+
+               status = contacts_record_get_int(event,
+                               _contacts_event.date,
+                               &date);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (date <= 0)
+                       continue;
+
+               bday = g_strdup_printf("%04d-%02d-%02d",
+                               (date/10000), (date/100)%100, date%100);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "BDAY",
+                               NULL, bday);
+               g_free(bday);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_adr_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.address,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h address = NULL;
+
+               gchar **addrv;
+               gchar **paramv;
+
+               gchar *addr;
+               gchar *param;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.address, i, &address);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               addrv = __bluetooth_pb_contact_addr(address);
+
+               if (addrv == NULL)
+                       continue;
+
+               addr = __bluetooth_pb_vcard_strv_concat(addrv, ";");
+               g_strfreev(addrv);
+
+               paramv = __bluetooth_pb_contact_addr_param(address);
+               param = __bluetooth_pb_vcard_strv_concat(paramv, ";");
+               g_strfreev(paramv);
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ADR",
+                               param, addr);
+
+               g_free(param);
+               g_free(addr);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_email_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.email,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h email = NULL;
+
+               gchar *tmp = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.email, i, &email);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(email,
+                               _contacts_email.email,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tmp);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "EMAIL", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_title_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.company,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h company = NULL;
+
+               char *title = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                                       _contacts_contact.company, i, &company);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(company,
+                               _contacts_company.job_title,
+                               &title);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(title);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "TITLE", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_role_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.company,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h company = NULL;
+
+               char *role = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.company, i, &company);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(company,
+                               _contacts_company.role,
+                               &role);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(role);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ROLE", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_org_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.company,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h company = NULL;
+
+               GString *str;
+
+               gchar *name = NULL;
+               gchar *department = NULL;
+
+               gint name_status;
+               gint department_status;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.company, i, &company);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+
+               name_status = contacts_record_get_str_p(company,
+                               _contacts_company.name,
+                               &name);
+
+               department_status = contacts_record_get_str_p(company,
+                               _contacts_company.department,
+                               &department);
+
+               if ((name_status != CONTACTS_ERROR_NONE) &&
+                               (department_status != CONTACTS_ERROR_NONE))
+                       continue;
+
+               str = g_string_new(NULL);
+
+               if (name) {
+                       gchar *escaped;
+
+                       escaped = __bluetooth_pb_vcard_escape(name);
+                       g_string_append(str, escaped);
+                       g_free(escaped);
+               }
+
+               g_string_append(str, ";");
+
+               if (department) {
+                       gchar *escaped;
+
+                       escaped = __bluetooth_pb_vcard_escape(department);
+                       g_string_append(str, escaped);
+                       g_free(escaped);
+               }
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "ORG", NULL,
+                                                               str->str);
+
+               g_string_free(str, TRUE);
+
+       }
+}
+
+static void __bluetooth_pb_vcard_append_note_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.note,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h note = NULL;
+
+               char *tmp = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.note, i, &note);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_str_p(note,
+                               _contacts_note.note,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tmp);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "NOTE", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_rev_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       gint time = 0;
+       gint status;
+
+       gchar *rev;
+       struct tm result;
+
+       status = contacts_record_get_int(contact,
+                       _contacts_contact.changed_time,
+                       &time);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       if (time <= 0)
+               return;
+
+       gmtime_r((const time_t *)(&time), &result);
+
+       rev = g_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02dZ",
+                       (1900 + result.tm_year), (1 + result.tm_mon),
+                       result.tm_mday, result.tm_hour, result.tm_min,
+                       result.tm_sec);
+
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "REV", NULL, rev);
+
+       g_free(rev);
+}
+
+static void __bluetooth_pb_vcard_append_url_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint i;
+       gint status;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.url,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h url = NULL;
+
+               gchar *tmp = NULL;
+               gchar *escaped;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.url, i, &url);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return;
+
+               if (url == NULL)
+                       continue;
+
+               status = contacts_record_get_str_p(url,
+                               _contacts_url.url,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escaped = __bluetooth_pb_vcard_escape(tmp);
+               __bluetooth_pb_vcard_append_qp_encode_v21(string, "URL", NULL,
+                                                               escaped);
+
+               g_free(escaped);
+       }
+}
+
+static void __bluetooth_pb_vcard_append_uid_v21(GString *string,
+                                               contacts_record_h contact)
+{
+       int status;
+
+       gchar *uid = NULL;
+       gchar *escaped;
+
+       status = contacts_record_get_str_p(contact,
+                       _contacts_contact.uid,
+                       &uid);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return;
+
+       escaped = __bluetooth_pb_vcard_escape(uid);
+       __bluetooth_pb_vcard_append_qp_encode_v21(string, "UID", NULL, escaped);
+
+       g_free(escaped);
+}
+
+static void __bluetooth_pb_vcard_append_v30(GString *string,
+                                       const gchar *name,
+                                       const gchar *param,
+                                       const gchar *value)
+{
+       if (string == NULL)
+               return;
+       if (name == NULL)
+               return;
+
+       g_string_append(string, name);
+
+       if (param)
+               g_string_append_printf(string, ";%s", param);
+
+       g_string_append(string, ":");
+
+       if (value)
+               g_string_append(string, value);
+
+       g_string_append(string, "\r\n");
+}
+
+static void __bluetooth_pb_vcard_remove_v30(GString *string,
+                                       const gchar *property_name)
+{
+       gchar *pos = NULL;
+       gchar *st_pos = NULL;
+
+       gboolean matched = FALSE;
+
+       if (string == NULL || property_name == NULL)
+               return;
+
+       pos = string->str;
+
+       while (*pos != '\0') {
+               if (matched == FALSE) {
+                       if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
+                               gint attrlen = 0;
+
+                               st_pos = pos;
+                               pos += 2;
+
+                               attrlen = strlen(property_name);
+                               if (g_ascii_strncasecmp(pos, property_name,
+                                                               attrlen) == 0) {
+                                       pos += attrlen;
+
+                                       if (*pos == ':' || *pos == ';') {
+                                               matched = TRUE;
+                                               pos++;
+                                       }
+                               }
+                               continue;
+                       }
+               } else {
+                       if (g_ascii_strncasecmp(pos, "\r\n", 2) == 0) {
+                               pos += 2;
+
+                               if (*pos != ' ' && *pos != '\t') {
+                                       /* +2 means move over \r\n */
+                                       g_string_erase(string,
+                                               (st_pos+2)-(string->str),
+                                               pos-(st_pos+2));
+
+                                       pos = st_pos;
+                                       matched = FALSE;
+                               }
+                               continue;
+                       }
+               }
+
+               pos++;
+       }
+}
+
+static gchar *__bluetooth_pb_vcard_filter_v30(const gchar *vcard,
+                                       guint64 filter)
+{
+       GString *string = NULL;
+
+       if (vcard == NULL)
+               return NULL;
+
+       string = g_string_new(vcard);
+
+       if ((filter & VCARD_PHOTO) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "PHOTO");
+
+       if ((filter & VCARD_BDAY) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "BDAY");
+
+       if ((filter & VCARD_ADR) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "ADR");
+
+       if ((filter & VCARD_EMAIL) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "EMAIL");
+
+       if ((filter & VCARD_TITLE) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "TITLE");
+
+       if ((filter & VCARD_ROLE) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "ROLE");
+
+       if ((filter & VCARD_ORG) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "ORG");
+
+       if ((filter & VCARD_NOTE) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "NOTE");
+
+       if ((filter & VCARD_REV) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "REV");
+
+       if ((filter & VCARD_URL) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "URL");
+
+       if ((filter & VCARD_UID) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "UID");
+
+       if ((filter & VCARD_NICKNAME) == 0)
+               __bluetooth_pb_vcard_remove_v30(string, "NICKNAME");
+
+       return g_string_free(string, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v21(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args)
+{
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       GString *str = NULL;
+
+       gint contact_id = 0;
+       gint status;
+
+       guint64 f = filter;
+
+       const gchar *name = first_name;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;;
+       }
+
+       if (f == 0)
+               f = ~f;
+
+       DBG("filter[%x]\n", filter);
+
+       str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
+
+       /* N, TEL is default */
+       __bluetooth_pb_vcard_append_n_v21(str, contact);
+
+       if (phonelog_id > 0) {
+               gchar *number;
+
+               number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0",
+                                                                       number);
+               g_free(number);
+
+
+       } else {
+               __bluetooth_pb_vcard_append_tel_v21(str, contact);
+       }
+
+       if (f & VCARD_FN)
+               __bluetooth_pb_vcard_append_fn_v21(str, person);
+/*     Need to check filter
+       if (f & VCARD_SOUND)*/
+               __bluetooth_pb_vcard_append_phonetic_first_v21(str, contact);
+       if (f & VCARD_PHOTO)
+               __bluetooth_pb_vcard_append_photo_v21(str, person);
+       if (f & VCARD_BDAY)
+               __bluetooth_pb_vcard_append_bday_v21(str, contact);
+       if (f & VCARD_ADR)
+               __bluetooth_pb_vcard_append_adr_v21(str, contact);
+       if (f & VCARD_EMAIL)
+               __bluetooth_pb_vcard_append_email_v21(str, contact);
+       if (f & VCARD_TITLE)
+               __bluetooth_pb_vcard_append_title_v21(str, contact);
+       if (f & VCARD_ROLE)
+               __bluetooth_pb_vcard_append_role_v21(str, contact);
+       if (f & VCARD_ORG)
+               __bluetooth_pb_vcard_append_org_v21(str, contact);
+       if (f & VCARD_NOTE)
+               __bluetooth_pb_vcard_append_note_v21(str, contact);
+       if (f & VCARD_REV)
+               __bluetooth_pb_vcard_append_rev_v21(str, contact);
+       if (f & VCARD_URL)
+               __bluetooth_pb_vcard_append_url_v21(str, contact);
+       if (f & VCARD_UID)
+               __bluetooth_pb_vcard_append_uid_v21(str, contact);
+
+       while (name) {
+               const gchar *param = va_arg(args, const gchar *);
+               const gchar *value = va_arg(args, const gchar *);
+
+               if (value) {
+                       gchar *escaped = NULL;
+
+                       escaped = __bluetooth_pb_vcard_escape(value);
+                       __bluetooth_pb_vcard_append_qp_encode_v21(str, name,
+                                                               param, escaped);
+
+                       g_free(escaped);
+               }
+
+               name = va_arg(args, const gchar *);
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       return g_string_free(str, FALSE);
+}
+
+
+static gchar *__bluetooth_pb_vcard_real_contact_valist_v30(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       const gchar *first_name,
+                                                       va_list args)
+{
+       contacts_record_h person = NULL;
+
+       GString *str = NULL;
+
+       gint status;
+
+       const gchar *name = first_name;
+       gchar *vcard = NULL;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_vcard_make_from_person(person, &vcard);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_destroy(person, TRUE);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       str = g_string_new(vcard);
+       g_free(vcard);
+
+       /* append contents on vcard */
+       while (name) {
+               const gchar *param = va_arg(args, const gchar *);
+               const gchar *value = va_arg(args, const gchar *);
+
+               __bluetooth_pb_vcard_append_v30(str, name, param, value);
+
+               name = va_arg(args, const gchar *);
+       }
+
+       /* if phonelog_id exist, we shall show only the phone number, which was
+          used for that phone log */
+       if (phonelog_id > 0) {
+               gchar *number;
+
+               __bluetooth_pb_vcard_remove_v30(str, "TEL");
+
+               number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+               __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
+               g_free(number);
+       }
+
+       vcard = g_string_free(str, FALSE);
+
+       /* temporary fixed for some application crash */
+       if (filter == 0)
+               filter = ~VCARD_NOTE;
+
+       if (filter) {
+               gchar *new_vcard = NULL;
+
+               new_vcard = __bluetooth_pb_vcard_filter_v30(vcard, filter);
+
+               if (new_vcard) {
+                       g_free(vcard);
+                       vcard = new_vcard;
+               }
+       }
+
+       return vcard;
+}
+
+
+static gchar *__bluetooth_pb_vcard_real_contact_with_properties(gint person_id,
+                                                       gint phonelog_id,
+                                                       guint64 filter,
+                                                       guint8 format,
+                                                       const gchar *first_name,
+                                                       ...)
+{
+       DBG(" format [%d]\n", format);
+       gchar *vcard = NULL;
+       va_list args;
+
+       va_start(args, first_name);
+
+       switch (format) {
+       case VCARD_FORMAT_3_0:
+               vcard = __bluetooth_pb_vcard_real_contact_valist_v30(person_id,
+                               phonelog_id, filter,
+                               first_name, args);
+               break;
+       case VCARD_FORMAT_2_1:
+       default:
+               vcard = __bluetooth_pb_vcard_real_contact_valist_v21(person_id,
+                               phonelog_id, filter,
+                               first_name, args);
+               break;
+       }
+
+       va_end(args);
+
+       return vcard;
+}
+
+static gchar *__bluetooth_pb_vcard_real_call_v21(gint phonelog_id,
+                                               guint filter,
+                                               const char *attr)
+{
+       GString *str;
+       gchar *number;
+
+       str = g_string_new("BEGIN:VCARD\r\nVERSION:2.1\r\n");
+
+       __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, NULL);
+
+       number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+       __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "X-0", number);
+       g_free(number);
+
+       if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
+                       && attr) {
+               gchar *datetime = NULL;
+
+               datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
+               __bluetooth_pb_vcard_append_qp_encode_v21(str,
+                                                       "X-IRMC-CALL-DATETIME",
+                                                       attr, datetime);
+               g_free(datetime);
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       return g_string_free(str, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_real_call_v30(gint phonelog_id,
+                                               guint filter,
+                                               const gchar *attr)
+{
+       GString *str;
+       gchar *number;
+
+       str = g_string_new("BEGIN:VCARD\r\nVERSION:3.0\r\n");
+
+       __bluetooth_pb_vcard_append_v30(str, "N", NULL, NULL);
+       __bluetooth_pb_vcard_append_v30(str, "FN", NULL, NULL);
+
+       number = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+       __bluetooth_pb_vcard_append_v30(str, "TEL", NULL, number);
+       g_free(number);
+
+       if (((filter == 0) || (filter & VCARD_X_IRMC_CALL_DATETIME))
+                       && attr) {
+               gchar *datetime = NULL;
+
+               datetime = __bluetooth_pb_phonelog_datetime(phonelog_id);
+               __bluetooth_pb_vcard_append_v30(str,
+                               "X-IRMC-CALL-DATETIME", attr, datetime);
+               g_free(datetime);
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       return g_string_free(str, FALSE);
+}
+
+static gchar *__bluetooth_pb_vcard_real_call(gint phonelog_id,
+                                       guint filter,
+                                       guint8 format,
+                                       const gchar *attr)
+{
+       DBG("\n");
+       gchar *vcard = NULL;
+
+       switch (format) {
+       case VCARD_FORMAT_3_0:
+               vcard = __bluetooth_pb_vcard_real_call_v30(phonelog_id,
+                               filter, attr);
+               break;
+       case VCARD_FORMAT_2_1:
+       default:
+               vcard = __bluetooth_pb_vcard_real_call_v21(phonelog_id,
+                               filter, attr);
+               break;
+       }
+
+       return vcard;
+}
+
+static gchar **__bluetooth_pb_contact_add_field_str(contacts_record_h record,
+                                               int *field,
+                                               gint field_size)
+{
+       gchar **strv;
+
+       gint status;
+       gint i;
+
+       gboolean valid = FALSE;
+
+       /* check empty field */
+       for (i = 0; i < field_size; i++) {
+               gchar *tmp = NULL;
+
+               status = contacts_record_get_str_p(record, field[i], &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (tmp) {
+                       valid = TRUE;
+                       break;
+               }
+       }
+
+       if (valid == FALSE)
+               return NULL;
+
+       strv = g_new0(gchar *, field_size + 1);
+
+       for (i = 0; i < field_size; i++) {
+               gchar *tmp;
+
+               status = contacts_record_get_str_p(record, field[i], &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (tmp == NULL)
+                       strv[i] = g_strdup("");
+               else
+                       strv[i] = __bluetooth_pb_vcard_escape(tmp);
+       }
+
+       return strv;
+}
+
+static gchar **__bluetooth_pb_contact_tel_param(contacts_record_h number)
+{
+       gchar **strv = NULL;
+
+       const gint TEL_PARAM_LEN = 13;
+
+       gint status;
+       gint i = 0;
+
+       contacts_number_type_e type;
+
+       bool is_default = false;
+
+       status = contacts_record_get_bool(number, _contacts_number.is_default,
+                       &is_default);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       strv = g_new0(char *, TEL_PARAM_LEN + 1);/* tel param max size is 13 */
+
+       if (is_default) {
+               strv[i] = g_strdup("PREF");
+               i++;
+       }
+
+       status = contacts_record_get_int(number,
+                       _contacts_number.type,
+                       (gint *)&type);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       if (type & CONTACTS_NUMBER_TYPE_HOME) {
+               strv[i] = g_strdup("HOME");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_WORK) {
+               strv[i] = g_strdup("WORK");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_VOICE) {
+               strv[i] = g_strdup("VOICE");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_FAX) {
+               strv[i] = g_strdup("FAX");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_MSG) {
+               strv[i] = g_strdup("MSG");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_CELL) {
+               strv[i] = g_strdup("CELL");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_PAGER) {
+               strv[i] = g_strdup("PAGER");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_BBS) {
+               strv[i] = g_strdup("BBS");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_MODEM) {
+               strv[i] = g_strdup("MODEM");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_CAR) {
+               strv[i] = g_strdup("CAR");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_ISDN) {
+               strv[i] = g_strdup("ISDN");
+               i++;
+       }
+
+       if (type & CONTACTS_NUMBER_TYPE_VIDEO) {
+               strv[i] = g_strdup("VIDEO");
+               i++;
+       }
+
+       /* CTS_NUM_TYPE_PCS is not part of vcard2.1 */
+       return strv;
+}
+
+
+static gchar *__bluetooth_pb_contact_photo_type(const gchar *filename)
+{
+       gchar *filetype = NULL;
+       gchar *ext = NULL;
+
+       if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == FALSE) {
+               ERR_SECURE("file does not regular:%s\n", filename);
+               return NULL;
+       }
+
+       ext = strrchr(filename, '.');
+       if (ext == NULL) {
+               ERR("file doesn't have extension\n");
+               return NULL;
+       }
+
+       ext++;
+
+       if (g_ascii_strcasecmp(ext, "gif") == 0)
+               filetype = "GIF";
+       else if (g_ascii_strcasecmp(ext, "cgm") == 0)
+               filetype = "CGM";
+       else if (g_ascii_strcasecmp(ext, "wmf") == 0)
+               filetype = "WMF";
+       else if (g_ascii_strcasecmp(ext, "bmp") == 0)
+               filetype = "BMP";
+       else if (g_ascii_strcasecmp(ext, "met") == 0)
+               filetype = "MET";
+       else if (g_ascii_strcasecmp(ext, "dib") == 0)
+               filetype = "DIB";
+       else if (g_ascii_strcasecmp(ext, "pict") == 0 ||
+                       g_ascii_strcasecmp(ext, "pct") == 0 ||
+                       g_ascii_strcasecmp(ext, "pic") == 0)
+               filetype = "PICT";
+       else if (g_ascii_strcasecmp(ext, "tiff") == 0 ||
+                       g_ascii_strcasecmp(ext, "tif") == 0)
+               filetype = "TIFF";
+       else if (g_ascii_strcasecmp(ext, "ps") == 0)
+               filetype = "PS";
+       else if (g_ascii_strcasecmp(ext, "pdf") == 0)
+               filetype = "PDF";
+       else if (g_ascii_strcasecmp(ext, "jpeg") == 0 ||
+                       g_ascii_strcasecmp(ext, "jpg") == 0 ||
+                       g_ascii_strcasecmp(ext, "jpe") == 0)
+               filetype = "JPEG";
+       else if (g_ascii_strcasecmp(ext, "mpeg") == 0 ||
+                       g_ascii_strcasecmp(ext, "mpg") == 0)
+               filetype = "MPEG";
+       else if (g_ascii_strcasecmp(ext, "m2v") == 0)
+               filetype = "MPEG2";
+       else if (g_ascii_strcasecmp(ext, "avi") == 0)
+               filetype = "AVI";
+       else if (g_ascii_strcasecmp(ext, "mov") == 0)
+               filetype = "QTIME";
+       else if (g_ascii_strcasecmp(ext, "png") == 0)
+               filetype = "PNG";
+
+       return g_strdup(filetype);
+}
+
+static gchar **__bluetooth_pb_contact_addr(contacts_record_h address)
+{
+       const gint ADDR_LEN = 7;
+
+       gchar **strv = NULL;
+
+       gint addr[] = { _contacts_address.postbox,
+                       _contacts_address.extended,
+                       _contacts_address.street,
+                       _contacts_address.locality,
+                       _contacts_address.region,
+                       _contacts_address.postal_code,
+                       _contacts_address.country };
+
+       strv = __bluetooth_pb_contact_add_field_str(address,
+                       addr, ADDR_LEN);
+       return strv;
+}
+
+static gchar **__bluetooth_pb_contact_addr_param(contacts_record_h address)
+{
+
+       contacts_address_type_e type;
+
+       gint status;
+       gint i = 0;
+
+       gchar **strv = NULL;
+
+       status = contacts_record_get_int(address,
+                       _contacts_address.type,
+                       (gint *)&type);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       strv = g_new0(gchar *, 7);      /* ADDR param max size is 6 */
+
+       if (type & CONTACTS_ADDRESS_TYPE_HOME) {
+               strv[i] = g_strdup("HOME");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_WORK) {
+               strv[i] = g_strdup("WORK");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_DOM) {
+               strv[i] = g_strdup("DOM");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_INTL) {
+               strv[i] = g_strdup("INTL");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_POSTAL) {
+               strv[i] = g_strdup("POSTAL");
+               i++;
+       }
+       if (type & CONTACTS_ADDRESS_TYPE_PARCEL) {
+               strv[i] = g_strdup("PARCEL");
+               i++;
+       }
+       return strv;
+}
+
+static gchar *__bluetooth_pb_phonelog_datetime(gint phonelog_id)
+{
+       contacts_record_h phone_log;
+
+       char time_str[32] = {0,};
+
+       gint status;
+       gint time = 0;
+
+       struct tm time_info;
+
+       status = contacts_db_get_record(_contacts_phone_log._uri,
+                       phonelog_id,
+                       &phone_log);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_int(phone_log,
+                       _contacts_phone_log.log_time,
+                       &time);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       if (time <= 0)
+               return NULL;
+
+       localtime_r((time_t *)&time, &time_info);
+
+       strftime(time_str, sizeof(time_str),
+                       "%Y%m%dT%H%M%S", &time_info);
+
+       contacts_record_destroy(phone_log, TRUE);
+
+       return g_strdup(time_str);
+}
+
+static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact)
+{
+       contacts_record_h name = NULL;
+
+       GString *str = g_string_new(NULL);
+
+       gint status;
+       gint i;
+
+       gint name_size = 5;
+       gint name_val[] = { _contacts_name.last,
+                       _contacts_name.first,
+                       _contacts_name.addition,
+                       _contacts_name.prefix,
+                       _contacts_name.suffix };
+
+
+       status = contacts_record_get_child_record_at_p(contact,
+                       _contacts_contact.name, 0, &name);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       for (i = 0; i < name_size; i++) {
+               gchar *tmp = NULL;
+               gchar *escape = NULL;
+
+               if (i > 0)
+                       g_string_append_c(str, ';');
+
+               status = contacts_record_get_str_p(name, name_val[i], &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               escape = __bluetooth_pb_vcard_escape(tmp);
+               g_string_append(str, escape);
+
+               g_free(escape);
+       }
+
+       return g_string_free(str, FALSE);
+}
+
+static gchar *__bluetooth_pb_phonetic_first_from_contact(contacts_record_h contact)
+{
+       contacts_record_h name = NULL;
+
+       GString *str = g_string_new(NULL);
+
+       gint status;
+
+       gchar *phonetic_first = NULL;
+       gchar *escape = NULL;
+
+       status = contacts_record_get_child_record_at_p(contact,
+                       _contacts_contact.name, 0, &name);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_str_p(name, _contacts_name.phonetic_first, &phonetic_first);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       if (phonetic_first == NULL)
+               return NULL;
+
+       escape = __bluetooth_pb_vcard_escape(phonetic_first);
+       g_string_append(str, escape);
+
+       g_free(escape);
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+       g_string_append_c(str, ';');
+
+       return g_string_free(str, FALSE);
+}
+
+
+static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact)
+{
+       guint count = 0;
+
+       gint status;
+       gint i;
+
+       gchar *str = NULL;
+
+       status = contacts_record_get_child_record_count(contact,
+                       _contacts_contact.number,
+                       &count);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       for (i = 0; i < count; i++) {
+               contacts_record_h number = NULL;
+
+               gchar *tmp = NULL;
+
+               bool is_default = false;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, i, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               status = contacts_record_get_bool(number,
+                               _contacts_number.is_default,
+                               &is_default);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (is_default == FALSE)
+                       continue;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       continue;
+
+               if (tmp) {
+                       str = g_strdup(tmp);
+                       break;
+               }
+       }
+
+       /* get first number */
+       if (str == NULL) {
+               gchar *tmp = NULL;
+
+               contacts_record_h number = NULL;
+
+               status = contacts_record_get_child_record_at_p(contact,
+                               _contacts_contact.number, 0, &number);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return NULL;
+
+               status = contacts_record_get_str_p(number,
+                               _contacts_number.number,
+                               &tmp);
+
+               if (status != CONTACTS_ERROR_NONE)
+                       return NULL;
+
+               str = g_strdup(tmp);
+       }
+
+       return str;
+}
+
+static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id)
+{
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_list_h record_list = NULL;
+
+       contacts_record_h phone_log = NULL;
+       contacts_record_h record = NULL;
+
+       gint status;
+       gint person_id = 0;
+
+       status = contacts_db_get_record(_contacts_phone_log._uri,
+                       phonelog_id,
+                       &phone_log);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return 0;
+
+       status = contacts_record_get_int(phone_log,
+                       _contacts_phone_log.person_id,
+                       &person_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(phone_log, TRUE);
+               return 0;
+       }
+
+       contacts_record_destroy(phone_log, TRUE);
+
+       if (person_id)
+               return person_id;
+
+       status = contacts_filter_create(_contacts_person_phone_log._uri,
+                       &filter);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return 0;
+
+
+       status = contacts_filter_add_int(filter,
+                       _contacts_person_phone_log.log_id,
+                       CONTACTS_MATCH_EQUAL,
+                       phonelog_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_query_create(_contacts_person_phone_log._uri, &query);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_query_set_filter(query, filter);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_db_get_records_with_query(query, -1, -1,
+                                                               &record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_list_first(record_list);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_list_get_current_record_p(record_list, &record);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+       status = contacts_record_get_int(record,
+                       _contacts_person_phone_log.person_id,
+                       &person_id);
+
+       if (status != CONTACTS_ERROR_NONE)
+               goto done;
+
+done:
+       if (record_list != NULL)
+               contacts_list_destroy(record_list, TRUE);
+
+       contacts_filter_destroy(filter);
+
+       if (query != NULL)
+               contacts_query_destroy(query);
+
+       return person_id;
+}
+
+/* API for vcard */
+gchar *_bluetooth_pb_vcard_contact(gint person_id,
+                               guint64 filter,
+                               guint8 format)
+{
+       gchar *str = NULL;
+
+       if (person_id <= 0)
+               return NULL;
+
+       str = __bluetooth_pb_vcard_real_contact_with_properties(person_id, 0,
+                       filter, format,
+                       NULL);
+       return str;
+}
+
+gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
+                                       guint64 filter,
+                                       guint8 format)
+{
+       GString *str = g_string_new("BEGIN:VCARD\r\n");
+       gchar *fn;
+       gchar *name;
+
+       fn = _bluetooth_pb_owner_name();
+       name = g_strdup_printf("%s;;;;", fn);
+
+       switch (format) {
+       case VCARD_FORMAT_3_0:
+               g_string_append(str, "VERSION:3.0\r\n");
+
+               __bluetooth_pb_vcard_append_v30(str, "N", NULL, name);
+               __bluetooth_pb_vcard_append_v30(str, "FN", NULL, fn);
+               __bluetooth_pb_vcard_append_v30(str, "TEL", "TYPE=CELL",
+                                                                       number);
+               break;
+       case VCARD_FORMAT_2_1:
+       default:
+               g_string_append(str, "VERSION:2.1\r\n");
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "N", NULL, name);
+
+               if (filter == 0 || (filter & VCARD_FN))
+                       __bluetooth_pb_vcard_append_qp_encode_v21(str, "FN",
+                                                               NULL, fn);
+
+               __bluetooth_pb_vcard_append_qp_encode_v21(str, "TEL", "CELL",
+                                                                       number);
+               break;
+
+       }
+
+       g_string_append(str, "END:VCARD\r\n");
+
+       g_free(fn);
+       g_free(name);
+
+       return g_string_free(str, FALSE);
+}
+
+gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
+                               guint64 filter,
+                               guint8 format,
+                               const gchar *attr)
+{
+       gint person_id = 0;
+
+       gchar *str = NULL;
+
+       if (attr == NULL) {
+               DBG("Unknown attribute type ignored\n");
+               return NULL;
+       }
+
+       person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
+
+       DBG("person_id %d\n", person_id);
+
+       if (person_id) {
+               if (filter == 0 || (filter & VCARD_X_IRMC_CALL_DATETIME)) {
+                       gchar *datetime = NULL;
+
+                       datetime = __bluetooth_pb_phonelog_datetime(
+                                                               phonelog_id);
+
+                       str = __bluetooth_pb_vcard_real_contact_with_properties(
+                                       person_id,
+                                       phonelog_id,
+                                       filter, format,
+                                       "X-IRMC-CALL-DATETIME", attr, datetime,
+                                       NULL);
+
+                       if (datetime)
+                               g_free(datetime);
+               } else {
+                       str = __bluetooth_pb_vcard_real_contact_with_properties(
+                                       person_id,
+                                       phonelog_id,
+                                       filter, format,
+                                       NULL);
+               }
+       } else
+               str = __bluetooth_pb_vcard_real_call(phonelog_id, filter,
+                                                               format, attr);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_fn_from_person_id(gint person_id)
+{
+       contacts_record_h person = NULL;
+
+       gint status;
+
+       gchar *str = NULL;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_str(person,
+                       _contacts_person.display_name,
+                       &str);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       contacts_record_destroy(person, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_name_from_person_id(gint person_id)
+{
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       gint status;
+       gint contact_id = 0;
+
+       gchar *str;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       str = __bluetooth_pb_name_from_contact(contact);
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_number_from_person_id(gint person_id)
+{
+       contacts_record_h person = NULL;
+       contacts_record_h contact = NULL;
+
+       gint status;
+       gint contact_id = 0;
+
+       gchar *str;
+
+       status = contacts_db_get_record(_contacts_person._uri,
+                       person_id,
+                       &person);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+
+       status = contacts_record_get_int(person,
+                       _contacts_person.display_contact_id,
+                       &contact_id);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       status = contacts_db_get_record(_contacts_contact._uri,
+                       contact_id,
+                       &contact);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(person, TRUE);
+               return NULL;
+       }
+
+       str = __bluetooth_pb_number_from_contact(contact);
+
+       contacts_record_destroy(contact, TRUE);
+       contacts_record_destroy(person, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id)
+{
+       gint person_id = 0;
+       gchar *str = NULL;
+
+       person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
+
+       if (person_id > 0)
+               str = _bluetooth_pb_fn_from_person_id(person_id);
+       else
+               str = g_strdup("");
+
+       return str;
+}
+
+gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id)
+{
+       gint person_id = 0;
+       gchar *str = NULL;
+
+       person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id);
+
+       if (person_id > 0)
+               str = _bluetooth_pb_name_from_person_id(person_id);
+       else {
+               gchar *tmp;
+
+               tmp = _bluetooth_pb_number_from_phonelog_id(phonelog_id);
+               str = g_strdup_printf("%s;;;;", tmp);
+
+               g_free(tmp);
+       }
+
+       return str;
+}
+
+gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id)
+{
+       contacts_record_h phone_log;
+
+       gint status;
+
+       gchar *str;
+       gchar *tmp = NULL;
+
+       status = contacts_db_get_record(_contacts_phone_log._uri,
+                       phonelog_id, &phone_log);
+
+       if (status != CONTACTS_ERROR_NONE)
+               return NULL;
+
+       contacts_record_get_str_p(phone_log,
+                       _contacts_phone_log.address,
+                       &tmp);
+
+       if (status != CONTACTS_ERROR_NONE) {
+               contacts_record_destroy(phone_log, TRUE);
+               return NULL;
+       }
+
+       str = g_strdup(tmp);
+
+       contacts_record_destroy(phone_log, TRUE);
+
+       return str;
+}
+
+gchar *_bluetooth_pb_owner_name(void)
+{
+       gchar *name;
+
+       name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
+
+       if (name == NULL)
+               name = g_strdup("My Name");
+
+       return name;
+}
diff --git a/wearable/pb-agent/bluetooth_pb_vcard.h b/wearable/pb-agent/bluetooth_pb_vcard.h
new file mode 100644 (file)
index 0000000..a838eb9
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
+ *              Girishashok Joshi <girish.joshi@samsung.com>
+ *              Chanyeol Park <chanyeol.park@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __DEF_BT_PB_VCARD_H_
+#define __DEF_BT_PB_VCARD_H_
+
+#include <glib.h>
+
+/* vcard */
+gchar *_bluetooth_pb_vcard_contact(gint person_id,
+                               guint64 filter,
+                               guint8 format);
+
+gchar *_bluetooth_pb_vcard_contact_owner(const gchar *number,
+                                       guint64 filter,
+                                       guint8 format);
+
+gchar *_bluetooth_pb_vcard_call(gint phonelog_id,
+                               guint64 filter,
+                               guint8 format,
+                               const gchar *attr);
+
+gchar *_bluetooth_pb_fn_from_person_id(gint person_id);
+
+gchar *_bluetooth_pb_name_from_person_id(gint person_id);
+
+gchar *_bluetooth_pb_number_from_person_id(gint person_id);
+
+gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id);
+
+gchar *_bluetooth_pb_name_from_phonelog_id(gint phonelog_id);
+
+gchar *_bluetooth_pb_number_from_phonelog_id(gint phonelog_id);
+
+gchar *_bluetooth_pb_owner_name(void);
+
+#endif
diff --git a/wearable/pb-agent/org.bluez.pb_agent.service b/wearable/pb-agent/org.bluez.pb_agent.service
new file mode 100644 (file)
index 0000000..e890341
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.bluez.pb_agent
+Exec=/usr/bin/bluetooth-pb-agent