Fix : Simultaneous GATT client requests are failed 90/127190/2
authorSeungyoun Ju <sy39.ju@samsung.com>
Thu, 20 Apr 2017 12:36:37 +0000 (21:36 +0900)
committerSeungyoun Ju <sy39.ju@samsung.com>
Wed, 26 Apr 2017 11:00:33 +0000 (20:00 +0900)
[Model] COMMON
[BinType] AP
[Customer] OPEN

[Issue#] N/A
[Request] Internal
[Occurrence Version] N/A

[Problem] Actually read / write request for each other characteritsics and
 descriptors should be allowed. But current implementation doesn't consider
 that. So in progress error comes in that situation.
[Cause & Measure] There was only one callback for GATT client request.
 So once it is used by other request, new ones are failed until old one
 is completed.
 This patch makes each request's callback data be passed to dbus.
 So, once remote device's response comes and dbus call is returned,
 each callback data will be passed to above layer.
[Checking Method] Request GATT operation as client role using several
 characteristics and descriptors before one of them is responded.

[Team] Basic connection
[Developer] Seungyoun Ju
[Solution company] Samsung
[Change Type] Specification change

Change-Id: I74eee1ad62df648fe36e805d06570327e5f2c1f8

bt-api/bt-gatt-client.c
include/bluetooth-api.h

index 5d3abdc..ad01365 100644 (file)
@@ -873,43 +873,50 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
 }
 
 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;
+       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) {
+               g_free(resp_data);
+               if (error) {
+                       BT_ERR("Error : %s", error->message);
+                       g_clear_error(&error);
+                       return;
+               }
+               g_variant_unref(value);
+               return;
+       }
+
        if (error) {
-               BT_ERR("Error : %s \n", error->message);
+               BT_ERR("Error : %s", error->message);
                if (g_strrstr(error->message, "Not paired"))
                        ret = BLUETOOTH_ERROR_NOT_PAIRED;
                else
                        ret = BLUETOOTH_ERROR_INTERNAL;
-
                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,
+                                   ret, 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,49 +924,42 @@ 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_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;
 
-       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;
 
-       g_dbus_connection_call(conn,
-                       BT_BLUEZ_NAME,
-                       characteristic,
-                       GATT_CHAR_INTERFACE,
-                       "ReadValue",
-                       NULL,
-                       G_VARIANT_TYPE("(ay)"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
+                       "ReadValue", NULL, G_VARIANT_TYPE("(ay)"),
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
                        (GAsyncReadyCallback)__bluetooth_internal_read_cb,
-                       (gpointer)handle);
+                       (gpointer)resp_data);
 
        return BLUETOOTH_ERROR_NONE;
 }
@@ -1013,57 +1013,68 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
 }
 
 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 result = BLUETOOTH_ERROR_NONE;
        guint8 att_ecode = 0;
-
-       user_info = _bt_get_user_data(BT_COMMON);
+       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);
 
-       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) {
+               g_free(resp_data);
+               if (error) {
+                       BT_ERR("Error : %s", error->message);
+                       g_clear_error(&error);
+                       return;
                }
+               g_variant_unref(value);
+               return;
        }
 
-       if (user_info) {
+       if (error) {
+               BT_ERR("Error : %s", error->message);
+               g_clear_error(&error);
+
                _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
-                               result, NULL,
+                               BLUETOOTH_ERROR_INTERNAL, 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);
+       g_variant_get(value, "(y)", &att_ecode);
+       if (att_ecode) {
+               BT_ERR("ATT Error code: %d", att_ecode);
+               result = att_ecode;
+       }
 
+       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
+                       result, 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_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;
        GVariantBuilder *builder;
        GDBusConnection *conn;
        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);
@@ -1072,25 +1083,24 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
-
        for (i = 0; i < length; i++)
                g_variant_builder_add(builder, "y", value[i]);
-
        val = g_variant_new("ay", builder);
-       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;
+
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
                        "WriteValuebyType",
                        g_variant_new("(y@ay)", write_type, val),
                        G_VARIANT_TYPE("(y)"),
-                       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(builder);
-       return ret;
+
+       return BLUETOOTH_ERROR_NONE;
 }
 
 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
@@ -1348,30 +1358,39 @@ 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;
+       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);
 
+       user_info = _bt_get_user_data(BT_COMMON);
+       if (!user_info) {
+               g_free(resp_data);
+               if (error) {
+                       BT_ERR("Error : %s", error->message);
+                       g_clear_error(&error);
+                       return;
+               }
+               g_variant_unref(value);
+               return;
+       }
+
        if (error) {
-               BT_ERR("Error : %s \n", error->message);
+               BT_ERR("Error : %s", error->message);
                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,
+                               BLUETOOTH_ERROR_INTERNAL, resp_data,
+                               user_info->cb, user_info->user_data);
+               g_free(resp_data);
                return;
        }
 
