Reduce the predefined logic (PredefinedPreprocessor)
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-client.c
old mode 100755 (executable)
new mode 100644 (file)
index 9daa2eb..539f543
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdint.h>
+#include <gio/gunixfdlist.h>
 
 #include "bt-common.h"
 #include "bt-event-handler.h"
 #include "bt-internal-types.h"
 #include "bt-request-sender.h"
 
-#ifdef TIZEN_GATT_CLIENT
 #include "bluetooth-gatt-client-api.h"
 #include <arpa/inet.h>
-#endif
+static GSList *gatt_characteristic_notify_list;
+static GSList *gatt_characteristic_write_list = NULL;;
 
 #define GATT_DEFAULT_TIMEOUT  (6 * 1000) // Dependent on supervision timeout 6 sec
 
@@ -47,61 +48,38 @@ static GSList *service_monitor_list = NULL;
 
 BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_t *svc_pty)
 {
-       BT_DBG("+");
-
        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));
 
-       BT_DBG("-");
        return BLUETOOTH_ERROR_NONE;
 }
 
 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
 {
-       BT_DBG("+");
-
        BT_CHECK_PARAMETER(char_pty, return);
 
        g_free(char_pty->uuid);
        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));
 
-       BT_DBG("-");
        return BLUETOOTH_ERROR_NONE;
 }
 
 BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_property_t *desc_pty)
 {
-       BT_DBG("+");
-
        BT_CHECK_PARAMETER(desc_pty, return);
 
        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));
 
-       BT_DBG("-");
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -130,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)))
@@ -220,11 +190,11 @@ 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_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        service_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -436,6 +406,13 @@ BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_
                                                g_strstr_len(service->uuid, -1,
                                                                service_uuid)) {
                                        ret = BLUETOOTH_ERROR_NONE;
+
+                                       /* release resources */
+                                       g_free(object_path);
+                                       g_variant_iter_free(interface_iter);
+                                       g_free(interface_str);
+                                       g_variant_iter_free(svc_iter);
+
                                        goto done;
                                }
                        }
@@ -512,6 +489,7 @@ static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
        g_variant_iter_free(char_iter);
        g_variant_unref(value);
        g_object_unref(proxy);
+       g_variant_unref(char_value);
 }
 
 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
