[GATT Client] Delivery ATT error code to higher layer
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-client.c
index 872b21f..aad09f1 100644 (file)
@@ -872,6 +872,51 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
        return BLUETOOTH_ERROR_NONE;
 }
 
+static int __bluetooth_get_att_error_code(GError *error)
+{
+       int att_ecode = 0;
+       int len;
+       char *str = NULL;
+
+       BT_ERR("Error : %s", error->message);
+       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:
+               break;
+       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;
+       }
+
+       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)
@@ -884,48 +929,30 @@ static void __bluetooth_internal_read_cb(GObject *source_object,
        GByteArray *gp_byte_array = NULL;
        GVariantIter *iter;
        guint8 g_byte;
-       gint att_error_code;
-       int ret = BLUETOOTH_ERROR_NONE;
+       int att_ecode = 0;
 
        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) {
-               BT_ERR("Error : %s \n", error->message);
-               if (g_strrstr(error->message, "Not paired"))
-                       ret = BLUETOOTH_ERROR_NOT_PAIRED;
-               else
-                       ret = BLUETOOTH_ERROR_INTERNAL;
-
+               att_ecode = __bluetooth_get_att_error_code(error);
                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);
-               return;
-       }
-
-       char_value.char_handle = user_data;
-
-       g_variant_get(value, "(yay)", &att_error_code, &iter);
-
-       if (att_error_code != 0) {
-               if (user_info) {
-                       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
-                               att_error_code, NULL,
+                               att_ecode, NULL,
                                user_info->cb, user_info->user_data);
                }
                g_free(char_value.char_handle);
                g_variant_unref(value);
-               g_variant_iter_free(iter);
                return;
        }
 
+       g_variant_get(value, "(ay)", &iter);
+
        gp_byte_array = g_byte_array_new();
        while (g_variant_iter_loop(iter, "y", &g_byte))
                g_byte_array_append(gp_byte_array, &g_byte, 1);
@@ -937,7 +964,7 @@ static void __bluetooth_internal_read_cb(GObject *source_object,
 
        if (user_info) {
                _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
-                               BLUETOOTH_ERROR_NONE, &char_value,
+                               BLUETOOTH_ATT_ERROR_NONE, &char_value,
                                user_info->cb, user_info->user_data);
        }
 
@@ -980,7 +1007,7 @@ BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *character
                        GATT_CHAR_INTERFACE,
                        "ReadValue",
                        g_variant_new("(a{sv})", builder),
-                       G_VARIANT_TYPE("(yay)"),
+                       G_VARIANT_TYPE("(ay)"),
                        G_DBUS_CALL_FLAGS_NONE,
                        -1,
                        NULL,
@@ -999,8 +1026,7 @@ static void __bluetooth_internal_write_cb(GObject *source_object,
        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;
 
        user_info = _bt_get_user_data(BT_COMMON);
 
@@ -1008,20 +1034,13 @@ static void __bluetooth_internal_write_cb(GObject *source_object,
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        if (error) {
-               BT_ERR("Error : %s \n", error->message);
+               att_ecode = __bluetooth_get_att_error_code(error);
                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,
+                               att_ecode, NULL,
                                user_info->cb, user_info->user_data);
        } else {
                BT_ERR("user info is null");
@@ -1077,7 +1096,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
                                "WriteValue",
                                g_variant_new("(@ay@a{sv})",
                                val, options),
-                               G_VARIANT_TYPE("(y)"),
+                               NULL,
                                G_DBUS_CALL_FLAGS_NONE,
                                -1, NULL,
                                (GAsyncReadyCallback)__bluetooth_internal_write_cb,
@@ -1141,7 +1160,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
                        "WriteValuebyType",
                        g_variant_new("(y@ay@a{sv})",
                        write_type, val, options),
-                       G_VARIANT_TYPE("(y)"),
+                       NULL,
                        G_DBUS_CALL_FLAGS_NONE,
                        -1, NULL,
                        (GAsyncReadyCallback)__bluetooth_internal_write_cb,
@@ -1198,7 +1217,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
                                "WriteValue",
                                g_variant_new("(@ay@a{sv})",
                                val, options),
-                               G_VARIANT_TYPE("(y)"),
+                               NULL,
                                G_DBUS_CALL_FLAGS_NONE,
                                -1, NULL,
                                (GAsyncReadyCallback)__bluetooth_internal_write_cb,
@@ -1338,6 +1357,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) {
@@ -1352,7 +1372,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;
        }
@@ -1369,13 +1389,13 @@ 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);
        }
        bluetooth_gatt_free_char_property(&characteristic);
 