@@ -1382,58 +1401,52 @@ static void __bluetooth_internal_read_desc_cb(GObject *source_object,
                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_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;
-       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;
 
-       g_dbus_connection_call(conn,
-                       BT_BLUEZ_NAME,
-                       char_descriptor,
-                       GATT_DESC_INTERFACE,
-                       "ReadValue",
-                       NULL,
-                       G_VARIANT_TYPE("(ay)"),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
+                       "ReadValue", NULL, G_VARIANT_TYPE("(ay)"),
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
                        (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
-                       (gpointer)handle);
+                       (gpointer)resp_data);
 
        BT_DBG("-");
        return BLUETOOTH_ERROR_NONE;
 }
 
 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;
@@ -1441,47 +1454,61 @@ static void __bluetooth_internal_write_desc_cb(GObject *source_object,
        GVariant *value;
        int result = BLUETOOTH_ERROR_NONE;
        guint8 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);
 
-       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) {
+               g_free(resp_data);
+               if (error) {
+                       BT_ERR("Error : %s", error->message);
+                       g_clear_error(&error);
+                       return;
                }
+               g_variant_unref(value);
+               return;
        }
 
-       if (user_info) {
+       if (error) {
+               BT_ERR("Error : %s", error->message);
+               g_clear_error(&error);
+
                _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
-                               result, NULL,
+                               BLUETOOTH_ERROR_INTERNAL, resp_data,
                                user_info->cb, user_info->user_data);
+               g_free(resp_data);
        }
 
-       if (value)
-               g_variant_unref(value);
+       g_variant_get(value, "(y)", &att_ecode);
+       if (att_ecode) {
+               BT_ERR("ATT Error code: %d", att_ecode);
+               result = att_ecode;
+       }
 
+       _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC, result, 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;
        GDBusConnection *conn;
        GVariantBuilder *builder;
        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);
@@ -1490,24 +1517,18 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
-
        for (i = 0; i < length; i++)
                g_variant_builder_add(builder, "y", value[i]);
-
        val = g_variant_new("(ay)", builder);
 
-       g_dbus_connection_call(conn,
-                               BT_BLUEZ_NAME,
-                               desc_handle,
-                               GATT_DESC_INTERFACE,
-                               "WriteValue",
-                               val,
-                               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;
 
+       g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
+                       "WriteValue", val, G_VARIANT_TYPE("(y)"),
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+                       (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
+                       (gpointer)resp_data);
        g_variant_builder_unref(builder);
 
        BT_DBG("-");
index 1dac034..3955cfc 100644 (file)
@@ -1554,6 +1554,15 @@ typedef struct {
 } bt_gatt_indicate_confirm_t;
 
 /**
+ * Structure for GATT response data
+ */
+typedef struct {
+       guint8 *value;
+       guint32 len;
+       gpointer user_data;
+} bt_gatt_resp_data_t;
+
+/**
  * Structure to RSSI Signal Strength Alert
  */
 
@@ -5328,7 +5337,8 @@ int bluetooth_gatt_set_characteristics_value(const char *char_handle,
  * @see                None
  */
 int bluetooth_gatt_set_characteristics_value_by_type(const char *char_handle,
-                               const guint8 *value, int length, guint8 write_type);
+                                       const guint8 *value, int length,
+                                       guint8 write_type, gpointer app_data);
 
 
 /**
@@ -5373,7 +5383,7 @@ int bluetooth_gatt_set_characteristics_value_request(const char *char_handle,
  * @remark     None
  * @see        None
  */
-int bluetooth_gatt_read_characteristic_value(const char *char_handle);
+int bluetooth_gatt_read_characteristic_value(const char *char_handle, gpointer app_data);
 
 /**
  * @fn int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
@@ -5540,7 +5550,7 @@ int bluetooth_gatt_discover_characteristic_descriptor(const char *characteristic
  * @remark     None
  * @see        None
  */
-int bluetooth_gatt_read_descriptor_value(const char *desc_handle);
+int bluetooth_gatt_read_descriptor_value(const char *desc_handle, gpointer app_data);
 
 /**
  * @fn int bluetooth_gatt_write_descriptor_value(const char *desc_handle,
@@ -5564,7 +5574,7 @@ int bluetooth_gatt_read_descriptor_value(const char *desc_handle);
  * @see        None
  */
 int bluetooth_gatt_write_descriptor_value(const char *desc_handle,
-                       const guint8 *value, int length);
+                       const guint8 *value, int length, gpointer app_data);
 
 /* @fn int bluetooth_gatt_init(void)
 *