Enhance debug message
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-client.c
index aad09f1..555a266 100644 (file)
@@ -107,28 +107,12 @@ gboolean _bluetooth_gatt_check_service_change_watcher_address(
                const bluetooth_device_address_t *device_addr)
 {
        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 +124,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);
@@ -239,39 +220,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 +285,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 +317,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))
@@ -537,8 +523,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 +553,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)
 {
@@ -633,8 +652,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 +677,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")) {
@@ -843,7 +863,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,18 +892,18 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
        return BLUETOOTH_ERROR_NONE;
 }
 
-static int __bluetooth_get_att_error_code(GError *error)
+static int __bluetooth_get_att_error_code(GError *error, char *handle)
 {
        int att_ecode = 0;
        int len;
        char *str = NULL;
 
-       BT_ERR("Error : %s", error->message);
+       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]);
+               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;
 
@@ -895,7 +915,6 @@ static int __bluetooth_get_att_error_code(GError *error)
                BT_ERR("Write not permitted");
                break;
        case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
-               break;
        case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
        case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
                BT_ERR("Not paired");
@@ -918,78 +937,87 @@ static int __bluetooth_get_att_error_code(GError *error)
 }
 
 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 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();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
-       char_value.char_handle = user_data;
 
-       if (error) {
-               att_ecode = __bluetooth_get_att_error_code(error);
-               g_clear_error(&error);
-               if (user_info) {
-                       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
-                               att_ecode, NULL,
-                               user_info->cb, user_info->user_data);
+       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(char_value.char_handle);
+               g_free(resp_data);
                g_variant_unref(value);
                return;
        }
 
-       g_variant_get(value, "(ay)", &iter);
+       if (error) {
+               att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
+               g_clear_error(&error);
+
+               _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;
+       }
 
        gp_byte_array = g_byte_array_new();
+       g_variant_get(value, "(ay)", &iter);
+
        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 = 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_ATT_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();
        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}"));
 
@@ -1001,54 +1029,59 @@ BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *character
 //     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)
+                                         GAsyncResult *res, gpointer user_data)
 {
        GError *error = NULL;
-       bt_user_info_t *user_info;
        GDBusConnection *system_gconn = NULL;
+       bt_user_info_t *user_info;
        GVariant *value;
-       int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
-
-       user_info = _bt_get_user_data(BT_COMMON);
+       int att_ecode = 0;
+       bt_gatt_resp_data_t *resp_data = user_data;
 
        system_gconn = _bt_gdbus_get_system_gconn();
        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);
+               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_WRITE_CHAR,
-                               att_ecode, NULL,
+                               att_ecode, resp_data,
                                user_info->cb, user_info->user_data);
-       } else {
-               BT_ERR("user info is null");
+               g_free(resp_data);
+               return;
        }
 
-       if (value)
-               g_variant_unref(value);
+       _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;
 }
 
@@ -1117,7 +1150,8 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
 }
 
 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;
@@ -1126,8 +1160,9 @@ 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);
@@ -1153,21 +1188,21 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
 
        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_new("(y@ay@a{sv})", write_type, val, options),
                        NULL,
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1, 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;
 }
 
@@ -1442,75 +1477,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_gdbus_get_system_gconn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
-       if (error) {
-               att_ecode = __bluetooth_get_att_error_code(error);
-               g_clear_error(&error);
-               if (user_info) {
-                       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
-                                       att_ecode, NULL,
-                                       user_info->cb, user_info->user_data);
+       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(char_value.handle);
+               g_free(resp_data);
                g_variant_unref(value);
                return;
        }
 
-       g_variant_get(value, "(ay)", &iter);
+       if (error) {
+               att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
+               g_clear_error(&error);
+
+               _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();
-       while (g_variant_iter_loop(iter, "y",  &g_byte))
+       g_variant_get(value, "(ay)", &iter);
+
+       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_ATT_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();
        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}"));
 
@@ -1521,18 +1568,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("-");
@@ -1540,40 +1581,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 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();
        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);
+               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_WRITE_DESC,
-                               att_ecode, 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;
@@ -1581,9 +1637,11 @@ 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);
@@ -1609,18 +1667,16 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
 
        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),
-                               NULL,
-                               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);
@@ -1629,7 +1685,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;
@@ -1638,7 +1694,7 @@ 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();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);