Fix to reallocate fd when gatt write fails
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-client.c
index 140cd3a..187e0a4 100644 (file)
 #include "bt-internal-types.h"
 #include "bt-request-sender.h"
 
-#ifdef TIZEN_GATT_CLIENT
 #include "bluetooth-gatt-client-api.h"
 #include <arpa/inet.h>
 static GSList *gatt_characteristic_notify_list;
 static GSList *gatt_characteristic_write_list = NULL;;
-#endif
 
 #define GATT_DEFAULT_TIMEOUT  (6 * 1000) // Dependent on supervision timeout 6 sec
 
@@ -52,14 +50,7 @@ BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_
 {
        BT_CHECK_PARAMETER(svc_pty, return);
 
-#ifdef TIZEN_GATT_CLIENT
-       g_free(svc_pty->uuid);
-#else
        g_free(svc_pty->uuid);
-       g_free(svc_pty->handle);
-       g_strfreev(svc_pty->include_handles.handle);
-       g_strfreev(svc_pty->char_handle.handle);
-#endif
 
        memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
 
@@ -74,10 +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);
-#ifndef TIZEN_GATT_CLIENT
-       g_free(char_pty->handle);
-       g_strfreev(char_pty->char_desc_handle.handle);
-#endif
 
        memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
 
@@ -90,9 +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);
-#ifndef TIZEN_GATT_CLIENT
-       g_free(desc_pty->handle);
-#endif
 
        memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
 
