Reduce the predefined logic (PredefinedPreprocessor)
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-client.c
index 9e0f92a..539f543 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdint.h>
+#include <gio/gunixfdlist.h>
 
 #include "bt-common.h"
 #include "bt-event-handler.h"
 #include "bt-internal-types.h"
 #include "bt-request-sender.h"
 
+#include "bluetooth-gatt-client-api.h"
+#include <arpa/inet.h>
+static GSList *gatt_characteristic_notify_list;
+static GSList *gatt_characteristic_write_list = NULL;;
+
 #define GATT_DEFAULT_TIMEOUT  (6 * 1000) // Dependent on supervision timeout 6 sec
 
 typedef enum {
@@ -45,9 +51,6 @@ BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_
        BT_CHECK_PARAMETER(svc_pty, return);
 
        g_free(svc_pty->uuid);
-       g_free(svc_pty->handle);
-       g_strfreev(svc_pty->include_handles.handle);
-       g_strfreev(svc_pty->char_handle.handle);
 
        memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
 
@@ -62,8 +65,6 @@ BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *cha
        g_free(char_pty->name);
        g_free(char_pty->description);
        g_free(char_pty->val);
-       g_free(char_pty->handle);
-       g_strfreev(char_pty->char_desc_handle.handle);
 
        memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
 
@@ -76,7 +77,6 @@ BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_prop
 
        g_free(desc_pty->uuid);
        g_free(desc_pty->val);
-       g_free(desc_pty->handle);
 
        memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
 
@@ -108,27 +108,19 @@ gboolean _bluetooth_gatt_check_service_change_watcher_address(
 {
        GSList *l;
        char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
-       char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
 
        _bt_convert_addr_type_to_string(device_address,
                        (unsigned char *)device_addr->addr);
 
        for (l = service_monitor_list; l != NULL; l = l->next) {
                char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
-               char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
                bluetooth_device_address_t *addr = l->data;
 
                _bt_convert_addr_type_to_string(device_address2,
                                (unsigned char *)addr->addr);
-               _bt_convert_addr_string_to_secure_string(secure_address,
-                               device_address);
-               _bt_convert_addr_string_to_secure_string(secure_address2,
-                               device_address2);
-               BT_INFO("service_monitor_list [%s] - Input [%s]",
-                               secure_address2, secure_address);
 
                if (!memcmp(device_addr, addr,
-                               sizeof(bluetooth_device_address_t)))
+                           sizeof(bluetooth_device_address_t)))
                        return TRUE;
        }
 
@@ -140,35 +132,32 @@ BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
 {
        GSList *l;
        bluetooth_device_address_t *addr = NULL;
-       char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
        char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
 
-       _bt_convert_addr_type_to_string(device_address,
-                       (unsigned char *)address->addr);
-       _bt_convert_addr_string_to_secure_string(secure_address,
-                       device_address);
+       _bt_convert_addr_type_to_secure_string(secure_address, (unsigned char *)address->addr);
        BT_INFO("Set watcher for %s with %d", secure_address, enable);
 
        if (enable == TRUE) {
-               if (service_monitor_list == NULL)
-                       _bt_register_manager_subscribe_signal(TRUE);
-
                if (_bluetooth_gatt_check_service_change_watcher_address(address)
                                == TRUE) {
                        BT_INFO("The watcher is already set");
                        return BLUETOOTH_ERROR_NONE;
                }
+
+               if (service_monitor_list == NULL)
+                       _bt_register_manager_subscribe_signal(TRUE);
+
                addr = g_malloc0(sizeof(bluetooth_device_address_t));
                memcpy(addr, address, sizeof(bluetooth_device_address_t));
 
                service_monitor_list =
                        g_slist_append(service_monitor_list, addr);
        } else {
-
                for (l = service_monitor_list; l != NULL; l = l->next) {
                        addr = l->data;
+
                        if (!memcmp(address, addr,
-                                       sizeof(bluetooth_device_address_t))) {
+                                   sizeof(bluetooth_device_address_t))) {
                                service_monitor_list =
                                        g_slist_remove(service_monitor_list, addr);
                                g_free(addr);
@@ -201,11 +190,11 @@ BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle
        BT_CHECK_PARAMETER(service, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        service_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -239,39 +228,43 @@ BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle
                if (!g_strcmp0(key, "UUID")) {
                        char *name = NULL;
                        service->uuid = g_variant_dup_string(value, &len);
-                       _bt_get_uuid_specification_name(service->uuid, &name);
-                       BT_INFO("======> Service : %s [%s]", service->uuid, name);
+                       bluetooth_get_uuid_name(service->uuid, &name);
+                       BT_INFO("%s %s [%s]", service_handle + 37, service->uuid, name);
                        g_free(name);
                } else if (!g_strcmp0(key, "Primary")) {
                        service->primary = g_variant_get_boolean(value);
 
                } else if (!g_strcmp0(key, "Includes")) {
                        g_variant_get(value, "ao", &char_iter);
-                       gp_array = g_ptr_array_new();
-                       while (g_variant_iter_loop(char_iter, "&o", &char_handle))
-                               g_ptr_array_add(gp_array, (gpointer)char_handle);
-
-                       if (gp_array->len != 0) {
-                               service->include_handles.count = gp_array->len;
-                               service->include_handles.handle =
-                                               __get_string_array_from_gptr_array(gp_array);
+                       if (char_iter != NULL) {
+                               gp_array = g_ptr_array_new();
+                               while (g_variant_iter_loop(char_iter, "&o", &char_handle))
+                                       g_ptr_array_add(gp_array, (gpointer)char_handle);
+
+                               if (gp_array->len != 0) {
+                                       service->include_handles.count = gp_array->len;
+                                       service->include_handles.handle =
+                                                       __get_string_array_from_gptr_array(gp_array);
+                               }
+                               g_ptr_array_free(gp_array, TRUE);
+                               g_variant_iter_free(char_iter);
                        }
-                       g_ptr_array_free(gp_array, TRUE);
-                       g_variant_iter_free(char_iter);
                } else if (!g_strcmp0(key, "Characteristics")) {
                        g_variant_get(value, "ao", &char_iter);
-                       gp_array = g_ptr_array_new();
-                       while (g_variant_iter_loop(char_iter, "&o", &char_handle))
-                               g_ptr_array_add(gp_array, (gpointer)char_handle);
-
-                       if (gp_array->len != 0) {
-                               service->char_handle.count = gp_array->len;
-                               service->char_handle.handle =
-                                               __get_string_array_from_gptr_array(gp_array);
+                       if (char_iter != NULL) {
+                               gp_array = g_ptr_array_new();
+                               while (g_variant_iter_loop(char_iter, "&o", &char_handle))
+                                       g_ptr_array_add(gp_array, (gpointer)char_handle);
+
+                               if (gp_array->len != 0) {
+                                       service->char_handle.count = gp_array->len;
+                                       service->char_handle.handle =
+                                                       __get_string_array_from_gptr_array(gp_array);
+                               }
+                               g_ptr_array_free(gp_array, TRUE);
+                               g_variant_iter_free(char_iter);
                        }
                        BT_DBG("Characteristics count : %d", service->char_handle.count);
-                       g_ptr_array_free(gp_array, TRUE);
-                       g_variant_iter_free(char_iter);
                }
        }
 
@@ -300,8 +293,9 @@ BT_EXPORT_API int bluetooth_gatt_get_primary_services(
        char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
        char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
        int ret = BLUETOOTH_ERROR_INTERNAL;
+       int idx = 0;
 
-       BT_INFO("+");
+       BT_DBG("+");
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(prim_svc, return);
        BT_CHECK_ENABLED(return);
@@ -331,7 +325,7 @@ BT_EXPORT_API int bluetooth_gatt_get_primary_services(
                        if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
                                continue;
 
-                       BT_DBG("Object Path: %s", object_path);
+                       BT_DBG("[%d] Object Path : %s", idx++, object_path);
                        while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
                                if (g_strcmp0(key, "Primary") == 0) {
                                        if (g_variant_get_boolean(value))
@@ -412,6 +406,13 @@ BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_
                                                g_strstr_len(service->uuid, -1,
                                                                service_uuid)) {
                                        ret = BLUETOOTH_ERROR_NONE;
+
+                                       /* release resources */
+                                       g_free(object_path);
+                                       g_variant_iter_free(interface_iter);
+                                       g_free(interface_str);
+                                       g_variant_iter_free(svc_iter);
+
                                        goto done;
                                }
                        }
@@ -488,6 +489,7 @@ static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
        g_variant_iter_free(char_iter);
        g_variant_unref(value);
        g_object_unref(proxy);
+       g_variant_unref(char_value);
 }
 
 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
@@ -503,11 +505,11 @@ BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
        BT_CHECK_PARAMETER(service_handle, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        service_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -537,8 +539,6 @@ static int __get_permission_flag(char *permission)
 
        retv_if(permission == NULL, ret);
 
-       BT_INFO("permission = %s", permission);
-
        if (!g_strcmp0(permission, "broadcast"))
                ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
        else if (!g_strcmp0(permission, "read"))
@@ -569,6 +569,41 @@ static int __get_permission_flag(char *permission)
        return ret;
 }
 
+static void __convert_permission_flag_to_str(unsigned int permission)
+{
+       char perm[200] = { 0, };
+
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
+               g_strlcat(perm, "broadcast ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ)
+               g_strlcat(perm, "read ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
+               g_strlcat(perm, "write-without-response ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE)
+               g_strlcat(perm, "write ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
+               g_strlcat(perm, "notify ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
+               g_strlcat(perm, "indicate ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
+               g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
+               g_strlcat(perm, "reliable-write ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
+               g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
+               g_strlcat(perm, "encrypt-read ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
+               g_strlcat(perm, "encrypt-write ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
+               g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
+       if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
+               g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
+
+       BT_INFO("permission [0x%04x] : %s\n", permission, perm);
+       return;
+}
+
 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
                const char *char_handle, bt_gatt_char_property_t *characteristic)
 {
@@ -594,11 +629,11 @@ BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
 
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        char_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -633,8 +668,8 @@ BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
                if (!g_strcmp0(key, "UUID")) {
                        char *name = NULL;
                        characteristic->uuid = g_variant_dup_string(value, &len);
-                       _bt_get_uuid_specification_name(characteristic->uuid, &name);
-                       BT_INFO("Characteristic : %s [%s]", characteristic->uuid, name);
+                       bluetooth_get_uuid_name(characteristic->uuid, &name);
+                       BT_INFO("%s %s [%s]", char_handle + 37, characteristic->uuid, name);
                        g_free(name);
                } else if (!g_strcmp0(key, "Value")) {
                        gb_array = g_byte_array_new();
@@ -658,6 +693,7 @@ BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
 
                        while (g_variant_iter_loop(char_perm_iter, "s", &permission))
                                characteristic->permission |= __get_permission_flag(permission);
+                       __convert_permission_flag_to_str(characteristic->permission);
 
                        g_variant_iter_free(char_perm_iter);
                } else if (!g_strcmp0(key, "Descriptors")) {
@@ -758,11 +794,11 @@ BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
        BT_CHECK_PARAMETER(char_uuid, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        service_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -804,11 +840,11 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
 
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        descriptor_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -843,7 +879,7 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
                if (!g_strcmp0(key, "UUID")) {
                        char *name = NULL;
                        descriptor->uuid = g_variant_dup_string(value, &len);
-                       _bt_get_uuid_specification_name(descriptor->uuid, &name);
+                       bluetooth_get_uuid_name(descriptor->uuid, &name);
                        BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
                        g_free(name);
                } else if (!g_strcmp0(key, "Value")) {
@@ -872,44 +908,95 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
        return BLUETOOTH_ERROR_NONE;
 }
 
+static int __bluetooth_get_att_error_code(GError *error, char *handle)
+{
+       int att_ecode = 0;
+       int len;
+       char *str = NULL;
+
+       BT_ERR("Error : %s [%s]", error->message, handle + 15);
+       str = g_strrstr(error->message, "ATT error: 0x");
+       if (str) {
+               len = strlen(str);
+               att_ecode =  g_ascii_xdigit_value(str[len - 2]) << 4;
+               att_ecode += g_ascii_xdigit_value(str[len - 1]);
+       } else
+               return BLUETOOTH_ATT_ERROR_INTERNAL;
+
+       switch (att_ecode) {
+       case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
+               BT_ERR("Read not permitted");
+               break;
+       case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
+               BT_ERR("Write not permitted");
+               break;
+       case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
+       case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
+       case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
+               BT_ERR("Not paired");
+               break;
+       case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
+               BT_ERR("Invalid offset");
+               break;
+       case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
+               BT_ERR("Invalid Length");
+               break;
+       case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
+               BT_ERR("Operation not Authorized");
+               break;
+       default:
+               BT_ERR("default ecode");
+               break;
+       }
+
+       if (att_ecode >= 0x80 && att_ecode <= 0x9F)
+               BT_ERR("Application error");
+
+       return att_ecode;
+}
+
 static void __bluetooth_internal_read_cb(GObject *source_object,
-                       GAsyncResult *res,
-                       gpointer user_data)
+                                        GAsyncResult *res, gpointer user_data)
 {
        GError *error = NULL;
-       bt_user_info_t *user_info;
-       bt_gatt_char_value_t char_value =  { 0, };
        GDBusConnection *system_gconn = NULL;
        GVariant *value;
-       GByteArray *gp_byte_array = NULL;
+       bt_user_info_t *user_info;
        GVariantIter *iter;
+       GByteArray *gp_byte_array = NULL;
        guint8 g_byte;
-       int ret = BLUETOOTH_ERROR_NONE;
+       int att_ecode = 0;
+       bt_gatt_resp_data_t *resp_data = user_data;
 
        BT_DBG("+");
-       user_info = _bt_get_user_data(BT_COMMON);
 
-       system_gconn = _bt_gdbus_get_system_gconn();
+       system_gconn = _bt_get_system_private_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
-       if (error) {
-               BT_ERR("Error : %s \n", error->message);
-               if (g_strrstr(error->message, "Not paired"))
-                       ret = BLUETOOTH_ERROR_NOT_PAIRED;
-               else
-                       ret = BLUETOOTH_ERROR_INTERNAL;
+       user_info = _bt_get_user_data(BT_COMMON);
+       if (!user_info) {
+               if (error) {
+                       BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
+                       g_clear_error(&error);
+                       g_free(resp_data);
+                       return;
+               }
+               g_free(resp_data);
+               g_variant_unref(value);
+               return;
+       }
 
+       if (error) {
+               att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
                g_clear_error(&error);
-               if (user_info) {
-                       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
-                               ret, NULL,
-                               user_info->cb, user_info->user_data);
-               }
-               g_free(user_data);
+
+               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
+                                   att_ecode, resp_data,
+                                   user_info->cb, user_info->user_data);
+               g_free(resp_data);
                return;
        }
 
-       char_value.char_handle = user_data;
        gp_byte_array = g_byte_array_new();
        g_variant_get(value, "(ay)", &iter);
 
@@ -917,38 +1004,39 @@ static void __bluetooth_internal_read_cb(GObject *source_object,
                g_byte_array_append(gp_byte_array, &g_byte, 1);
 
        if (gp_byte_array->len != 0) {
-               char_value.val_len = gp_byte_array->len;
-               char_value.char_value = gp_byte_array->data;
+               resp_data->len = gp_byte_array->len;
+               resp_data->value = gp_byte_array->data;
        }
 
-       if (user_info) {
-               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
-                               BLUETOOTH_ERROR_NONE, &char_value,
-                               user_info->cb, user_info->user_data);
-       }
+       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
+                           BLUETOOTH_ATT_ERROR_NONE, resp_data,
+                           user_info->cb, user_info->user_data);
+       g_free(resp_data);
 
-       g_free(char_value.char_handle);
        g_byte_array_free(gp_byte_array, TRUE);
-       g_variant_unref(value);
        g_variant_iter_free(iter);
+       g_variant_unref(value);
 
        BT_DBG("-");
 }
 
-BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *characteristic)
+BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
+                                                          gpointer user_data)
 {
        GDBusConnection *conn;
-       char *handle;
+       bt_gatt_resp_data_t *resp_data;
        GVariantBuilder *builder = NULL;
        guint16 offset = 0;
 
-       BT_CHECK_PARAMETER(characteristic, return);
+       BT_CHECK_PARAMETER(chr, return);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
-       handle = g_strdup(characteristic);
+       resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
+       resp_data->user_data = user_data;
+       resp_data->handle = (char *)chr;
 
        builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
 
@@ -957,26 +1045,65 @@ BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *character
                g_variant_new("q", offset));
 
        /* Device Object path*/
-//  g_variant_builder_add(builder, "{sv}", "device",
-//  g_variant_new_object("o", NULL));
+//     g_variant_builder_add(builder, "{sv}", "device",
+//     g_variant_new_object("o", NULL));
 
-       g_dbus_connection_call(conn,
-                       BT_BLUEZ_NAME,
-                       characteristic,
-                       GATT_CHAR_INTERFACE,
-                       "ReadValue",
-                       g_variant_new("(a{sv})", builder),
-                       G_VARIANT_TYPE("(ay)"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
+                       "ReadValue", g_variant_new("(a{sv})", builder),
+                       G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
                        (GAsyncReadyCallback)__bluetooth_internal_read_cb,
-                       (gpointer)handle);
+                       (gpointer)resp_data);
        g_variant_builder_unref(builder);
 
        return BLUETOOTH_ERROR_NONE;
 }
 
+static void __bluetooth_internal_write_cb(GObject *source_object,
+                                         GAsyncResult *res, gpointer user_data)
+{
+       GError *error = NULL;
+       GDBusConnection *system_gconn = NULL;
+       bt_user_info_t *user_info;
+       GVariant *value;
+       int att_ecode = 0;
+       bt_gatt_resp_data_t *resp_data = user_data;
+
+       system_gconn = _bt_get_system_private_conn();
+       value = g_dbus_connection_call_finish(system_gconn, res, &error);
+
+       user_info = _bt_get_user_data(BT_COMMON);
+       if (!user_info) {
+               if (error) {
+                       BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
+                       g_clear_error(&error);
+                       g_free(resp_data);
+                       return;
+               }
+               g_free(resp_data);
+               g_variant_unref(value);
+               return;
+       }
+
+       if (error) {
+               att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
+               g_clear_error(&error);
+
+               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
+                               att_ecode, resp_data,
+                               user_info->cb, user_info->user_data);
+               g_free(resp_data);
+               return;
+       }
+
+       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
+                       BLUETOOTH_ATT_ERROR_NONE, resp_data,
+                       user_info->cb, user_info->user_data);
+       g_free(resp_data);
+
+       g_variant_unref(value);
+       return;
+}
+
 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
                const char *char_handle, const guint8 *value, int length)
 {
@@ -994,7 +1121,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1009,20 +1136,24 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
                                g_variant_new_uint16(offset));
 
        /* Device Object path*/
-//  g_variant_builder_add(builder2, "{sv}", "device",
-//  g_variant_new_object("o", NULL));
+//     g_variant_builder_add(builder2, "{sv}", "device",
+//     g_variant_new_object("o", NULL));
 
        options = g_variant_new("a{sv}", builder2);
 
-       g_dbus_connection_call_sync(conn,
-                       BT_BLUEZ_NAME,
-                       char_handle,
-                       GATT_CHAR_INTERFACE,
-                       "WriteValue",
-                       g_variant_new("(@ay@a{sv})", val, options),
-                       NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1, NULL, &error);
+       g_dbus_connection_call(conn,
+                               BT_BLUEZ_NAME,
+                               char_handle,
+                               GATT_CHAR_INTERFACE,
+                               "WriteValue",
+                               g_variant_new("(@ay@a{sv})",
+                               val, options),
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL,
+                               (GAsyncReadyCallback)__bluetooth_internal_write_cb,
+                               NULL);
+
 
        if (error) {
                BT_ERR("Set value Failed: %s", error->message);
@@ -1037,50 +1168,9 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
        return BLUETOOTH_ERROR_NONE;
 }
 
-static void __bluetooth_internal_write_cb(GObject *source_object,
-                       GAsyncResult *res,
-                       gpointer user_data)
-{
-       GError *error = NULL;
-       bt_user_info_t *user_info;
-       GDBusConnection *system_gconn = NULL;
-       GVariant *value;
-       int result = BLUETOOTH_ERROR_NONE;
-       guint8 att_ecode = 0;
-
-       user_info = _bt_get_user_data(BT_COMMON);
-
-       system_gconn = _bt_gdbus_get_system_gconn();
-       value = g_dbus_connection_call_finish(system_gconn, res, &error);
-
-       if (error) {
-               BT_ERR("Error : %s \n", error->message);
-               g_clear_error(&error);
-               result = BLUETOOTH_ERROR_INTERNAL;
-       } else {
-               g_variant_get(value, "(y)", &att_ecode);
-               if (att_ecode) {
-                       result =  att_ecode;
-                       BT_ERR("ATT Error code: %d \n", att_ecode);
-               }
-       }
-
-       if (user_info) {
-               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
-                               result, NULL,
-                               user_info->cb, user_info->user_data);
-       } else {
-               BT_ERR("user info is null");
-       }
-
-       if (value)
-               g_variant_unref(value);
-
-       return;
-}
-
 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
-               const char *char_handle, const guint8 *value, int length, guint8 write_type)
+                       const char *chr, const guint8 *value, int length,
+                       guint8 write_type, gpointer user_data)
 {
        GVariant *val, *options;
        GVariantBuilder *builder1;
@@ -1089,13 +1179,14 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
        guint16 offset = 0;
        int i = 0;
        int ret = BLUETOOTH_ERROR_NONE;
+       bt_gatt_resp_data_t *resp_data;
 
-       BT_CHECK_PARAMETER(char_handle, return);
+       BT_CHECK_PARAMETER(chr, return);
        BT_CHECK_PARAMETER(value, return);
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED_INTERNAL(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1111,26 +1202,26 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
                        g_variant_new_uint16(offset));
 
        /* Device Object path*/
-//  g_variant_builder_add(builder2, "{sv}", "device",
-//  g_variant_new_object("o", NULL));
+//     g_variant_builder_add(builder2, "{sv}", "device",
+//     g_variant_new_object("o", NULL));
 
        options = g_variant_new("a{sv}", builder2);
 
-       g_dbus_connection_call(conn,
-                       BT_BLUEZ_NAME,
-                       char_handle,
-                       GATT_CHAR_INTERFACE,
+       resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
+       resp_data->user_data = user_data;
+       resp_data->handle = (char *)chr;
+
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
                        "WriteValuebyType",
-                       g_variant_new("(y@ay@a{sv})",
-                       write_type, val, options),
-                       G_VARIANT_TYPE("(y)"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1, NULL,
+                       g_variant_new("(y@ay@a{sv})", write_type, val, options),
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
                        (GAsyncReadyCallback)__bluetooth_internal_write_cb,
-                       NULL);
+                       (gpointer)resp_data);
 
        g_variant_builder_unref(builder1);
        g_variant_builder_unref(builder2);
+
        return ret;
 }
 
@@ -1150,7 +1241,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1168,8 +1259,8 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
                                g_variant_new_uint16(offset));
 
        /* Device Object path*/
-//  g_variant_builder_add(builder2, "{sv}", "device",
-//  g_variant_new_object("o", NULL));
+//     g_variant_builder_add(builder2, "{sv}", "device",
+//     g_variant_new_object("o", NULL));
 
        options = g_variant_new("a{sv}", builder2);
 
@@ -1209,11 +1300,11 @@ static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
        const gchar *key;
        char_descriptor_type_t desc_type = TYPE_NONE;
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        char_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -1320,6 +1411,7 @@ static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
        user_info = _bt_get_user_data(BT_COMMON);
 
        value = g_dbus_proxy_call_finish(proxy, res, &error);
+       characteristic.handle = user_data;
 
        if (value == NULL) {
                if (error != NULL) {
@@ -1334,7 +1426,7 @@ static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
                                BLUETOOTH_ERROR_INTERNAL, NULL,
                                user_info->cb, user_info->user_data);
                }
-               g_free(user_data);
+               g_free(characteristic.handle);
                g_object_unref(proxy);
                return;
        }
@@ -1351,7 +1443,6 @@ static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
                }
        }
 
-       characteristic.handle = user_data;
        if (user_info) {
                _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
                                ret, &characteristic, user_info->cb, user_info->user_data);
@@ -1360,10 +1451,11 @@ static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
 
        g_variant_iter_free(char_iter);
        g_variant_unref(value);
+       g_variant_unref(char_value);
        BT_DBG("-");
 }
 
-BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
+BT_EXPORT_API int bltooth_gatt_discover_characteristic_descriptor(
                        const char *characteristic_handle)
 {
        GDBusProxy *properties_proxy = NULL;
@@ -1374,11 +1466,11 @@ BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
        BT_CHECK_PARAMETER(characteristic_handle, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        characteristic_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -1404,73 +1496,87 @@ static void __bluetooth_internal_read_desc_cb(GObject *source_object,
                        gpointer user_data)
 {
        GError *error = NULL;
-       bt_user_info_t *user_info;
-       bt_gatt_char_property_t char_value =  { 0, };
        GDBusConnection *system_gconn = NULL;
        GVariant *value;
+       bt_user_info_t *user_info;
        GByteArray *gp_byte_array = NULL;
        GVariantIter *iter;
        guint8 g_byte;
+       int att_ecode = 0;
+       bt_gatt_resp_data_t *resp_data = user_data;
 
        BT_DBG("+");
-       user_info = _bt_get_user_data(BT_COMMON);
-       system_gconn = _bt_gdbus_get_system_gconn();
 
-       char_value.handle = user_data;
+       system_gconn = _bt_get_system_private_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
+       user_info = _bt_get_user_data(BT_COMMON);
+       if (!user_info) {
+               if (error) {
+                       BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
+                       g_clear_error(&error);
+                       g_free(resp_data);
+                       return;
+               }
+               g_free(resp_data);
+               g_variant_unref(value);
+               return;
+       }
+
        if (error) {
-               BT_ERR("Error : %s \n", error->message);
+               att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
                g_clear_error(&error);
-               if (user_info) {
-                       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
-                                       BLUETOOTH_ERROR_INTERNAL, NULL,
-                                       user_info->cb, user_info->user_data);
-               }
-               g_free(char_value.handle);
+
+               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
+                               att_ecode, resp_data,
+                               user_info->cb, user_info->user_data);
+               g_free(resp_data);
                return;
        }
 
        gp_byte_array = g_byte_array_new();
        g_variant_get(value, "(ay)", &iter);
 
-       while (g_variant_iter_loop(iter, "y",  &g_byte))
+       while (g_variant_iter_loop(iter, "y", &g_byte))
                g_byte_array_append(gp_byte_array, &g_byte, 1);
 
        if (gp_byte_array->len != 0) {
-               char_value.val_len = (unsigned int)gp_byte_array->len;
-               char_value.description = (char *)gp_byte_array->data;
+               resp_data->len = gp_byte_array->len;
+               resp_data->value = gp_byte_array->data;
        }
 
-       if (user_info) {
-               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
-                               BLUETOOTH_ERROR_NONE, &char_value,
-                               user_info->cb, user_info->user_data);
-       }
+       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
+                       BLUETOOTH_ATT_ERROR_NONE, resp_data,
+                       user_info->cb, user_info->user_data);
+       g_free(resp_data);
+
 
        g_byte_array_free(gp_byte_array, TRUE);
