gatt: Check error before retrying if Acquire* failed
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 31 Mar 2020 21:05:48 +0000 (14:05 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Mon, 12 Apr 2021 09:00:48 +0000 (14:30 +0530)
If the method has timed out it probably means the application is not
responding so a follow up method call might have the same result, also
in case the application returns org.bluez.Error.Failed it indicates the
operation has been attempted but failed which again most likely will
have the same result if reattempted.

Change-Id: Ie768f1e3613957f362b65fba12a03d0ee21bce9c
Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/gatt-database.c

index aef5e81..0f7d5d4 100644 (file)
@@ -53,6 +53,7 @@
 #define GATT_SERVICE_IFACE     "org.bluez.GattService1"
 #define GATT_CHRC_IFACE                "org.bluez.GattCharacteristic1"
 #define GATT_DESC_IFACE                "org.bluez.GattDescriptor1"
+#define ERROR_FAILED           ERROR_INTERFACE ".Failed"
 
 #define UUID_GAP       0x1800
 #define UUID_GATT      0x1801
@@ -2429,7 +2430,7 @@ static bool parse_handle(GDBusProxy *proxy, uint16_t *handle)
 }
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-static uint8_t dbus_error_to_att_ecode(const char *error_message)
+static uint8_t dbus_error_to_att_ecode(const char *error_message, uint8_t perm_err)
 {
        uint8_t att_ecode = 0;
        int len;
@@ -2446,28 +2447,31 @@ static uint8_t dbus_error_to_att_ecode(const char *error_message)
        return att_ecode;
 }
 #else
-static uint8_t dbus_error_to_att_ecode(const char *error_name)
+static uint8_t dbus_error_to_att_ecode(const char *error_name, uint8_t perm_err)
 {
 
-       if (strcmp(error_name, "org.bluez.Error.Failed") == 0)
+       if (strcmp(error_name, ERROR_INTERFACE ".Failed") == 0)
                return 0x80;  /* For now return this "application error" */
 
-       if (strcmp(error_name, "org.bluez.Error.NotSupported") == 0)
+       if (strcmp(error_name, ERROR_INTERFACE ".NotSupported") == 0
                return BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
 
-       if (strcmp(error_name, "org.bluez.Error.NotAuthorized") == 0)
+       if (strcmp(error_name, ERROR_INTERFACE ".NotAuthorized") == 0)
                return BT_ATT_ERROR_AUTHORIZATION;
 
-       if (strcmp(error_name, "org.bluez.Error.InvalidValueLength") == 0)
+       if (strcmp(error_name, ERROR_INTERFACE ".InvalidValueLength") == 0)
                return BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
 
-       if (strcmp(error_name, "org.bluez.Error.InvalidOffset") == 0)
+       if (strcmp(error_name, ERROR_INTERFACE ".InvalidOffset") == 0)
                return BT_ATT_ERROR_INVALID_OFFSET;
 
-       if (strcmp(error_name, "org.bluez.Error.InProgress") == 0)
+       if (strcmp(error_name, ERROR_INTERFACE ".InProgress") == 0)
                return BT_ERROR_ALREADY_IN_PROGRESS;
 
-       return 0;
+       if (strcmp(error_name, ERROR_INTERFACE ".NotPermitted") == 0)
+               return perm_err;
+
+       return BT_ATT_ERROR_UNLIKELY;
 }
 #endif
 
@@ -2490,10 +2494,11 @@ static void read_reply_cb(DBusMessage *message, void *user_data)
        if (dbus_set_error_from_message(&err, message) == TRUE) {
                DBG("Failed to read value: %s: %s", err.name, err.message);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-               ecode = dbus_error_to_att_ecode(err.message);
+               ecode = dbus_error_to_att_ecode(err.message,
+                                       BT_ATT_ERROR_WRITE_NOT_PERMITTED);
 #else
-               ecode = dbus_error_to_att_ecode(err.name);
-               ecode = ecode ? ecode : BT_ATT_ERROR_READ_NOT_PERMITTED;
+               ecode = dbus_error_to_att_ecode(err.name,
+                                       BT_ATT_ERROR_WRITE_NOT_PERMITTED);
 #endif
                dbus_error_free(&err);
                goto done;
@@ -2714,10 +2719,11 @@ static void write_reply_cb(DBusMessage *message, void *user_data)
        if (dbus_set_error_from_message(&err, message) == TRUE) {
                DBG("Failed to write value: %s: %s", err.name, err.message);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-               ecode = dbus_error_to_att_ecode(err.message);
+               ecode = dbus_error_to_att_ecode(err.message,
+                                       BT_ATT_ERROR_WRITE_NOT_PERMITTED);
 #else
-               ecode = dbus_error_to_att_ecode(err.name);
-               ecode = ecode ? ecode : BT_ATT_ERROR_WRITE_NOT_PERMITTED;
+               ecode = dbus_error_to_att_ecode(err.name,
+                                       BT_ATT_ERROR_WRITE_NOT_PERMITTED);
 #endif
                dbus_error_free(&err);
                goto done;
@@ -2900,8 +2906,20 @@ static void acquire_write_reply(DBusMessage *message, void *user_data)
        dbus_error_init(&err);
 
        if (dbus_set_error_from_message(&err, message) == TRUE) {
+               uint8_t ecode;
+
                error("Failed to acquire write: %s\n", err.name);
+
+               ecode = dbus_error_to_att_ecode(err.name,
+                                       BT_ATT_ERROR_WRITE_NOT_PERMITTED);
                dbus_error_free(&err);
+
+               if (ecode != BT_ATT_ERROR_UNLIKELY) {
+                       gatt_db_attribute_write_result(op->attrib, op->id,
+                                                               ecode);
+                       return;
+               }
+
                goto retry;
        }
 
@@ -2995,6 +3013,13 @@ static void acquire_notify_reply(DBusMessage *message, void *user_data)
 
        if (dbus_set_error_from_message(&err, message) == TRUE) {
                error("Failed to acquire notify: %s\n", err.name);
+
+               if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY) ||
+                               dbus_error_has_name(&err, ERROR_FAILED)) {
+                       dbus_error_free(&err);
+                       return;
+               }
+
                dbus_error_free(&err);
                goto retry;
        }