@@ -527,11 +505,11 @@ BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
        BT_CHECK_PARAMETER(service_handle, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        service_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -651,11 +629,11 @@ BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
 
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        char_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -816,11 +794,11 @@ 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_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        service_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -862,11 +840,11 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
 
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        descriptor_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -992,7 +970,7 @@ static void __bluetooth_internal_read_cb(GObject *source_object,
 
        BT_DBG("+");
 
-       system_gconn = _bt_gdbus_get_system_gconn();
+       system_gconn = _bt_get_system_private_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1053,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_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
@@ -1090,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_gdbus_get_system_gconn();
+       system_gconn = _bt_get_system_private_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1143,7 +1121,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
        retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1208,7 +1186,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_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1263,7 +1241,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_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1322,11 +1300,11 @@ static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
        const gchar *key;
        char_descriptor_type_t desc_type = TYPE_NONE;
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        char_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -1473,10 +1451,11 @@ static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
 
        g_variant_iter_free(char_iter);
        g_variant_unref(value);
+       g_variant_unref(char_value);
        BT_DBG("-");
 }
 
-BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
+BT_EXPORT_API int bltooth_gatt_discover_characteristic_descriptor(
                        const char *characteristic_handle)
 {
        GDBusProxy *properties_proxy = NULL;
@@ -1487,11 +1466,11 @@ BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
        BT_CHECK_PARAMETER(characteristic_handle, return);
        BT_CHECK_ENABLED(return);
 
-       g_conn = _bt_gdbus_get_system_gconn();
+       g_conn = _bt_get_system_private_conn();
        retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        properties_proxy = g_dbus_proxy_new_sync(g_conn,
-                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
                        BT_BLUEZ_NAME,
                        characteristic_handle,
                        BT_PROPERTIES_INTERFACE,
@@ -1528,7 +1507,7 @@ static void __bluetooth_internal_read_desc_cb(GObject *source_object,
 
        BT_DBG("+");
 
-       system_gconn = _bt_gdbus_get_system_gconn();
+       system_gconn = _bt_get_system_private_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1592,7 +1571,7 @@ BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
        BT_CHECK_PARAMETER(desc, return);
        BT_CHECK_ENABLED(return);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
@@ -1632,7 +1611,7 @@ static void __bluetooth_internal_write_desc_cb(GObject *source_object,
 
        BT_DBG("+");
 
-       system_gconn = _bt_gdbus_get_system_gconn();
+       system_gconn = _bt_get_system_private_conn();
        value = g_dbus_connection_call_finish(system_gconn, res, &error);
 
        user_info = _bt_get_user_data(BT_COMMON);
@@ -1686,7 +1665,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_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
@@ -1736,7 +1715,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_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        g_dbus_connection_call_sync(conn,
@@ -1786,7 +1765,7 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle
 
        BT_INFO("Disable CCCD : %s", char_handle);
 
-       conn = _bt_gdbus_get_system_gconn();
+       conn = _bt_get_system_private_conn();
        retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
 
        g_dbus_connection_call_sync(conn,
@@ -1808,7 +1787,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;
@@ -1833,7 +1811,6 @@ static void __bt_fill_service_handle_informations(bt_services_browse_info_t *pro
                bt_gatt_handle_info_t *svcs)
 {
        int count;
-       BT_INFO("Total services found [%d]", props->count);
 
        if (props->count == 0)
                return;
@@ -1841,7 +1818,7 @@ static void __bt_fill_service_handle_informations(bt_services_browse_info_t *pro
        svcs->count = props->count;
 
        for (count = 0; count < props->count; count++) {
-               BT_INFO("UUID[%d] = [%s] instance_id [%d] Is Primary [%d]",
+               BT_DBG("[%d] %s  instance_id [%d] Is Primary [%d]",
                                count, props->uuids[count], props->inst_id[count], props->primary[count]);
                g_strlcpy(svcs->uuids[count], props->uuids[count],
                                BLUETOOTH_UUID_STRING_MAX);
@@ -1849,13 +1826,10 @@ static void __bt_fill_service_handle_informations(bt_services_browse_info_t *pro
        }
 }
 
-static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props,
-               bt_gatt_service_property_t *service)
+static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props, bt_gatt_service_property_t *service)
 {
        int count;
        char uuid_string[BLUETOOTH_UUID_STRING_MAX];
-       BT_INFO("Total number of characteristics found [%d]",
-                       props->count);
 
        service->char_handle.count = props->count;
 
@@ -1866,7 +1840,7 @@ static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props,
 
        /* Now fill all the char handles [UUID and Instance ID's]*/
        for (count = 0; count < props->count; count++) {
-               BT_INFO("UUID[%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],
@@ -1882,7 +1856,6 @@ static void __bt_fill_desc_handle_informations(bt_descriptor_browse_info_t *prop
 {
        int count;
        char uuid_string[BLUETOOTH_UUID_STRING_MAX];
-       BT_INFO("Total descriptor count found [%d]", props->count);
 
        charc->char_desc_handle.count = props->count;
 
@@ -1892,7 +1865,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("UUID[%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],
@@ -1902,7 +1875,7 @@ static void __bt_fill_desc_handle_informations(bt_descriptor_browse_info_t *prop
                charc->char_desc_handle.inst_id[count] = props->inst_id[count];
        }
        charc->permission = props->char_props_map;
-       BT_INFO("Characteritic property map val [%d]", charc->permission);
+       __convert_permission_flag_to_str(charc->permission);
 }
 
 
@@ -1919,8 +1892,6 @@ BT_EXPORT_API int bluetooth_gatt_client_init(
        BT_CHECK_PARAMETER(callback_ptr, return);
        BT_CHECK_ENABLED(return);
 
-       BT_INFO("+");
-
        BT_INIT_PARAMS();
        BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
 
@@ -1974,8 +1945,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_primary_services(
        int result = BLUETOOTH_ERROR_NONE;
        bt_services_browse_info_t service_props;
 
-       BT_DBG("+");
-
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(prim_svc, return);
        BT_CHECK_ENABLED(return);
@@ -2001,7 +1970,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_primary_services(
 
 done:
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
-       BT_DBG("result = %d", result);
        return result;
 }
 
@@ -2013,7 +1981,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_service_property(
        int result = BLUETOOTH_ERROR_NONE;
        bluetooth_gatt_client_svc_prop_info_t svc_prop;
        bt_char_browse_info_t char_handles_info;
-       BT_INFO("Remote Address [%s]", address);
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
@@ -2050,7 +2017,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_service_property(
 
 done:
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
-       BT_INFO("result = %d", result);
        return result;
 }
 
@@ -2063,7 +2029,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_characteristics_property(
        int result = BLUETOOTH_ERROR_NONE;
        bt_descriptor_browse_info_t desc_handles_info;
        bluetooth_gatt_client_char_prop_info_t char_prop;
-       BT_INFO("Get Properties of characteristics from remote device [%s]", address);
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
@@ -2091,7 +2056,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_characteristics_property(
                        BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
                        in_param1, in_param2, in_param3, in_param4, &out_param);
 
-       BT_INFO("result = [%d]", result);
        if (BLUETOOTH_ERROR_NONE != result)
                goto done;
 
@@ -2106,7 +2070,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_characteristics_property(
 
 done:
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
-       BT_INFO("result = %d", result);
        return result;
        /* Call to bt-service (sync) and send address, service_handle & char_handle infos */
 
@@ -2126,7 +2089,6 @@ BT_EXPORT_API int bluetooth_gatt_client_get_char_descriptor_property(
                bt_gatt_char_descriptor_property_t *desc_prop)
 {
        char uuid_string[BLUETOOTH_UUID_STRING_MAX];
-       BT_DBG("Remote Address [%s]", address);
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
@@ -2147,27 +2109,172 @@ BT_EXPORT_API int bluetooth_gatt_client_get_char_descriptor_property(
                as an asyn function and leave every thing else in the callback */
 }
 
+
+static gboolean  bluetooth_gatt_client_notify_channel_watch_cb(GIOChannel *gio,
+                                       GIOCondition cond, gpointer data)
+{
+       bt_gatt_characteristic_notify_info_t *chr_info = (bt_gatt_characteristic_notify_info_t *)data;
+
+       if (!chr_info) {
+               BT_ERR("chr_info is invalid");
+               return FALSE;
+       }
+       if (cond & G_IO_IN) {
+               GIOStatus status = G_IO_STATUS_NORMAL;
+               GError *err = NULL;
+               char *buffer = NULL;
+               gsize len = 0;
+               bt_event_info_t *event_info;
+
+               buffer = g_malloc0(chr_info->mtu + 1);
+               memset(buffer, 0, chr_info->mtu + 1);
+
+               status = g_io_channel_read_chars(gio, buffer,
+                               chr_info->mtu, &len, &err);
+               if (status != G_IO_STATUS_NORMAL) {
+                       BT_ERR("IO Channel read is failed with %d", status);
+                       g_free(buffer);
+                       if (err) {
+                               BT_ERR("IO Channel read error [%s]", err->message);
+                               if (status == G_IO_STATUS_ERROR) {
+                                       BT_ERR("cond : %d", cond);
+                                       g_error_free(err);
+                                       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;
+                               }
+                               g_error_free(err);
+                       }
+                       return FALSE;
+               }
+
+               if (len > 0 && len < chr_info->mtu) {
+                       bt_gatt_char_property_t char_val;
+//                      BT_DBG("FD io sending  value changed  %x %x %x %x %x %x %x %zd \n", buffer[0], buffer[1], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], len);
+
+                       memcpy(char_val.prop.uuid, chr_info->UUID, 16);
+                       memcpy(char_val.value, buffer, len);
+                       char_val.val_len = len;
+                       memcpy(char_val.address, chr_info->address, 18);
+
+                       event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
+                       if (event_info) {
+                               _bt_common_event_cb(BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
+                                                       BLUETOOTH_ERROR_NONE, &char_val,
+                                                       event_info->cb, event_info->user_data);
+                       } else {
+                               BT_ERR("event_info failed");
+                       }
+
+               } else
+                       BT_ERR("Packet corrupted");
+
+               g_free(buffer);
+
+               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;
+}
+
+#ifndef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
+static bt_gatt_characteristic_notify_info_t * bluetooth_gatt_client_get_characteristic_notify_info(unsigned  char *handle , int id)
+{
+       GSList *l;
+
+       for (l = gatt_characteristic_notify_list; l != NULL; l = l->next) {
+               bt_gatt_characteristic_notify_info_t *info = l->data;
+               if (memcmp(info->UUID, handle, 16) == 0 && info->id == id)
+                       return info;
+       }
+       return NULL;
+}
+#endif
+
+static bt_gatt_characteristic_notify_info_t *  bluetooth_gatt_client_create_watch_io(int fd, int id, int mtu, char * address, unsigned char *uuid)
+{
+       GIOChannel *channel;
+       bt_gatt_characteristic_notify_info_t *chr_info;
+
+       chr_info = g_malloc0(sizeof(bt_gatt_characteristic_notify_info_t));
+       chr_info->notify_fd = fd;
+       chr_info->id = id;
+       chr_info->mtu = mtu;
+       g_strlcpy(chr_info->address, address, 18);
+       memcpy(chr_info->UUID, uuid, 16);
+
+       channel = g_io_channel_unix_new(fd);
+
+       chr_info->io_channel = channel;
+
+       g_io_channel_set_encoding(channel, NULL, NULL);
+       g_io_channel_set_buffered(channel, FALSE);
+       g_io_channel_set_close_on_unref(channel, TRUE);
+       g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+
+       chr_info->watch_id = g_io_add_watch(channel, (G_IO_IN | G_IO_ERR | G_IO_HUP),
+                        bluetooth_gatt_client_notify_channel_watch_cb, chr_info);
+
+       return chr_info;
+
+}
+
 BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
                        const char *address,
                        bt_gatt_handle_property_t *service_handle,
                        bt_gatt_handle_property_t *char_handle,
                        int client_id,
-                       gboolean is_notify)
+                       gboolean is_notify,
+                       gboolean is_indicate)
 {
        int result = BLUETOOTH_ERROR_NONE;
        bluetooth_gatt_client_char_prop_info_t param;
-       BT_DBG("+");
+       bt_gatt_characteristic_notify_info_t *chr_info;
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
        BT_CHECK_PARAMETER(char_handle, return);
 
+#ifndef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
+       chr_info = bluetooth_gatt_client_get_characteristic_notify_info(char_handle->uuid , char_handle->instance_id);
+       if (chr_info && !is_notify) {
+               BT_INFO("Already CCCD enabled. fd %d", chr_info->notify_fd);
+
+               if (chr_info->watch_id > 0)
+                       g_source_remove(chr_info->watch_id);
+
+               if (chr_info->io_channel) {
+                       g_io_channel_shutdown(chr_info->io_channel, TRUE, NULL);
+                       g_io_channel_unref(chr_info->io_channel);
+               }
+
+               gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
+
+               g_free(chr_info);
+
+               return result;
+       }
+#endif
+
        /* ASync Function, result expected in callback from bt-service */
 
        BT_INIT_PARAMS();
        BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
 
-       BT_INFO("Address [%s]", address);
        memset(&param, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
 
        memcpy(&param.svc.uuid, service_handle->uuid, 16);
@@ -2181,7 +2288,9 @@ BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
        g_array_append_vals(in_param1, &param, sizeof(bluetooth_gatt_client_char_prop_info_t));
        g_array_append_vals(in_param2, &client_id, sizeof(int));
        g_array_append_vals(in_param3, &is_notify, sizeof(gboolean));
+       g_array_append_vals(in_param4, &is_indicate, sizeof(gboolean));
 
+#ifdef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
        result = _bt_send_request(BT_BLUEZ_SERVICE,
                        BT_GATT_WATCH_CHARACTERISTIC,
                        in_param1, in_param2, in_param3, in_param4, &out_param);
@@ -2190,6 +2299,60 @@ BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
 
        BT_INFO("Result [%d]", result);
        return result;
+#endif
+
+       GUnixFDList *out_fd_list = NULL;
+       char *svc_name = NULL;
+       char  str_uuid[37];
+
+       _bt_convert_uuid_type_to_string(str_uuid, param.svc.uuid);
+       bluetooth_get_uuid_name(str_uuid, &svc_name);
+
+       _bt_convert_uuid_type_to_string(str_uuid, param.characteristic.uuid);
+
+       BT_INFO_C("### Request subscription Notify : %s [%s]", str_uuid, svc_name);
+       g_free(svc_name);
+
+       result  = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_WATCH_CHARACTERISTIC,
+                                                       in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
+       if (result != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("Fail to get Nofify FD. result %d", result);
+               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+               return result;
+       }
+
+       if (is_indicate == false) {
+               if (NULL == out_fd_list) {
+                       BT_ERR("out_fd_list is NULL");
+                       result = BLUETOOTH_ERROR_INTERNAL;
+               } else {
+                       int *fd_list_array;
+                       int len = 0;
+                       int mtu;
+                       int fd = -1;
+
+                       fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
+                       BT_DBG("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
+                       fd = fd_list_array[0];
+                       mtu =  g_array_index(out_param, int, 0);
+
+                       BT_INFO("Acquired characteristic Notify FD %d, mtu %d", fd, mtu);
+                       chr_info = bluetooth_gatt_client_create_watch_io(fd, char_handle->instance_id, mtu, (char *)address, char_handle->uuid);
+
+                       gatt_characteristic_notify_list = g_slist_append(gatt_characteristic_notify_list, chr_info);
+
+                       g_free(fd_list_array);
+                       g_object_unref(out_fd_list);
+               }
+       }
+
+       /*result = _bt_send_request(BT_BLUEZ_SERVICE,
+                       BT_GATT_WATCH_CHARACTERISTIC,
+                       in_param1, in_param2, in_param3, in_param4, &out_param);*/
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
 }
 
 BT_EXPORT_API int bluetooth_gatt_client_read_characteristic_value(
@@ -2200,7 +2363,6 @@ BT_EXPORT_API int bluetooth_gatt_client_read_characteristic_value(
        int result = BLUETOOTH_ERROR_NONE;
        bt_user_info_t *user_info;
        bluetooth_gatt_client_char_prop_info_t param;
-       BT_DBG("+");
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
@@ -2227,13 +2389,10 @@ BT_EXPORT_API int bluetooth_gatt_client_read_characteristic_value(
        g_array_append_vals(in_param1, &param,
                        sizeof(bluetooth_gatt_client_char_prop_info_t));
 
-
        result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_CHARACTERISTIC,
                        in_param1, in_param2, in_param3, in_param4,
                        user_info->cb, user_info->user_data);
 
-
-       BT_INFO("result = [%d]", result);
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
        return result;
 }
@@ -2247,7 +2406,6 @@ BT_EXPORT_API int bluetooth_gatt_client_read_descriptor_value(
        int result = BLUETOOTH_ERROR_NONE;
        bt_user_info_t *user_info;
        bluetooth_gatt_client_desc_prop_info_t param;
-       BT_DBG("+");
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
@@ -2277,16 +2435,95 @@ BT_EXPORT_API int bluetooth_gatt_client_read_descriptor_value(
        g_array_append_vals(in_param1, &param,
                        sizeof(bluetooth_gatt_client_desc_prop_info_t));
 
-
        result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_DESCRIPTOR_VALUE,
                        in_param1, in_param2, in_param3, in_param4,
                        user_info->cb, user_info->user_data);
 
-       BT_INFO("result = [%d]", result);
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
        return result;
 }
 
+
+static bt_gatt_characteristic_write_info_t *  bluetooth_gatt_client_get_characteristic_fd(unsigned  char *handle, int id)
+{
+       GSList *l;
+       char  str[37];
+
+       for (l = gatt_characteristic_write_list; l != NULL; l = l->next) {
+               bt_gatt_characteristic_write_info_t *info = l->data;
+
+               if (memcmp(info->UUID, handle, 16) ==  0 &&  info->id == id)
+                       return info;
+       }
+
+       _bt_convert_uuid_type_to_string(str, handle);
+       BT_ERR("Unable to get characteristic fd. [%s] id [ %d]", str, id);
+       return NULL;
+}
+
+static gboolean  bluetooth_gatt_client_write_channel_watch_cb(GIOChannel *gio,
+                                       GIOCondition cond, gpointer data)
+{
+       bt_gatt_characteristic_write_info_t *chr_info = (bt_gatt_characteristic_write_info_t *)data;
+
+       if (!chr_info)
+               return FALSE;
+
+       if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+               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);
+
+               gatt_characteristic_write_list = g_slist_remove(gatt_characteristic_write_list, chr_info);
+               g_free(chr_info);
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static int  bluetooth_gatt_client_write_characteristics_value_to_fd(
+                        int fd, const guint8 *value, int length, int mtu,
+                       gpointer user_data)
+{
+       int written;
+       int att_result = BLUETOOTH_ERROR_NONE;
+       BT_CHECK_PARAMETER(value, return);
+       written = write(fd, value, length);
+       if (written != length) {
+               att_result = BLUETOOTH_ERROR_INTERNAL;
+               BT_ERR("write data failed.  ret : %d ", written);
+       }
+
+       return att_result;
+}
+
+static void  bluetooth_gatt_client_create_write_io_channel(int fd, unsigned char * uuid, int id, int mtu)
+{
+       bt_gatt_characteristic_write_info_t *chr_info;
+       GIOChannel *channel;
+
+       chr_info = g_malloc0(sizeof(bt_gatt_characteristic_write_info_t));
+       chr_info->write_fd = fd;
+       chr_info->id = id;
+       chr_info->mtu = mtu;
+
+       memcpy(chr_info->UUID, uuid, 16);
+       channel = g_io_channel_unix_new(fd);
+       g_io_channel_set_encoding(channel, NULL, NULL);
+       g_io_channel_set_buffered(channel, FALSE);
+       g_io_channel_set_close_on_unref(channel, TRUE);
+       g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_add_watch(channel, (G_IO_ERR | G_IO_HUP | G_IO_NVAL),
+                        bluetooth_gatt_client_write_channel_watch_cb, chr_info);
+
+       gatt_characteristic_write_list = g_slist_append(gatt_characteristic_write_list, chr_info);
+
+}
+
 BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
                const char *address,
                bt_gatt_handle_property_t *service_handle,
@@ -2297,7 +2534,6 @@ BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
        int result = BLUETOOTH_ERROR_NONE;
        bt_user_info_t *user_info;
        bluetooth_gatt_client_char_prop_info_t param;
-       BT_DBG("+");
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
@@ -2325,10 +2561,71 @@ BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
        g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
        g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
 
-       result = _bt_send_request_async(BT_BLUEZ_SERVICE,
+#ifdef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
+       goto done;
+#endif
+
+       if (write_type == BLUETOOTH_GATT_TYPE_WRITE_NO_RESPONSE) {
+               int fd = -1;
+               int mtu = 0;
+               bt_gatt_characteristic_write_info_t *info;
+               info =  bluetooth_gatt_client_get_characteristic_fd(char_handle->uuid, service_handle->instance_id);
+
+               if (info) {
+                       fd = info->write_fd;
+                       mtu = info->mtu;
+               }
+
+               if (fd < 0) {
+
+                       GUnixFDList *out_fd_list = NULL;
+
+                       result  = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_ACQUIRE_WRITE,
+                                       in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
+
+                       mtu =  g_array_index(out_param, int, 0);
+
+                       if (result != BLUETOOTH_ERROR_NONE) {
+                               BT_ERR("Fail to get Write FD. result %d", result);
+                               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+                               return result;
+                       } else if (NULL == out_fd_list) {
+                               BT_ERR("out_fd_list is NULL");
+                               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       } else {
+                               int *fd_list_array;
+                               int len = 0;
+
+                               fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
+                               fd = fd_list_array[0];
+
+                               g_free(fd_list_array);
+                               g_object_unref(out_fd_list);
+                       }
+                       BT_INFO("Acquired characteristic Write FD %d, mtu %d", fd, mtu);
+
+                       if (fd > -1) {
+                               bluetooth_gatt_client_create_write_io_channel(fd, char_handle->uuid, service_handle->instance_id, mtu);
+
+                               result =  bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
+
+                       } else {
+                               BT_ERR("characteristic info  FD is invalid");
+                               goto done;
+                       }
+
+               } else {
+                       result =  bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
+               }
+
+       } else {
+done:
+               result = _bt_send_request_async(BT_BLUEZ_SERVICE,
                        BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
                        in_param1, in_param2, in_param3, in_param4,
                        user_info->cb, user_info->user_data);
+       }
 
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
 
@@ -2346,7 +2643,6 @@ BT_EXPORT_API int bluetooth_gatt_client_write_descriptor_value(
        int result = BLUETOOTH_ERROR_NONE;
        bt_user_info_t *user_info;
        bluetooth_gatt_client_desc_prop_info_t param;
-       BT_DBG("+");
 
        BT_CHECK_PARAMETER(address, return);
        BT_CHECK_PARAMETER(service_handle, return);
@@ -2393,26 +2689,25 @@ BT_EXPORT_API int bluetooth_gatt_client_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 };
        int result = BLUETOOTH_ERROR_NONE;
 
-       BT_INFO("+");
-
        BT_INIT_PARAMS();
        BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
 
        g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
        g_array_append_vals(in_param2, &enable, sizeof(gboolean));
 
-
-       _bt_convert_addr_string_to_secure_string(secure_address, (const char *)address->addr);
-       BT_INFO("Set watcher for %s with %d", secure_address, enable);
+       _bt_convert_addr_type_to_string(device_address, (unsigned char *)address->addr);
+       _bt_convert_addr_string_to_secure_string(secure_address, device_address);
+       BT_INFO("%s watcher for [%s]", enable ? "Set":"Unset", secure_address);
 
        if (enable == TRUE) {
                if (_bluetooth_gatt_check_service_change_watcher_address(address)
                                == TRUE) {
                        BT_INFO("The watcher is already set");
-                       return BLUETOOTH_ERROR_NONE;
+                       goto done;
                }
 
                if (service_monitor_list == NULL) {
@@ -2452,6 +2747,7 @@ BT_EXPORT_API int bluetooth_gatt_client_set_service_change_watcher(
                }
        }
 
+done:
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
        return result;
 }
@@ -2477,9 +2773,7 @@ BT_EXPORT_API int bluetooth_gatt_client_deinit(
                        in_param1, in_param2, in_param3, in_param4, &out_param);
 
        if (result != BLUETOOTH_ERROR_NONE)
-               BT_INFO("GATT Client Unregistration failed result [%d]", result);
-       else
-               BT_INFO("GATT Client Unregistration successful");
+               BT_ERR("GATT Client Unregistration failed result [%d]", result);
 
        /* Unregister event handler if this is the only instance */
        event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
@@ -2487,10 +2781,10 @@ 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_INFO("Currently only one GATT client instance, so remove it and unregister GATT client events");
+                       BT_DBG("Currently only one GATT client instance, so remove it and unregister GATT client events");
                        _bt_unregister_event(BT_GATT_CLIENT_EVENT);
                        _bt_set_user_data(BT_GATT_CLIENT, NULL, NULL);
                } else
@@ -2501,5 +2795,3 @@ BT_EXPORT_API int bluetooth_gatt_client_deinit(
        BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
        return result;
 }
-
-#endif