-       g_free(char_value.handle);
-       g_variant_unref(value);
        g_variant_iter_free(iter);
+       g_variant_unref(value);
 
        BT_DBG("-");
 }
 
-BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descriptor)
+BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
+                                                      gpointer user_data)
 {
        GDBusConnection *conn;
        GVariantBuilder *builder;
        guint offset = 0;
-       char *handle;
+       bt_gatt_resp_data_t *resp_data;
 
        BT_DBG("+");
-       BT_CHECK_PARAMETER(char_descriptor, return);
+
+       BT_CHECK_PARAMETER(desc, return);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
-       handle = g_strdup(char_descriptor);
+       resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
+       resp_data->user_data = user_data;
+       resp_data->handle = (char *)desc;
 
        builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
 
@@ -1481,18 +1587,12 @@ BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descript
 //  g_variant_builder_add(builder, "{sv}", "device",
 //  g_variant_new("o", serv_info->serv_path));
 
-       g_dbus_connection_call(conn,
-                       BT_BLUEZ_NAME,
-                       char_descriptor,
-                       GATT_DESC_INTERFACE,
-                       "ReadValue",
-                       g_variant_new("(a{sv})", builder),
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
+                       "ReadValue", g_variant_new("(a{sv})", builder),
                        G_VARIANT_TYPE("(ay)"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
                        (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
-                       (gpointer)handle);
+                       (gpointer)resp_data);
        g_variant_builder_unref(builder);
 
        BT_DBG("-");
@@ -1500,48 +1600,55 @@ BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descript
 }
 
 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
-                       GAsyncResult *res,
-                       gpointer user_data)
+                                       GAsyncResult *res, gpointer user_data)
 {
        GError *error = NULL;
        bt_user_info_t *user_info;
        GDBusConnection *system_gconn = NULL;
        GVariant *value;
-       int result = BLUETOOTH_ERROR_NONE;
-       guint8 att_ecode = 0;
+       int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
+       bt_gatt_resp_data_t *resp_data = user_data;
 
        BT_DBG("+");
-       user_info = _bt_get_user_data(BT_COMMON);
 
-       system_gconn = _bt_gdbus_get_system_gconn();
+       system_gconn = _bt_get_system_private_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
-       if (error) {
-               BT_ERR("Error : %s \n", error->message);
-               g_clear_error(&error);
-               result = BLUETOOTH_ERROR_INTERNAL;
-       } else {
-               g_variant_get(value, "(y)", &att_ecode);
-               if (att_ecode) {
-                       result =  att_ecode;
-                       BT_ERR("ATT Error code: %d \n", att_ecode);
+       user_info = _bt_get_user_data(BT_COMMON);
+       if (!user_info) {
+               if (error) {
+                       BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
+                       g_clear_error(&error);
+                       g_free(resp_data);
+                       return;
                }
+               g_free(resp_data);
+               g_variant_unref(value);
+               return;
        }
 
-       if (user_info) {
+       if (error) {
+               att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
+               g_clear_error(&error);
+
                _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
-                               result, NULL,
+                               att_ecode, resp_data,
                                user_info->cb, user_info->user_data);
+               g_free(resp_data);
+               return;
        }
 
-       if (value)
-               g_variant_unref(value);
+       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
+                               BLUETOOTH_ATT_ERROR_NONE, resp_data,
+                       user_info->cb, user_info->user_data);
+       g_free(resp_data);
 
+       g_variant_unref(value);
        BT_DBG("-");
 }
 
-BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
-                       const char *desc_handle, const guint8 *value, int length)
+BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
+                       const guint8 *value, int length, gpointer user_data)
 {
        GVariant *val, *options;
        GDBusConnection *conn;
@@ -1549,14 +1656,16 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
        GVariantBuilder *builder2;
        guint offset = 0;
        int i;
+       bt_gatt_resp_data_t *resp_data;
 
        BT_DBG("+");
-       BT_CHECK_PARAMETER(desc_handle, return);
+
+       BT_CHECK_PARAMETER(desc, return);
        BT_CHECK_PARAMETER(value, return);
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1572,23 +1681,21 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
                                g_variant_new_uint16(offset));
 
        /* Device Object path*/