@@ -124,24 +108,16 @@ 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)))
@@ -214,7 +190,7 @@ 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_get_system_private_conn();
+       g_conn = _bt_get_system_common_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
@@ -529,7 +505,7 @@ BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
        BT_CHECK_PARAMETER(service_handle, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_get_system_private_conn();
+       g_conn = _bt_get_system_common_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
@@ -653,7 +629,7 @@ BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
 
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_get_system_private_conn();
+       g_conn = _bt_get_system_common_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
@@ -818,7 +794,7 @@ 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_get_system_private_conn();
+       g_conn = _bt_get_system_common_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
@@ -864,7 +840,7 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
 
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_get_system_private_conn();
+       g_conn = _bt_get_system_common_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
@@ -994,7 +970,7 @@ static void __bluetooth_internal_read_cb(GObject *source_object,
 
        BT_DBG("+");
 
-       system_gconn = _bt_get_system_private_conn();
+       system_gconn = _bt_get_system_common_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1055,7 +1031,7 @@ BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
        BT_CHECK_PARAMETER(chr, return);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
@@ -1092,7 +1068,7 @@ static void __bluetooth_internal_write_cb(GObject *source_object,
        int att_ecode = 0;
        bt_gatt_resp_data_t *resp_data = user_data;
 
-       system_gconn = _bt_get_system_private_conn();
+       system_gconn = _bt_get_system_common_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1134,7 +1110,6 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
        GVariant *val, *options;
        GVariantBuilder *builder1;
        GVariantBuilder *builder2;
-       GError *error = NULL;
        GDBusConnection *conn;
        int i = 0;
        guint16 offset = 0;
@@ -1145,7 +1120,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1178,13 +1153,6 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
                                (GAsyncReadyCallback)__bluetooth_internal_write_cb,
                                NULL);
 
-
-       if (error) {
-               BT_ERR("Set value Failed: %s", error->message);
-               g_clear_error(&error);
-               g_variant_builder_unref(builder1);
-               return BLUETOOTH_ERROR_INTERNAL;
-       }
        g_variant_builder_unref(builder1);
        g_variant_builder_unref(builder2);
 
@@ -1210,7 +1178,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED_INTERNAL(return);
 
-       conn = _bt_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1265,7 +1233,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_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1324,7 +1292,7 @@ static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
        const gchar *key;
        char_descriptor_type_t desc_type = TYPE_NONE;
 
-       g_conn = _bt_get_system_private_conn();
+       g_conn = _bt_get_system_common_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
@@ -1490,7 +1458,7 @@ BT_EXPORT_API int bltooth_gatt_discover_characteristic_descriptor(
        BT_CHECK_PARAMETER(characteristic_handle, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_get_system_private_conn();
+       g_conn = _bt_get_system_common_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
@@ -1531,7 +1499,7 @@ static void __bluetooth_internal_read_desc_cb(GObject *source_object,
 
        BT_DBG("+");
 
-       system_gconn = _bt_get_system_private_conn();
+       system_gconn = _bt_get_system_common_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1595,7 +1563,7 @@ BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
        BT_CHECK_PARAMETER(desc, return);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
@@ -1635,7 +1603,7 @@ static void __bluetooth_internal_write_desc_cb(GObject *source_object,
 
        BT_DBG("+");
 
-       system_gconn = _bt_get_system_private_conn();
+       system_gconn = _bt_get_system_common_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1689,7 +1657,7 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1739,7 +1707,7 @@ BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle,
 
        BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
 
-       conn = _bt_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        g_dbus_connection_call_sync(conn,
@@ -1789,7 +1757,7 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle
 
        BT_INFO("Disable CCCD : %s", char_handle);
 
-       conn = _bt_get_system_private_conn();
+       conn = _bt_get_system_common_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        g_dbus_connection_call_sync(conn,
@@ -1811,7 +1779,6 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle
        return ret;
 }
 
-#ifdef TIZEN_GATT_CLIENT
 void __bt_uuid_hex_to_string(unsigned char *uuid, char *str)
 {
        uint32_t uuid0, uuid4;
@@ -1865,7 +1832,7 @@ static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props, bt_
 
        /* Now fill all the char handles [UUID and Instance ID's]*/
        for (count = 0; count < props->count; count++) {
-               BT_INFO("[%d] %s  instance_id [%d] properties [%d]",
+               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],
@@ -1890,7 +1857,7 @@ static void __bt_fill_desc_handle_informations(bt_descriptor_browse_info_t *prop
 
        /* Now fill all the descriptor handles [UUID and Instance ID's]*/
        for (count = 0; count < props->count; count++) {
-               BT_INFO("[%d] %s  instance_id [%d]",
+               BT_DBG("[%d] %s  instance_id [%d]",
                                count, props->uuids[count], props->inst_id[count]);
 
                g_strlcpy(charc->char_desc_handle.uuids[count],
@@ -2144,6 +2111,18 @@ static gboolean  bluetooth_gatt_client_notify_channel_watch_cb(GIOChannel *gio,
                BT_ERR("chr_info is invalid");
                return FALSE;
        }
+
+       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;
+       }
+
        if (cond & G_IO_IN) {
                GIOStatus status = G_IO_STATUS_NORMAL;
                GError *err = NULL;
@@ -2202,17 +2181,6 @@ static gboolean  bluetooth_gatt_client_notify_channel_watch_cb(GIOChannel *gio,
                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;
 }
 
@@ -2495,7 +2463,9 @@ static gboolean  bluetooth_gatt_client_write_channel_watch_cb(GIOChannel *gio,
                return FALSE;
 
        if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
-               BT_ERR("Error : GIOCondition %d, [%s]", cond, chr_info->UUID);
+               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);
 
@@ -2519,6 +2489,21 @@ static int  bluetooth_gatt_client_write_characteristics_value_to_fd(
        if (written != length) {
                att_result = BLUETOOTH_ERROR_INTERNAL;
                BT_ERR("write data failed.  ret : %d ", written);
+               if (TIZEN_FEATURE_DA_REFERENCE) {
+                       /* If bluetooth_gatt_client_write_channel_watch_cb() is not called
+                        * due to a server issue and write request fails,
+                        * remove the existing fd from the list and reallocate it.*/
+                       GSList *l;
+                       for (l = gatt_characteristic_write_list; l != NULL; l = l->next) {
+                               bt_gatt_characteristic_write_info_t *info = l->data;
+                               if (!info)
+                                       continue;
+                               if (info->write_fd == fd) {
+                                       gatt_characteristic_write_list = g_slist_remove(gatt_characteristic_write_list, info);
+                                       break;
+                               }
+                       }
+               }
        }
 
        return att_result;
@@ -2797,8 +2782,6 @@ BT_EXPORT_API int bluetooth_gatt_client_deinit(
 
        if (result != BLUETOOTH_ERROR_NONE)
                BT_ERR("GATT Client Unregistration failed result [%d]", result);
-       else
-               BT_INFO("GATT Client Unregistration successful");
 
        /* Unregister event handler if this is the only instance */
        event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
@@ -2806,7 +2789,7 @@ BT_EXPORT_API int bluetooth_gatt_client_deinit(
        if (event_info) {
                count = (int*)event_info->user_data;
 
-               BT_INFO("Total num of GATT client instances [%d]", *count);
+               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");
@@ -2821,4 +2804,58 @@ BT_EXPORT_API int bluetooth_gatt_client_deinit(
        return result;
 }
 
-#endif
+BT_EXPORT_API int bluetooth_gatt_client_read_phy(const bluetooth_device_address_t *device_address)
+{
+       int result;
+
+       BT_CHECK_PARAMETER(device_address, 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, device_address, sizeof(bluetooth_device_address_t));
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_READ_PHY,
+               in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (result != BLUETOOTH_ERROR_NONE)
+               BT_INFO("GATT Client Read PHY failed result [%d]", result);
+       else
+               BT_INFO("GATT Client Read PHY successful");
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_gatt_client_set_phy(const bluetooth_device_address_t *device_address,
+                               int tx_phy, int rx_phy, int phy_options)
+{
+       int result;
+
+       BT_CHECK_PARAMETER(device_address, return);
+       BT_CHECK_ENABLED(return);
+
+       BT_INFO("Set PHY: Tx[%d], Rx[%d], Phy_options[%d]", tx_phy, rx_phy, phy_options);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, device_address, sizeof(bluetooth_device_address_t));
+       g_array_append_vals(in_param2, &tx_phy, sizeof(int));
+       g_array_append_vals(in_param3, &rx_phy, sizeof(int));
+       g_array_append_vals(in_param4, &phy_options, sizeof(int));
+
+       result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_SET_PHY,
+               in_param1, in_param2, in_param3, in_param4, &out_param);
+
+       if (result != BLUETOOTH_ERROR_NONE)
+               BT_INFO("GATT Client Set PHY failed result [%d]", result);
+       else
+               BT_INFO("GATT Client Set PHY successful");
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
+}