+       g_free(characteristic.handle);
        g_variant_iter_free(char_iter);
        g_variant_unref(value);
        BT_DBG("-");
@@ -1429,7 +1449,7 @@ static void __bluetooth_internal_read_desc_cb(GObject *source_object,
        GByteArray *gp_byte_array = NULL;
        GVariantIter *iter;
        guint8 g_byte;
-       gint att_error_code;
+       int att_ecode = 0;
 
        BT_DBG("+");
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1439,31 +1459,20 @@ static void __bluetooth_internal_read_desc_cb(GObject *source_object,
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        if (error) {
-               BT_ERR("Error : %s \n", error->message);
+               att_ecode = __bluetooth_get_att_error_code(error);
                g_clear_error(&error);
                if (user_info) {
                        _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
-                                       BLUETOOTH_ERROR_INTERNAL, NULL,
+                                       att_ecode, NULL,
                                        user_info->cb, user_info->user_data);
                }
                g_free(char_value.handle);
-               return;
-       }
-
-       g_variant_get(value, "(yay)", &att_error_code, &iter);
-
-       if (att_error_code != 0) {
-               if (user_info) {
-                       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
-                               att_error_code, NULL,
-                               user_info->cb, user_info->user_data);
-               }
-               g_free(char_value.handle);
                g_variant_unref(value);
-               g_variant_iter_free(iter);
                return;
        }
 
+       g_variant_get(value, "(ay)", &iter);
+
        gp_byte_array = g_byte_array_new();
        while (g_variant_iter_loop(iter, "y",  &g_byte))
                g_byte_array_append(gp_byte_array, &g_byte, 1);
@@ -1475,7 +1484,7 @@ static void __bluetooth_internal_read_desc_cb(GObject *source_object,
 
        if (user_info) {
                _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
-                               BLUETOOTH_ERROR_NONE, &char_value,
+                               BLUETOOTH_ATT_ERROR_NONE, &char_value,
                                user_info->cb, user_info->user_data);
        }
 
@@ -1518,7 +1527,7 @@ BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descript
                        GATT_DESC_INTERFACE,
                        "ReadValue",
                        g_variant_new("(a{sv})", builder),
-                       G_VARIANT_TYPE("(yay)"),
+                       G_VARIANT_TYPE("(ay)"),
                        G_DBUS_CALL_FLAGS_NONE,
                        -1,
                        NULL,
@@ -1538,8 +1547,7 @@ static void __bluetooth_internal_write_desc_cb(GObject *source_object,
        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_DBG("+");
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1548,20 +1556,13 @@ static void __bluetooth_internal_write_desc_cb(GObject *source_object,
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        if (error) {
-               BT_ERR("Error : %s \n", error->message);
+               att_ecode = __bluetooth_get_att_error_code(error);
                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_DESC,
-                               result, NULL,
+                               att_ecode, NULL,
                                user_info->cb, user_info->user_data);
        }
 
@@ -1615,7 +1616,7 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
                                "WriteValue",
                                g_variant_new("(@ay@a{sv})",
                                val, options),
-                               G_VARIANT_TYPE("(y)"),
+                               NULL,
                                G_DBUS_CALL_FLAGS_NONE,
                                -1, NULL,
                                (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,