-//  g_variant_builder_add(builder2, "{sv}", "device",
-//  g_variant_new_object("o", NULL));
+//     g_variant_builder_add(builder2, "{sv}", "device",
+//     g_variant_new_object("o", NULL));
 
        options = g_variant_new("a{sv}", builder2);
 
-       g_dbus_connection_call(conn,
-                               BT_BLUEZ_NAME,
-                               desc_handle,
-                               GATT_DESC_INTERFACE,
-                               "WriteValue",
-                               g_variant_new("(@ay@a{sv})",
-                               val, options),
-                               G_VARIANT_TYPE("(y)"),
-                               G_DBUS_CALL_FLAGS_NONE,
-                               -1, NULL,
-                               (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
-                               NULL);
+       resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
+       resp_data->user_data = user_data;
+       resp_data->handle = (char *)desc;
+
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
+                       "WriteValue", g_variant_new("(@ay@a{sv})",
+                       val, options), NULL,
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+                       (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
+                       (gpointer)resp_data);
 
        g_variant_builder_unref(builder1);
        g_variant_builder_unref(builder2);
@@ -1597,7 +1704,7 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
        return BLUETOOTH_ERROR_NONE;
 }
 
-BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
+BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle, const char *svc_name)
 {
        GDBusConnection *conn;
        GError *error = NULL;
@@ -1606,9 +1713,9 @@ BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
        BT_CHECK_PARAMETER(char_handle, return);
        BT_CHECK_ENABLED(return);
 
-       BT_INFO_C("### Enable CCCD : %s", char_handle);
+       BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        g_dbus_connection_call_sync(conn,
@@ -1649,7 +1756,6 @@ BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
 
 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
 {
-
        GDBusConnection *conn;
        GError *error = NULL;
        int ret = BLUETOOTH_ERROR_NONE;
@@ -1659,7 +1765,7 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle
 
        BT_INFO("Disable CCCD : %s", char_handle);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        g_dbus_connection_call_sync(conn,
@@ -1680,3 +1786,1012 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle
 
        return ret;
 }
+
+void __bt_uuid_hex_to_string(unsigned char *uuid, char *str)
+{
+       uint32_t uuid0, uuid4;
+       uint16_t uuid1, uuid2, uuid3, uuid5;
+
+       memcpy(&uuid0, &(uuid[0]), 4);
+       memcpy(&uuid1, &(uuid[4]), 2);
+       memcpy(&uuid2, &(uuid[6]), 2);
+       memcpy(&uuid3, &(uuid[8]), 2);
+       memcpy(&uuid4, &(uuid[10]), 4);
+       memcpy(&uuid5, &(uuid[14]), 2);
+
+       snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
+                       ntohl(uuid0), ntohs(uuid1),
+                       ntohs(uuid2), ntohs(uuid3),
+                       ntohl(uuid4), ntohs(uuid5));
+       return;
+}
+
+
+static void __bt_fill_service_handle_informations(bt_services_browse_info_t *props,
+               bt_gatt_handle_info_t *svcs)
+{
+       int count;
+
+       if (props->count == 0)
+               return;
+
+       svcs->count = props->count;
+
+       for (count = 0; count < props->count; count++) {
+               BT_DBG("[%d] %s  instance_id [%d] Is Primary [%d]",
+                               count, props->uuids[count], props->inst_id[count], props->primary[count]);
+               g_strlcpy(svcs->uuids[count], props->uuids[count],
+                               BLUETOOTH_UUID_STRING_MAX);
+               svcs->inst_id[count] = props->inst_id[count];
+       }
+}
+
+static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props, bt_gatt_service_property_t *service)
+{
+       int count;
+       char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+       service->char_handle.count = props->count;
+
+       /* Before filling all char handles, fill the service's UUID and instance ID */
+       __bt_uuid_hex_to_string(props->svc_uuid, uuid_string);
+       service->uuid = g_strdup(uuid_string);
+       service->primary = TRUE;
+
+       /* Now fill all the char handles [UUID and Instance ID's]*/
+       for (count = 0; count < props->count; count++) {
+               BT_DBG("[%d] %s  instance_id [%d] properties [%d]",
+                               count, props->uuids[count], props->inst_id[count], props->props[count]);
+
+               g_strlcpy(service->char_handle.uuids[count],
+                               props->uuids[count],
+                               BLUETOOTH_UUID_STRING_MAX);
+
+               service->char_handle.inst_id[count] = props->inst_id[count];
+       }
+}
+
+static void __bt_fill_desc_handle_informations(bt_descriptor_browse_info_t *props,
+               bt_gatt_char_property_t *charc)
+{
+       int count;
+       char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+       charc->char_desc_handle.count = props->count;
+
+       /* Before filling all desc handles, fill the charac's UUID and instance ID */
+       __bt_uuid_hex_to_string(props->char_uuid, uuid_string);
+       charc->uuid = g_strdup(uuid_string);
+
+       /* Now fill all the descriptor handles [UUID and Instance ID's]*/
+       for (count = 0; count < props->count; count++) {
+               BT_DBG("[%d] %s  instance_id [%d]",
+                               count, props->uuids[count], props->inst_id[count]);
+
+               g_strlcpy(charc->char_desc_handle.uuids[count],
+                               props->uuids[count],
+                               BLUETOOTH_UUID_STRING_MAX);
+
+               charc->char_desc_handle.inst_id[count] = props->inst_id[count];
+       }
+       charc->permission = props->char_props_map;
+       __convert_permission_flag_to_str(charc->permission);
+}
+
+
+BT_EXPORT_API int bluetooth_gatt_client_init(
+               int *client_id,
+               const bluetooth_device_address_t *address,
+               gatt_client_cb_func_ptr callback_ptr)
+{
+       int ret = BLUETOOTH_ERROR_NONE;
+       bt_event_info_t *event_info;
+       int *count;
+
+       BT_CHECK_PARAMETER(client_id, return);
+       BT_CHECK_PARAMETER(callback_ptr, return);
+       BT_CHECK_ENABLED(return);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
+
+       ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_REGISTER,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       /* App ID -1 is invalid */
+       if (ret == BLUETOOTH_ERROR_NONE) {
+
+               *client_id = g_array_index(out_param, int, 0);
+
+               BT_INFO("GATT Client Registered successfully: Client instance ID [%d]", *client_id);
+
+               event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
+
+               if (event_info) {
+                       count = (int*)event_info->user_data;
+
+                       BT_INFO("Total num of GATT client instances [%d]", *count);
+
+                       /* Increement the count */
+                       *count += 1;
+               } else {
+                       BT_INFO("No GATT Client instances found in this application: Set User data");
+                       count = g_malloc0(sizeof(int));
+                       *count = 1;
+
+                       /* Register event handler for GATT */
+                       _bt_register_event(BT_GATT_CLIENT_EVENT,
+                                       (void *)callback_ptr,
+                                       (void *)count);
+                       _bt_set_user_data(BT_GATT_CLIENT, (void *)callback_ptr, NULL);
+               }
+       } else
+               BT_ERR("GATT Client Registration failed!! ret [%d]", ret);
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return ret;
+}
+
+
+
+/* GATT Client*/
+BT_EXPORT_API int bluetooth_gatt_client_get_primary_services(
+               const bluetooth_device_address_t *address, /* Remote GATT Server */
+               bt_gatt_handle_info_t *prim_svc) /* UUID & instance_id */
+{
+
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_services_browse_info_t service_props;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(prim_svc, return);
+       BT_CHECK_ENABLED(return);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE,
+                       BT_GATT_GET_PRIMARY_SERVICES,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (BLUETOOTH_ERROR_NONE != result)
+               goto done;
+
+       memset(&service_props, 0x00, sizeof(bt_services_browse_info_t));
+
+       service_props = g_array_index(
+                       out_param, bt_services_browse_info_t, 0);
+
+       __bt_fill_service_handle_informations(
+                       &service_props, prim_svc);
+
+done:
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_get_service_property(
+               const char *address,
+               bt_gatt_handle_property_t *service_handle,
+               bt_gatt_service_property_t *service)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bluetooth_gatt_client_svc_prop_info_t svc_prop;
+       bt_char_browse_info_t char_handles_info;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(service, return);
+       BT_CHECK_ENABLED(return);
+
+       /* Call to bt-service (sync) and send address and service_handle info */
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       memset(&svc_prop, 0x00, sizeof(bluetooth_gatt_client_svc_prop_info_t));
+       /* All characteristics handles are discovered */
+       memset(&char_handles_info, 0x00, sizeof(bt_char_browse_info_t));
+
+       svc_prop.svc.instance_id = service_handle->instance_id;
+       memcpy(&svc_prop.svc.uuid, &service_handle->uuid, 16);
+
+       _bt_convert_addr_string_to_type(svc_prop.device_address.addr, address);
+
+       g_array_append_vals(in_param1, &svc_prop, sizeof(bluetooth_gatt_client_svc_prop_info_t));
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE,
+                       BT_GATT_GET_SERVICE_PROPERTIES,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (BLUETOOTH_ERROR_NONE != result)
+               goto done;
+
+       char_handles_info = g_array_index(
+                       out_param, bt_char_browse_info_t, 0);
+       __bt_fill_char_handle_informations(&char_handles_info,
+                       service);
+       /* TODO Get all Included Services */
+
+done:
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_get_characteristics_property(
+               const char *address,
+               bt_gatt_handle_property_t *service_handle,
+               bt_gatt_handle_property_t *char_handle,
+               bt_gatt_char_property_t *char_property)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_descriptor_browse_info_t desc_handles_info;
+       bluetooth_gatt_client_char_prop_info_t char_prop;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(char_handle, return);
+       BT_CHECK_PARAMETER(char_property, return);
+       BT_CHECK_ENABLED(return);
+
+
+       /* Call to bt-service (sync) and send address service_handle info & char handle info  */
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       memset(&char_prop, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
+       char_prop.svc.instance_id = service_handle->instance_id;
+       memcpy(&char_prop.svc.uuid, &service_handle->uuid, 16);
+
+       char_prop.characteristic.instance_id = char_handle->instance_id;
+       memcpy(&char_prop.characteristic.uuid, &char_handle->uuid, 16);
+
+       _bt_convert_addr_string_to_type(char_prop.device_address.addr, address);
+
+       g_array_append_vals(in_param1, &char_prop, sizeof(bluetooth_gatt_client_char_prop_info_t));
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE,
+                       BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (BLUETOOTH_ERROR_NONE != result)
+               goto done;
+
+       /* All descriptors handles are discovered */
+       memset(&desc_handles_info, 0x00, sizeof(bt_descriptor_browse_info_t));
+
+       desc_handles_info = g_array_index(
+                       out_param, bt_descriptor_browse_info_t, 0);
+
+       __bt_fill_desc_handle_informations(&desc_handles_info,
+                       char_property);
+
+done:
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return result;
+       /* Call to bt-service (sync) and send address, service_handle & char_handle infos */
+
+       /* After result is fetched, extract descriptor handles (UUID's & instance_id's) */
+
+       /* Fill the info in *char_prop */
+
+       /*No: Before returning, call bluetooth_gatt_client_read_characteristic_value as
+               an asyn function and leave every thing else in the callback */
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_get_char_descriptor_property(
+               const char *address,
+               bt_gatt_handle_property_t *service_handle,
+               bt_gatt_handle_property_t *char_handle,
+               bt_gatt_handle_property_t *descriptor_handle,
+               bt_gatt_char_descriptor_property_t *desc_prop)
+{
+       char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(char_handle, return);
+       BT_CHECK_PARAMETER(descriptor_handle, return);
+       BT_CHECK_PARAMETER(desc_prop, return);
+       /* No Need to Call to bt-service (sync) and send address, service_handle,
+               char_handle & descriptor handle infos */
+       /* After result is fetched, extract descriptior handles (UUID's & instance_id's) */
+       /* Fill the info in *desc_prop */
+       __bt_uuid_hex_to_string(descriptor_handle->uuid, uuid_string);
+
+       /* Before filling all desc handles, fill the charac's UUID and instance ID */
+       desc_prop->uuid = g_strdup(uuid_string);
+
+       return BLUETOOTH_ERROR_NONE;
+       /* No: Before returning, call bluetooth_gatt_client_read_descriptor_value
+               as an asyn function and leave every thing else in the callback */
+}
+
+
+static gboolean  bluetooth_gatt_client_notify_channel_watch_cb(GIOChannel *gio,
+                                       GIOCondition cond, gpointer data)
+{
+       bt_gatt_characteristic_notify_info_t *chr_info = (bt_gatt_characteristic_notify_info_t *)data;
+
+       if (!chr_info) {
+               BT_ERR("chr_info is invalid");
+               return FALSE;
+       }
+       if (cond & G_IO_IN) {
+               GIOStatus status = G_IO_STATUS_NORMAL;
+               GError *err = NULL;
+               char *buffer = NULL;
+               gsize len = 0;
+               bt_event_info_t *event_info;
+
+               buffer = g_malloc0(chr_info->mtu + 1);
+               memset(buffer, 0, chr_info->mtu + 1);
+
+               status = g_io_channel_read_chars(gio, buffer,
+                               chr_info->mtu, &len, &err);
+               if (status != G_IO_STATUS_NORMAL) {
+                       BT_ERR("IO Channel read is failed with %d", status);
+                       g_free(buffer);
+                       if (err) {
+                               BT_ERR("IO Channel read error [%s]", err->message);
+                               if (status == G_IO_STATUS_ERROR) {
+                                       BT_ERR("cond : %d", cond);
+                                       g_error_free(err);
+                                       g_io_channel_shutdown(gio, TRUE, NULL);
+                                       g_io_channel_unref(gio);
+
+                                       gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
+                                       g_free(chr_info);
+                                       return FALSE;
+                               }
+                               g_error_free(err);
+                       }
+                       return FALSE;
+               }
+
+               if (len > 0 && len < chr_info->mtu) {
+                       bt_gatt_char_property_t char_val;
+//                      BT_DBG("FD io sending  value changed  %x %x %x %x %x %x %x %zd \n", buffer[0], buffer[1], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], len);
+
+                       memcpy(char_val.prop.uuid, chr_info->UUID, 16);
+                       memcpy(char_val.value, buffer, len);
+                       char_val.val_len = len;
+                       memcpy(char_val.address, chr_info->address, 18);
+
+                       event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
+                       if (event_info) {
+                               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
+                                                       BLUETOOTH_ERROR_NONE, &char_val,
+                                                       event_info->cb, event_info->user_data);
+                       } else {
+                               BT_ERR("event_info failed");
+                       }
+
+               } else
+                       BT_ERR("Packet corrupted");
+
+               g_free(buffer);
+
+               return TRUE;
+       }
+
+       if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+               BT_ERR("Error : GIOCondition %d, [%s]", cond, chr_info->UUID);
+               g_io_channel_shutdown(gio, TRUE, NULL);
+               g_io_channel_unref(gio);
+
+               gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
+               g_free(chr_info);
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+#ifndef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
+static bt_gatt_characteristic_notify_info_t * bluetooth_gatt_client_get_characteristic_notify_info(unsigned  char *handle , int id)
+{
+       GSList *l;
+
+       for (l = gatt_characteristic_notify_list; l != NULL; l = l->next) {
+               bt_gatt_characteristic_notify_info_t *info = l->data;
+               if (memcmp(info->UUID, handle, 16) == 0 && info->id == id)
+                       return info;
+       }
+       return NULL;
+}
+#endif
+
+static bt_gatt_characteristic_notify_info_t *  bluetooth_gatt_client_create_watch_io(int fd, int id, int mtu, char * address, unsigned char *uuid)
+{
+       GIOChannel *channel;
+       bt_gatt_characteristic_notify_info_t *chr_info;
+
+       chr_info = g_malloc0(sizeof(bt_gatt_characteristic_notify_info_t));
+       chr_info->notify_fd = fd;
+       chr_info->id = id;
+       chr_info->mtu = mtu;
+       g_strlcpy(chr_info->address, address, 18);
+       memcpy(chr_info->UUID, uuid, 16);
+
+       channel = g_io_channel_unix_new(fd);
+
+       chr_info->io_channel = channel;
+
+       g_io_channel_set_encoding(channel, NULL, NULL);
+       g_io_channel_set_buffered(channel, FALSE);
+       g_io_channel_set_close_on_unref(channel, TRUE);
+       g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+
+       chr_info->watch_id = g_io_add_watch(channel, (G_IO_IN | G_IO_ERR | G_IO_HUP),
+                        bluetooth_gatt_client_notify_channel_watch_cb, chr_info);
+
+       return chr_info;
+
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
+                       const char *address,
+                       bt_gatt_handle_property_t *service_handle,
+                       bt_gatt_handle_property_t *char_handle,
+                       int client_id,
+                       gboolean is_notify,
+                       gboolean is_indicate)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bluetooth_gatt_client_char_prop_info_t param;
+       bt_gatt_characteristic_notify_info_t *chr_info;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(char_handle, return);
+
+#ifndef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
+       chr_info = bluetooth_gatt_client_get_characteristic_notify_info(char_handle->uuid , char_handle->instance_id);
+       if (chr_info && !is_notify) {
+               BT_INFO("Already CCCD enabled. fd %d", chr_info->notify_fd);
+
+               if (chr_info->watch_id > 0)
+                       g_source_remove(chr_info->watch_id);
+
+               if (chr_info->io_channel) {
+                       g_io_channel_shutdown(chr_info->io_channel, TRUE, NULL);
+                       g_io_channel_unref(chr_info->io_channel);
+               }
+
+               gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
+
+               g_free(chr_info);
+
+               return result;
+       }
+#endif
+
+       /* ASync Function, result expected in callback from bt-service */
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       memset(&param, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
+
+       memcpy(&param.svc.uuid, service_handle->uuid, 16);
+       param.svc.instance_id = service_handle->instance_id;
+
+       memcpy(&param.characteristic.uuid, char_handle->uuid, 16);
+       param.characteristic.instance_id = char_handle->instance_id;
+
+       _bt_convert_addr_string_to_type(param.device_address.addr, address);
+
+       g_array_append_vals(in_param1, &param, sizeof(bluetooth_gatt_client_char_prop_info_t));
+       g_array_append_vals(in_param2, &client_id, sizeof(int));
+       g_array_append_vals(in_param3, &is_notify, sizeof(gboolean));
+       g_array_append_vals(in_param4, &is_indicate, sizeof(gboolean));
+
+#ifdef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
+       result = _bt_send_request(BT_BLUEZ_SERVICE,
+                       BT_GATT_WATCH_CHARACTERISTIC,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       BT_INFO("Result [%d]", result);
+       return result;
+#endif
+
+       GUnixFDList *out_fd_list = NULL;
+       char *svc_name = NULL;
+       char  str_uuid[37];
+
+       _bt_convert_uuid_type_to_string(str_uuid, param.svc.uuid);
+       bluetooth_get_uuid_name(str_uuid, &svc_name);
+
+       _bt_convert_uuid_type_to_string(str_uuid, param.characteristic.uuid);
+
+       BT_INFO_C("### Request subscription Notify : %s [%s]", str_uuid, svc_name);
+       g_free(svc_name);
+
+       result  = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_WATCH_CHARACTERISTIC,
+                                                       in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
+       if (result != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("Fail to get Nofify FD. result %d", result);
+               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+               return result;
+       }
+
+       if (is_indicate == false) {
+               if (NULL == out_fd_list) {
+                       BT_ERR("out_fd_list is NULL");
+                       result = BLUETOOTH_ERROR_INTERNAL;
+               } else {
+                       int *fd_list_array;
+                       int len = 0;
+                       int mtu;
+                       int fd = -1;
+
+                       fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
+                       BT_DBG("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
+                       fd = fd_list_array[0];
+                       mtu =  g_array_index(out_param, int, 0);
+
+                       BT_INFO("Acquired characteristic Notify FD %d, mtu %d", fd, mtu);
+                       chr_info = bluetooth_gatt_client_create_watch_io(fd, char_handle->instance_id, mtu, (char *)address, char_handle->uuid);
+
+                       gatt_characteristic_notify_list = g_slist_append(gatt_characteristic_notify_list, chr_info);
+
+                       g_free(fd_list_array);
+                       g_object_unref(out_fd_list);
+               }
+       }
+
+       /*result = _bt_send_request(BT_BLUEZ_SERVICE,
+                       BT_GATT_WATCH_CHARACTERISTIC,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);*/
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_read_characteristic_value(
+               const char *address,
+               bt_gatt_handle_property_t *service_handle,
+               bt_gatt_handle_property_t *char_handle)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_user_info_t *user_info;
+       bluetooth_gatt_client_char_prop_info_t param;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(char_handle, return);
+
+       user_info = _bt_get_user_data(BT_GATT_CLIENT);
+       retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       /* Async Function, result expected in callback from bt-service */
+       /* Call to bt-service (sync) and send address service_handle info & char handle info  */
+       memset(&param, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
+
+       memcpy(&param.svc.uuid, service_handle->uuid, 16);
+       param.svc.instance_id = service_handle->instance_id;
+
+       memcpy(&param.characteristic.uuid, char_handle->uuid, 16);
+       param.characteristic.instance_id = char_handle->instance_id;
+
+       _bt_convert_addr_string_to_type(param.device_address.addr, address);
+
+       g_array_append_vals(in_param1, &param,
+                       sizeof(bluetooth_gatt_client_char_prop_info_t));
+
+       result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_CHARACTERISTIC,
+                       in_param1, in_param2, in_param3, in_param4,
+                       user_info->cb, user_info->user_data);
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_read_descriptor_value(
+               const char *address,
+               bt_gatt_handle_property_t *service_handle,
+               bt_gatt_handle_property_t *char_handle,
+               bt_gatt_handle_property_t *descriptor_handle)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_user_info_t *user_info;
+       bluetooth_gatt_client_desc_prop_info_t param;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(char_handle, return);
+       BT_CHECK_PARAMETER(descriptor_handle, return);
+
+       user_info = _bt_get_user_data(BT_GATT_CLIENT);
+       retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       /* Async Function, result expected in callback from bt-service */
+       memset(&param, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
+
+       memcpy(&param.svc.uuid, service_handle->uuid, 16);
+       param.svc.instance_id = service_handle->instance_id;
+
+       memcpy(&param.characteristic.uuid, char_handle->uuid, 16);
+       param.characteristic.instance_id = char_handle->instance_id;
+
+       memcpy(&param.descriptor.uuid, descriptor_handle->uuid, 16);
+       param.descriptor.instance_id = descriptor_handle->instance_id;
+
+       _bt_convert_addr_string_to_type(param.device_address.addr, address);
+
+       g_array_append_vals(in_param1, &param,
+                       sizeof(bluetooth_gatt_client_desc_prop_info_t));
+
+       result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_DESCRIPTOR_VALUE,
+                       in_param1, in_param2, in_param3, in_param4,
+                       user_info->cb, user_info->user_data);
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return result;
+}
+
+
+static bt_gatt_characteristic_write_info_t *  bluetooth_gatt_client_get_characteristic_fd(unsigned  char *handle, int id)
+{
+       GSList *l;
+       char  str[37];
+
+       for (l = gatt_characteristic_write_list; l != NULL; l = l->next) {
+               bt_gatt_characteristic_write_info_t *info = l->data;
+
+               if (memcmp(info->UUID, handle, 16) ==  0 &&  info->id == id)
+                       return info;
+       }
+
+       _bt_convert_uuid_type_to_string(str, handle);
+       BT_ERR("Unable to get characteristic fd. [%s] id [ %d]", str, id);
+       return NULL;
+}
+
+static gboolean  bluetooth_gatt_client_write_channel_watch_cb(GIOChannel *gio,
+                                       GIOCondition cond, gpointer data)
+{
+       bt_gatt_characteristic_write_info_t *chr_info = (bt_gatt_characteristic_write_info_t *)data;
+
+       if (!chr_info)
+               return FALSE;
+
+       if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+               char  uuid_str[37];
+               _bt_convert_uuid_type_to_string(uuid_str, chr_info->UUID);
+               BT_ERR("Error : GIOCondition %d, [%s]", cond, uuid_str);
+               g_io_channel_shutdown(gio, TRUE, NULL);
+               g_io_channel_unref(gio);
+
+               gatt_characteristic_write_list = g_slist_remove(gatt_characteristic_write_list, chr_info);
+               g_free(chr_info);
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static int  bluetooth_gatt_client_write_characteristics_value_to_fd(
+                        int fd, const guint8 *value, int length, int mtu,
+                       gpointer user_data)
+{
+       int written;
+       int att_result = BLUETOOTH_ERROR_NONE;
+       BT_CHECK_PARAMETER(value, return);
+       written = write(fd, value, length);
+       if (written != length) {
+               att_result = BLUETOOTH_ERROR_INTERNAL;
+               BT_ERR("write data failed.  ret : %d ", written);
+       }
+
+       return att_result;
+}
+
+static void  bluetooth_gatt_client_create_write_io_channel(int fd, unsigned char * uuid, int id, int mtu)
+{
+       bt_gatt_characteristic_write_info_t *chr_info;
+       GIOChannel *channel;
+
+       chr_info = g_malloc0(sizeof(bt_gatt_characteristic_write_info_t));
+       chr_info->write_fd = fd;
+       chr_info->id = id;
+       chr_info->mtu = mtu;
+
+       memcpy(chr_info->UUID, uuid, 16);
+       channel = g_io_channel_unix_new(fd);
+       g_io_channel_set_encoding(channel, NULL, NULL);
+       g_io_channel_set_buffered(channel, FALSE);
+       g_io_channel_set_close_on_unref(channel, TRUE);
+       g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_add_watch(channel, (G_IO_ERR | G_IO_HUP | G_IO_NVAL),
+                        bluetooth_gatt_client_write_channel_watch_cb, chr_info);
+
+       gatt_characteristic_write_list = g_slist_append(gatt_characteristic_write_list, chr_info);
+
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
+               const char *address,
+               bt_gatt_handle_property_t *service_handle,
+               bt_gatt_handle_property_t *char_handle,
+               bluetooth_gatt_att_data_t *data,
+               bluetooth_gatt_write_type_e  write_type)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_user_info_t *user_info;
+       bluetooth_gatt_client_char_prop_info_t param;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(char_handle, return);
+       BT_CHECK_PARAMETER(data, return);
+
+       /* ASync Function, result expected in callback from bt-service */
+       user_info = _bt_get_user_data(BT_GATT_CLIENT);
+       retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       memset(&param, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
+
+       memcpy(&param.svc.uuid, service_handle->uuid, 16);
+       param.svc.instance_id = service_handle->instance_id;
+
+       memcpy(&param.characteristic.uuid, char_handle->uuid, 16);
+       param.characteristic.instance_id = char_handle->instance_id;
+
+       _bt_convert_addr_string_to_type(param.device_address.addr, address);
+
+       g_array_append_vals(in_param1, &param, sizeof(bluetooth_gatt_client_char_prop_info_t));
+       g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
+       g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
+
+#ifdef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
+       goto done;
+#endif
+
+       if (write_type == BLUETOOTH_GATT_TYPE_WRITE_NO_RESPONSE) {
+               int fd = -1;
+               int mtu = 0;
+               bt_gatt_characteristic_write_info_t *info;
+               info =  bluetooth_gatt_client_get_characteristic_fd(char_handle->uuid, service_handle->instance_id);
+
+               if (info) {
+                       fd = info->write_fd;
+                       mtu = info->mtu;
+               }
+
+               if (fd < 0) {
+
+                       GUnixFDList *out_fd_list = NULL;
+
+                       result  = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_ACQUIRE_WRITE,
+                                       in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
+
+                       mtu =  g_array_index(out_param, int, 0);
+
+                       if (result != BLUETOOTH_ERROR_NONE) {
+                               BT_ERR("Fail to get Write FD. result %d", result);
+                               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+                               return result;
+                       } else if (NULL == out_fd_list) {
+                               BT_ERR("out_fd_list is NULL");
+                               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       } else {
+                               int *fd_list_array;
+                               int len = 0;
+
+                               fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
+                               fd = fd_list_array[0];
+
+                               g_free(fd_list_array);
+                               g_object_unref(out_fd_list);
+                       }
+                       BT_INFO("Acquired characteristic Write FD %d, mtu %d", fd, mtu);
+
+                       if (fd > -1) {
+                               bluetooth_gatt_client_create_write_io_channel(fd, char_handle->uuid, service_handle->instance_id, mtu);
+
+                               result =  bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
+
+                       } else {
+                               BT_ERR("characteristic info  FD is invalid");
+                               goto done;
+                       }
+
+               } else {
+                       result =  bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
+               }
+
+       } else {
+done:
+               result = _bt_send_request_async(BT_BLUEZ_SERVICE,
+                       BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
+                       in_param1, in_param2, in_param3, in_param4,
+                       user_info->cb, user_info->user_data);
+       }
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_write_descriptor_value(
+               const char *address,
+               bt_gatt_handle_property_t *service_handle,
+               bt_gatt_handle_property_t *char_handle,
+               bt_gatt_handle_property_t *descriptor_handle,
+               bluetooth_gatt_att_data_t *data,
+               bluetooth_gatt_write_type_e  write_type)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_user_info_t *user_info;
+       bluetooth_gatt_client_desc_prop_info_t param;
+
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(service_handle, return);
+       BT_CHECK_PARAMETER(char_handle, return);
+       BT_CHECK_PARAMETER(descriptor_handle, return);
+       BT_CHECK_PARAMETER(data, return);
+
+       /* Async Function, result expected in callback from bt-service */
+       user_info = _bt_get_user_data(BT_GATT_CLIENT);
+       retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       memset(&param, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
+
+       memcpy(&param.svc.uuid, service_handle->uuid, 16);
+       param.svc.instance_id = service_handle->instance_id;
+
+       memcpy(&param.characteristic.uuid, char_handle->uuid, 16);
+       param.characteristic.instance_id = char_handle->instance_id;
+
+       memcpy(&param.descriptor.uuid, descriptor_handle->uuid, 16);
+       param.descriptor.instance_id = descriptor_handle->instance_id;
+
+       _bt_convert_addr_string_to_type(param.device_address.addr, address);
+
+       g_array_append_vals(in_param1, &param, sizeof(bluetooth_gatt_client_desc_prop_info_t));
+       g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
+       g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
+
+       result = _bt_send_request_async(BT_BLUEZ_SERVICE,
+                       BT_GATT_WRITE_DESCRIPTOR_VALUE,
+                       in_param1, in_param2, in_param3, in_param4,
+                       user_info->cb, user_info->user_data);
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_set_service_change_watcher(
+               const bluetooth_device_address_t *address, gboolean enable)
+{
+       GSList *l;
+       bluetooth_device_address_t *addr = NULL;
+       char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
+       char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
+       int result = BLUETOOTH_ERROR_NONE;
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
+       g_array_append_vals(in_param2, &enable, sizeof(gboolean));
+
+       _bt_convert_addr_type_to_string(device_address, (unsigned char *)address->addr);
+       _bt_convert_addr_string_to_secure_string(secure_address, device_address);
+       BT_INFO("%s watcher for [%s]", enable ? "Set":"Unset", secure_address);
+
+       if (enable == TRUE) {
+               if (_bluetooth_gatt_check_service_change_watcher_address(address)
+                               == TRUE) {
+                       BT_INFO("The watcher is already set");
+                       goto done;
+               }
+
+               if (service_monitor_list == NULL) {
+                       //_bt_register_manager_subscribe_signal(TRUE);
+
+                       result = _bt_send_request(BT_BLUEZ_SERVICE,
+                                       BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
+                                       in_param1, in_param2, in_param3, in_param4, &out_param);
+               }
+
+               if (result == BLUETOOTH_ERROR_NONE) {
+                       addr = g_malloc0(sizeof(bluetooth_device_address_t));
+                       memcpy(addr, address, sizeof(bluetooth_device_address_t));
+
+                       service_monitor_list =
+                               g_slist_append(service_monitor_list, addr);
+               }
+       } else {
+               for (l = service_monitor_list; l != NULL; l = l->next) {
+                       addr = l->data;
+
+                       if (!memcmp(address, addr,
+                                               sizeof(bluetooth_device_address_t))) {
+                               service_monitor_list =
+                                       g_slist_remove(service_monitor_list, addr);
+                               g_free(addr);
+                               break;
+                       }
+               }
+
+               if (service_monitor_list == NULL) {
+                       //_bt_register_manager_subscribe_signal(FALSE);
+                       result = _bt_send_request(BT_BLUEZ_SERVICE,
+                                       BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
+                                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+               }
+       }
+
+done:
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_deinit(
+               int client_id)
+{
+       int result;
+       int *count;
+       bt_event_info_t *event_info;
+
+       BT_CHECK_ENABLED(return);
+
+       BT_INFO("GATT Client Deinit Client instance ID [%d]", client_id);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, &client_id, sizeof(int));
+
+       /* Unregistration MUST NOT FAIL */
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_UNREGISTER,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (result != BLUETOOTH_ERROR_NONE)
+               BT_ERR("GATT Client Unregistration failed result [%d]", result);
+
+       /* Unregister event handler if this is the only instance */
+       event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
+
+       if (event_info) {
+               count = (int*)event_info->user_data;
+
+               BT_DBG("Total num of GATT client instances [%d]", *count);
+
+               if (*count == 1) {
+                       BT_DBG("Currently only one GATT client instance, so remove it and unregister GATT client events");
+                       _bt_unregister_event(BT_GATT_CLIENT_EVENT);
+                       _bt_set_user_data(BT_GATT_CLIENT, NULL, NULL);
+               } else
+                       *count -= 1;
+       } else
+               BT_ERR("Impossible that client is created, but no event handler is registered!!!");
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       return result;
+}