Return error code properly
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / gatt / bt-service-gatt.c
index 61c4987..c6a1315 100644 (file)
@@ -255,6 +255,7 @@ static int __bt_do_unregister_gatt_instance(int instance_id);
 static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_data);
 static void __bt_handle_client_notification_registered(event_gattc_regdereg_notify_t *event_data,
                gboolean is_registered);
+static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data);
 
 #endif
 
@@ -1128,7 +1129,6 @@ static void __bt_handle_server_instance_registered(event_gatts_register_t *data)
                }
        }
        g_free(uuid_string);
-       g_free(data);
 }
 
 static void __bt_handle_gatt_server_service_added(event_gatts_srvc_prm_t *event)
@@ -1176,7 +1176,6 @@ static void __bt_handle_gatt_server_service_added(event_gatts_srvc_prm_t *event)
                }
        }
 
-       g_free(event);
        g_free(uuid_str);
 }
 
@@ -1218,7 +1217,6 @@ static void __bt_handle_gatt_server_characteristic_added(event_gatts_srvc_charct
        _bt_uuid_to_string(&(event->charctr_uuid), uuid_str);
        BT_INFO("GATT Added Characteristic:  UUID: [%s]", uuid_str);
 
-       g_free(event);
        g_free(uuid_str);
 }
 
@@ -1258,7 +1256,6 @@ static void __bt_handle_gatt_server_descriptor_added(event_gatts_srvc_descr_t* e
        _bt_uuid_to_string(&(event->descrptr_uuid), uuid_str);
        BT_INFO("GATT Added Descriptor:  UUID: [%s]", uuid_str);
 
-       g_free(event);
        g_free(uuid_str);
 }
 
@@ -1290,8 +1287,6 @@ static void __bt_handle_gatt_server_service_started(event_gatts_srvc_t *event)
                        break;
                }
        }
-
-       g_free(event);
 }
 
 static void __bt_handle_gatt_server_service_stopped(event_gatts_srvc_t *event)
@@ -1321,8 +1316,6 @@ static void __bt_handle_gatt_server_service_stopped(event_gatts_srvc_t *event)
                        break;
                }
        }
-
-       g_free(event);
 }
 
 static void __bt_handle_gatt_server_service_deleted(event_gatts_srvc_t *event)
@@ -1352,8 +1345,6 @@ static void __bt_handle_gatt_server_service_deleted(event_gatts_srvc_t *event)
                        break;
                }
        }
-
-       g_free(event);
 }
 
 static struct gatt_client_info_t *__bt_find_remote_gatt_client_info(char *address)
@@ -1454,6 +1445,7 @@ static void __bt_handle_gatt_server_connection_state(event_gatts_conn_t *event)
        int result = BLUETOOTH_ERROR_NONE;
        struct gatt_client_info_t *conn_info = NULL;
        bluetooth_device_address_t dev_addr;
+       GVariant *param = NULL;
 
        char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
 
@@ -1463,6 +1455,10 @@ static void __bt_handle_gatt_server_connection_state(event_gatts_conn_t *event)
           in this event */
        _bt_convert_addr_type_to_string(address,
                        (unsigned char *)dev_addr.addr);
+
+       if (event->status != OAL_STATUS_SUCCESS)
+               result = BLUETOOTH_ERROR_INTERNAL;
+
        __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
                        address, BT_ADDRESS_STRING_SIZE);
 
@@ -1475,14 +1471,14 @@ static void __bt_handle_gatt_server_connection_state(event_gatts_conn_t *event)
 
        if (!conn_info) {
                BT_INFO("Conn Info absent: But no need to Send Local GATT Server Connected event to apps");
-#if 0
+
                param = g_variant_new("(is)", result, address);
 
                /* Send event to application */
                _bt_send_event(BT_DEVICE_EVENT,
                                BLUETOOTH_EVENT_GATT_SERVER_CONNECTED, /* Local device is GATT server */
                                param);
-#endif
+
                /* Save Connection info */
                conn_info = g_new0(struct gatt_client_info_t, 1);
                conn_info->addr = g_strdup(address);
@@ -1502,8 +1498,8 @@ static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *even
        int result = BLUETOOTH_ERROR_NONE;
        struct gatt_client_info_t *conn_info = NULL;
        bluetooth_device_address_t dev_addr;
-
-       char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       GVariant *param = NULL;
+       char address[BT_ADDRESS_STRING_SIZE];
 
        memcpy(dev_addr.addr, event->address.addr, 6);
 
@@ -1512,6 +1508,9 @@ static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *even
        _bt_convert_addr_type_to_string(address,
                        (unsigned char *)dev_addr.addr);
 
+       if (event->status != OAL_STATUS_SUCCESS)
+               result = BLUETOOTH_ERROR_INTERNAL;
+
        if (NULL ==  _bt_get_request_info_data(BT_DISCONNECT_LE, address)) {
                if (NULL !=  _bt_get_request_info_data(BT_CONNECT_LE, address)) {
                        result = BLUETOOTH_ERROR_INTERNAL;
@@ -1533,21 +1532,19 @@ static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *even
        conn_info = __bt_find_remote_gatt_client_info(address);
        if (conn_info) {
                BT_INFO("No need to Send Local GATT Server Disconnected event to apps, just remove remote client info");
-#if 0
+
                param = g_variant_new("(is)", result, address);
                /* Send event to application */
                _bt_send_event(BT_DEVICE_EVENT,
                                BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED, /* Local device is GATT server */
                                param);
-#endif
+
                /* Remove info from List */
                gatt_client_info_list = g_slist_remove(gatt_client_info_list, conn_info);
                BT_INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
                g_free(conn_info->addr);
                g_free(conn_info);
        }
-
-       g_free(address);
 }
 #else
 
@@ -1664,6 +1661,84 @@ static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *even
 }
 #endif
 
+
+static void __bt_handle_gatt_server_acquire_write_requested(event_gatts_srvc_acquire_attr_t *event)
+{
+       GVariant *param = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       struct gatt_server_req_info *req_info = NULL;
+       bluetooth_device_address_t dev_addr;
+       char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+
+       BT_INFO("GATT Server ACQUIRE  Write Req Connection ID: [%d]", event->attr_trans.conn_id);
+       BT_INFO("GATT Server  ACQUIRE Write Req Transaction ID:[%d]", event->attr_trans.trans_id);
+       BT_INFO("GATT Server ACQUIRE Write Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
+
+       //address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       memcpy(dev_addr.addr, event->address.addr, 6);
+
+       req_info = g_new0(struct gatt_server_req_info, 1);
+       req_info->request_id = event->attr_trans.trans_id;
+       req_info->attribute_handle = event->attr_trans.attr_handle;
+       req_info->connection_id = event->attr_trans.conn_id;
+       req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
+       gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
+
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+
+       param = g_variant_new("(iiiiiis)", result,
+                       event->attr_trans.conn_id,
+                       event->attr_trans.trans_id,
+                       event->attr_trans.attr_handle,
+                       event->mtu, event->attr_trans.offset, address);
+       BT_INFO("GATT Server ACQUIRE Write Req Attribute remote address : [%s]", address);
+
+       _bt_send_event(BT_GATT_SERVER_EVENT,
+                       BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_WRITE,
+                       param);
+
+}
+
+static void __bt_handle_gatt_server_acquire_notify_requested(event_gatts_srvc_acquire_attr_t *event)
+{
+       GVariant *param = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       struct gatt_server_req_info *req_info = NULL;
+       bluetooth_device_address_t dev_addr;
+       char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+
+       BT_INFO("GATT Server ACQUIRE  Notify Req Connection ID: [%d]", event->attr_trans.conn_id);
+       BT_INFO("GATT Server ACQUIRE Notify  Req Transaction ID:[%d]", event->attr_trans.trans_id);
+       BT_INFO("GATT Server ACQUIRE Notify Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
+       BT_INFO("GATT Server ACQUIRE notify Req address : [%s]", address);
+
+       memcpy(dev_addr.addr, event->address.addr, 6);
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+       BT_INFO("GATT Server ACQUIRE notify Req remote address : [%s]", address);
+
+       req_info = g_new0(struct gatt_server_req_info, 1);
+       req_info->request_id = event->attr_trans.trans_id;
+       req_info->attribute_handle = event->attr_trans.attr_handle;
+       req_info->connection_id = event->attr_trans.conn_id;
+       req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
+       gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
+
+       param = g_variant_new("(iiiiiis)", result,
+                       event->attr_trans.conn_id,
+                       event->attr_trans.trans_id,
+                       event->attr_trans.attr_handle,
+                       event->mtu, event->attr_trans.offset,
+                       address);
+
+       BT_INFO("GATT Server ACQUIRE Notify  Req Attribute : ");
+
+        _bt_send_event(BT_GATT_SERVER_EVENT,
+                                BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_NOTIFY,
+                                param);
+}
+
 static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_t *event)
 {
        char *address;
@@ -1690,7 +1765,6 @@ static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_
 
        if (event->length <= 0) {
                BT_INFO("GATT Server write requested, but length of attr value is 0");
-               g_free(event);
                return;
        }
 
@@ -1741,7 +1815,6 @@ static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_
                         BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
                        param);
 
-       g_free(event);
        g_free(write_val);
 }
 
@@ -1792,8 +1865,6 @@ static void __bt_handle_gatt_server_read_requested(event_gatts_srvc_read_attr_t
        _bt_send_event(BT_GATT_SERVER_EVENT,
                        BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
                        param);
-
-       g_free(event);
 }
 
 static void __bt_handle_gatt_server_indicate_confirmed(event_gatts_ind_cnfrm_t *event)
@@ -1841,7 +1912,6 @@ static void __bt_handle_gatt_server_indicate_confirmed(event_gatts_ind_cnfrm_t *
                        param);
 
        BT_INFO("Received Indication confirm for client number [%d]", recvd);
-       g_free(event);
        g_free(address);
 }
 
@@ -1878,7 +1948,6 @@ static void __bt_handle_gatt_server_notification_changed(event_gatts_notif_t *ev
                        BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
                        param);
 
-       g_free(event);
        g_free(address);
 }
 
@@ -1893,7 +1962,6 @@ static void __bt_handle_gatt_mtu_changed_event(event_gatts_mtu_changed_t *event)
        conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
        if (conn_info == NULL) {
                BT_ERR("Cant find connection Information");
-               g_free(event);
                return;
        }
        BT_INFO("Got connection Info GATT client [%s] MTU Size [%d]",
@@ -1909,7 +1977,6 @@ static void __bt_handle_gatt_mtu_changed_event(event_gatts_mtu_changed_t *event)
        _bt_send_event(BT_GATT_SERVER_EVENT,
                        BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
                        param);
-       g_free(event);
 }
 
 static void __bt_gatt_event_handler(int event_type, gpointer event_data)
@@ -1918,87 +1985,83 @@ static void __bt_gatt_event_handler(int event_type, gpointer event_data)
        switch (event_type) {
                case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED: {
                BT_INFO("OAL Event: Server Instance Registered");
-               event_gatts_register_t* event = g_memdup(event_data, sizeof(event_gatts_register_t));
                /* GATT Server Registered event is handled in MAIN thread context */
-               __bt_handle_server_instance_registered(event);
+               __bt_handle_server_instance_registered((event_gatts_register_t *)event_data);
                break;
                                                                }
        case OAL_EVENT_GATTS_SERVICE_ADDED: {
                BT_INFO("OAL Event: GATT Service added");
-               event_gatts_srvc_prm_t *service_parm = g_memdup(event_data, sizeof(event_gatts_srvc_prm_t));
-               __bt_handle_gatt_server_service_added(service_parm);
+               __bt_handle_gatt_server_service_added((event_gatts_srvc_prm_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_CHARACTERISTIC_ADDED: {
                BT_INFO("OAL Event: GATT characteristic added");
-               event_gatts_srvc_charctr_t *char_parm = g_memdup(event_data, sizeof(event_gatts_srvc_charctr_t));
-               __bt_handle_gatt_server_characteristic_added(char_parm);
+               __bt_handle_gatt_server_characteristic_added((event_gatts_srvc_charctr_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_DESCRIPTOR_ADDED: {
                BT_INFO("OAL Event: GATT descriptor added");
-               event_gatts_srvc_descr_t *desc_parm = g_memdup(event_data, sizeof(event_gatts_srvc_descr_t));
-               __bt_handle_gatt_server_descriptor_added(desc_parm);
+               __bt_handle_gatt_server_descriptor_added((event_gatts_srvc_descr_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_SERVICE_STARTED: {
                BT_INFO("OAL Event: GATT Service started");
-               event_gatts_srvc_t *svc_started = g_memdup(event_data, sizeof(event_gatts_srvc_t));
-               __bt_handle_gatt_server_service_started(svc_started);
+               __bt_handle_gatt_server_service_started((event_gatts_srvc_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_SERVICE_STOPED: {
                BT_INFO("OAL Event: GATT Service stopped");
-               event_gatts_srvc_t *svc_stopped = g_memdup(event_data, sizeof(event_gatts_srvc_t));
-               __bt_handle_gatt_server_service_stopped(svc_stopped);
+               __bt_handle_gatt_server_service_stopped((event_gatts_srvc_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_SERVICE_DELETED: {
                BT_INFO("OAL Event: GATT Service deleted");
-               event_gatts_srvc_t *svc_deleted = g_memdup(event_data, sizeof(event_gatts_srvc_t));
-               __bt_handle_gatt_server_service_deleted(svc_deleted);
+               __bt_handle_gatt_server_service_deleted((event_gatts_srvc_t *) event_data);
                break;
        }
        case OAL_EVENT_GATTS_CONNECTION_COMPLETED: {
                BT_INFO("OAL Event: GATT Server Connected");
-               event_gatts_conn_t* event = g_memdup(event_data, sizeof(event_gatts_conn_t));
-               __bt_handle_gatt_server_connection_state(event);
+               __bt_handle_gatt_server_connection_state((event_gatts_conn_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_DISCONNECTION_COMPLETED: {
                BT_INFO("OAL Event: GATT Server Disconnected");
-               event_gatts_conn_t* event = g_memdup(event_data, sizeof(event_gatts_conn_t));
-               __bt_handle_gatt_server_disconnection_state(event);
+               __bt_handle_gatt_server_disconnection_state((event_gatts_conn_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_REQUEST_READ: {
                BT_INFO("OAL Event: GATT Server Read Request");
-               event_gatts_srvc_read_attr_t *read_req = g_memdup(event_data, sizeof(event_gatts_srvc_read_attr_t));
-               __bt_handle_gatt_server_read_requested(read_req);
+               __bt_handle_gatt_server_read_requested((event_gatts_srvc_read_attr_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_REQUEST_WRITE: {
                BT_INFO("OAL Event: GATT Server Write Request");
-               event_gatts_srvc_write_attr_t *write_req = g_memdup(event_data, sizeof(event_gatts_srvc_write_attr_t));
-               __bt_handle_gatt_server_write_requested(write_req);
+               __bt_handle_gatt_server_write_requested((event_gatts_srvc_write_attr_t *)event_data);
+               break;
+       }
+       case OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE: {
+               BT_INFO("OAL Event: GATT Server Acquire  Write Request");
+               __bt_handle_gatt_server_acquire_write_requested((event_gatts_srvc_acquire_attr_t*)event_data);
+               break;
+       }
+       case OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY: {
+               BT_INFO("OAL Event: GATT ServerAcquire Notify  Request");
+               __bt_handle_gatt_server_acquire_notify_requested((event_gatts_srvc_acquire_attr_t*)event_data);
                break;
        }
        case OAL_EVENT_GATTS_IND_CONFIRM: {
                BT_INFO("OAL Event: GATT Server Indication confirmed");
-               event_gatts_ind_cnfrm_t *parm = g_memdup(event_data, sizeof(event_gatts_ind_cnfrm_t));
-               __bt_handle_gatt_server_indicate_confirmed(parm);
+               __bt_handle_gatt_server_indicate_confirmed((event_gatts_ind_cnfrm_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_NOTIFICATION: { /* Tizen Platform Specific */
                BT_INFO("OAL Event: GATT Server DisConnected");
-               event_gatts_notif_t* notif = g_memdup(event_data, sizeof(event_gatts_notif_t));
-               __bt_handle_gatt_server_notification_changed(notif);
+               __bt_handle_gatt_server_notification_changed((event_gatts_notif_t *)event_data);
                break;
        }
        case OAL_EVENT_GATTS_MTU_CHANGED: {
                BT_INFO("OAL Event: GATT Server MTU changed event callback");
-               event_gatts_mtu_changed_t *mtu_changed = g_memdup(event_data, sizeof(event_gatts_mtu_changed_t));
-               __bt_handle_gatt_mtu_changed_event(mtu_changed);
+               __bt_handle_gatt_mtu_changed_event((event_gatts_mtu_changed_t *)event_data);
                break;
        }
 #ifdef TIZEN_GATT_CLIENT
@@ -2072,6 +2135,11 @@ static void __bt_gatt_event_handler(int event_type, gpointer event_data)
                __bt_handle_client_notification_registered((event_gattc_regdereg_notify_t *) event_data, FALSE);
                break;
        }
+       case OAL_EVENT_GATTC_NOTIFY_DATA: {
+               BT_INFO("OAL Event: GATT Client Notification Data");
+               __bt_handle_client_notification_data((event_gattc_notify_data *) event_data);
+
+       }
 #endif
        default:
                break;
@@ -2270,6 +2338,43 @@ int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
        return BLUETOOTH_ERROR_NONE;
 }
 
+int _bt_gatt_server_acquire_send_response(char *sender, bluetooth_gatt_server_acquire_response_params_t *param ,       void *fd_list)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       BT_CHECK_PARAMETER(param, return);
+       struct gatt_server_req_info *req_info = NULL;
+       int ret = OAL_STATUS_SUCCESS;
+
+
+       BT_INFO("GATT acquire Server Response: Req Type [%d] req_id [%d] fd  [%d] mtu[%d]",
+                       param->req_type, param->request_id,
+                        param->fd,
+                       param->mtu);
+
+       /* Search for matching Request in List */
+       req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
+       if (!req_info) {
+               BT_ERR("GATT acquire Server Req Info not found for current response..return Error");
+               return BLUETOOTH_ERROR_NOT_IN_OPERATION;
+       }
+
+       ret = gatt_send_response_acquire(req_info->connection_id, param->request_id, 0, param->fd, param->mtu, fd_list);
+
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_INFO("GATT acquire Server Response successfully sent");
+       /* Remove GATT server request from list */
+       gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
+       g_free(req_info->addr);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+
+
 int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *dev_addr,
                bluetooth_gatt_att_data_t *data,
                bluetooth_gatt_server_indication_params_t *param)
@@ -2375,7 +2480,7 @@ int _bt_get_att_mtu(bluetooth_device_address_t *address,
                BT_INFO("GATT Client [%s] is connected, conn Id [%d] Instance ID [%d]",
                                conn_info->addr, conn_info->connection_id, conn_info->instance_id);
        } else {
-               BT_ERR("GATT Client [%s] is not yet connected..");
+               BT_ERR("GATT Client [%s] is not yet connected..", addr);
                return BLUETOOTH_ERROR_NOT_CONNECTED;
        }
 
@@ -2384,8 +2489,15 @@ int _bt_get_att_mtu(bluetooth_device_address_t *address,
                BT_ERR("ret: %d", ret);
                return BLUETOOTH_ERROR_INTERNAL;
        }
+
        BT_INFO("ATT MTU received from OAL [%d]", stack_mtu);
        *mtu = (unsigned int)stack_mtu;
+
+       if (*mtu == 0) {
+               BT_ERR("MTU value is zero, GATT Client [%s] is not yet connected..", addr);
+               return BLUETOOTH_ERROR_NOT_CONNECTED;
+       }
+
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -2593,13 +2705,13 @@ static void __bt_build_service_browse_info(int conn_id,
                memcpy(&uuid.uuid, &svc_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
                _bt_uuid_to_string(&uuid, uuid_string);
 
-               BT_INFO("Service UUID formed [%s] strlen [%d]", uuid_string, strlen(uuid_string));
+               BT_INFO("Service UUID formed [%s] strlen [%zd]", uuid_string, strlen(uuid_string));
 
                /* Fill UUID of service */
                g_strlcpy(info->uuids[count], uuid_string,
                                BLUETOOTH_UUID_STRING_MAX);
 
-               BT_INFO("Service UUID formed  TO be sent [%s] strlen [%d]",
+               BT_INFO("Service UUID formed  TO be sent [%s] strlen [%zd]",
                                info->uuids[count], strlen(info->uuids[count]));
                /* Fill instance ID of service */
                info->inst_id[count] = svc_info->inst_id;
@@ -2691,14 +2803,17 @@ static void __bt_build_descriptor_browse_info(int conn_id,
        memcpy(&info->char_uuid, char_info->uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
        info->char_inst_id = char_info->inst_id;
 
+       /* Fill property of the parent characteristic of this descriptor */
+       info->char_props_map = char_info->props;
+
+       info->count = g_slist_length(char_info->descs);
+       BT_INFO("Total count of Descriptors [%d]", info->count);
+
        if (!char_info->descs) {
                BT_ERR("No Descriptors browsed for address [%s]", conn_info->addr);
                return;
        }
 
-       info->count = g_slist_length(char_info->descs);
-       BT_INFO("Total count of Descriptors [%d]", info->count);
-
        for (l = char_info->descs; l != NULL; l = g_slist_next(l)) {
                desc_info = (bt_gatt_descriptor_info_t*)l->data;
                if (desc_info == NULL)
@@ -2714,8 +2829,6 @@ static void __bt_build_descriptor_browse_info(int conn_id,
                /* Fill instance ID of Descriptor */
                info->inst_id[count] = desc_info->inst_id;
 
-               /* Fill property of the parent characteristic of this descriptor */
-               info->char_props_map = char_info->props;
 
                /* Increment count of Descriptor browsed */
                count++;
@@ -2791,6 +2904,8 @@ static void __bt_cleanup_remote_services(struct gatt_server_info_t *conn_info)
                svc_info_list->services = g_slist_remove(svc_info_list->services, svc);
                g_free(svc);
        }
+
+       list_gatt_info = g_slist_remove(list_gatt_info, svc_info_list);
        g_free(svc_info_list);
        BT_INFO("Cleanup of all services done");
 }
@@ -2985,6 +3100,7 @@ static void __bt_handle_client_disconnected(event_gattc_conn_t *event_data)
                        __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
                                        address, BT_ADDRESS_STRING_SIZE);
                        BT_ERR("Failed to connect Local GATT Remote addr[%s]", address);
+                       g_free(address);
                        return;
                }
        } else {
@@ -3207,7 +3323,8 @@ static void __bt_handle_client_characteristic_search_result(
                        svc_info->chars = g_slist_append(svc_info->chars, char_info);
                } else {
                        /* If found, then return */
-                       BT_INFO("Characteristic browsed is already presesnt");
+                       BT_INFO("update char property as Characteristic browsed is already present");
+                       char_info->props |= event_data->char_prop;
                }
        } else {
                /* If Not success: Means Charc browse is completed  */
@@ -3462,7 +3579,7 @@ static void __bt_handle_client_descriptor_read_data(
        if (event_data->uuid_status.conn_status.status != OAL_STATUS_SUCCESS)
                result = BLUETOOTH_ERROR_INTERNAL;
        else {
-               BT_INFO("desc data len:", event_data->data_len);
+               BT_INFO("desc data len:%d", event_data->data_len);
                if (event_data->data_len > 0) {
                        /* DEBUG */
                        for (i = 0; i < event_data->data_len; i++)
@@ -3765,6 +3882,7 @@ static void __bt_hanlde_le_device_disconnection(event_dev_conn_status_t *event_d
 
        __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE, address,
                                                 BT_ADDRESS_STRING_SIZE);
+       g_free(address);
 }
 
 static void __bt_handle_client_notification_registered(
@@ -3819,6 +3937,91 @@ static void __bt_handle_client_notification_registered(
                        sizeof(bt_gatt_notif_reg_info_t));
 }
 
+static void __bt_handle_client_notification_data(event_gattc_notify_data *event_data)
+{
+       /* No status in this event from OAL */
+       int result = BLUETOOTH_ERROR_NONE;
+
+       /* Read Information data structures */
+       GVariant *param = NULL;
+       GVariant *data = NULL;
+       GVariant *data_svc_uuid = NULL;
+       GVariant *data_char_uuid = NULL;
+       char *read_val = NULL;
+       char *svc_uuid = NULL;
+       char *char_uuid = NULL;
+       char *addr = NULL;
+       int i;
+       int uuid_len = 16;
+       BT_INFO("+");
+
+       BT_INFO("Notifcation of charc data changed");
+
+       if (event_data->data_len > 0) {
+               /* DEBUG */
+               for (i = 0; i < event_data->data_len; i++)
+                       BT_INFO("Data[%d] = [0x%x]", i, event_data->data[i]);
+
+               /* Fill address */
+               addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+               _bt_convert_addr_type_to_string(addr,
+                               (unsigned char *)&(event_data->address.addr));
+
+               /* Read data */
+               read_val = g_memdup(&event_data->data[0], event_data->data_len);
+
+               data = g_variant_new_from_data(
+                               G_VARIANT_TYPE_BYTESTRING,
+                               read_val,
+                               event_data->data_len,
+                               TRUE, NULL, NULL);
+               /* SVC uuid */
+               svc_uuid = g_memdup(&event_data->srvc_id.id.uuid.uuid[0], uuid_len);
+
+               data_svc_uuid = g_variant_new_from_data(
+                               G_VARIANT_TYPE_BYTESTRING,
+                               svc_uuid,
+                               uuid_len,
+                               TRUE, NULL, NULL);
+
+               /* Char uuid */
+               char_uuid = g_memdup(&event_data->char_id.uuid.uuid[0], uuid_len);
+
+               data_char_uuid = g_variant_new_from_data(
+                               G_VARIANT_TYPE_BYTESTRING,
+                               char_uuid,
+                               uuid_len,
+                               TRUE, NULL, NULL);
+
+               /* Build Param */
+               param = g_variant_new("(isn@ayin@ayin@ay)", result,
+                               addr,
+                               16,
+                               data_svc_uuid,
+                               event_data->srvc_id.id.inst_id,
+                               16,
+                               data_char_uuid,
+                               event_data->char_id.inst_id,
+                               event_data->data_len,
+                               data);
+
+               /* Send Event */
+               _bt_send_event(BT_GATT_CLIENT_EVENT,
+                               BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
+                               param);
+       } else {
+               BT_ERR("No Data!!");
+       }
+       /* Free data */
+       if (read_val)
+               g_free(read_val);
+       if (svc_uuid)
+               g_free(svc_uuid);
+       if (char_uuid)
+               g_free(char_uuid);
+       if (addr)
+               g_free(addr);
+}
 
 gboolean _bt_is_remote_gatt_device_connected(bluetooth_device_address_t *address)
 {
@@ -4200,6 +4403,100 @@ int _bt_gatt_read_descriptor_value(
        return BLUETOOTH_ERROR_NONE;
 }
 
+/*acquire Notify*/
+int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
+{
+       struct gatt_server_info_t *conn_info = NULL;
+       oal_gatt_srvc_id_t srvc_id;
+       oal_gatt_id_t char_id;
+       int ret = OAL_STATUS_SUCCESS;
+       char *addr;
+
+       BT_CHECK_PARAMETER(chr, return);
+
+       BT_INFO("+");
+
+       addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
+       _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
+
+       /* Check if remote GATT Server is connected or not */
+       conn_info = __bt_find_remote_gatt_server_info(addr);
+       if (conn_info) {
+               BT_INFO("GATT Server [%s] is connected, conn Id [%d]",
+                               conn_info->addr, conn_info->connection_id);
+       } else {
+               BT_ERR("GATT Server is not yet connected..");
+               g_free(addr);
+               return BLUETOOTH_ERROR_NOT_CONNECTED;
+       }
+
+       srvc_id.is_prmry = TRUE;
+       srvc_id.id.inst_id = chr->svc.instance_id;
+       memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+       char_id.inst_id = chr->characteristic.instance_id;
+       memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+               ret = gattc_acquire_notify(conn_info->connection_id, &srvc_id, &char_id, fd, mtu);
+
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               g_free(addr);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       BT_INFO("GATT characterstics FD [%d]  mtu[%d]", *fd, *mtu);
+       g_free(addr);
+       return BLUETOOTH_ERROR_NONE;
+}
+
+/*acquire Write*/
+int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
+{
+
+       struct gatt_server_info_t *conn_info = NULL;
+       oal_gatt_srvc_id_t srvc_id;
+       oal_gatt_id_t char_id;
+       int ret = OAL_STATUS_SUCCESS;
+       char *addr;
+
+       BT_CHECK_PARAMETER(chr, return);
+
+       BT_INFO("+");
+
+       addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
+       _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
+
+       /* Check if remote GATT Server is connected or not */
+       conn_info = __bt_find_remote_gatt_server_info(addr);
+       if (conn_info) {
+               BT_INFO("GATT Server [%s] is connected, conn Id [%d]",
+                               conn_info->addr, conn_info->connection_id);
+       } else {
+               BT_ERR("GATT Server is not yet connected..");
+               g_free(addr);
+               return BLUETOOTH_ERROR_NOT_CONNECTED;
+       }
+
+       srvc_id.is_prmry = TRUE;
+       srvc_id.id.inst_id = chr->svc.instance_id;
+       memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+       char_id.inst_id = chr->characteristic.instance_id;
+       memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+               ret = gattc_acquire_write(conn_info->connection_id, &srvc_id, &char_id,
+                                       OAL_GATT_AUTH_REQ_NONE, fd, mtu);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               g_free(addr);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       BT_INFO("GATT characterstics FD [%d]  mtu [%d]", *fd, *mtu);
+       g_free(addr);
+       return BLUETOOTH_ERROR_NONE;
+
+}
+
 
 /* Write Characteristic */
 int _bt_gatt_write_characteristic_value_by_type(
@@ -4418,6 +4715,7 @@ int _bt_disconnect_le_device(bluetooth_device_address_t *address,
                int client_id)
 {
        struct gatt_server_info_t *conn_info = NULL;
+       struct gatt_client_info_t *rem_client_conn_info = NULL;
        invocation_info_t *req_info = NULL;
        int ret = OAL_STATUS_SUCCESS;
        char *addr;
@@ -4444,23 +4742,33 @@ int _bt_disconnect_le_device(bluetooth_device_address_t *address,
        }
        /* Check if remote GATT Server is connected or not */
        conn_info = __bt_find_remote_gatt_server_info(addr);
-       if (!conn_info) {
-               BT_ERR("GATT Server is not connected..");
-               g_free(addr);
-               return BLUETOOTH_ERROR_NOT_IN_OPERATION;
-       }
+       if (conn_info) {
+               /* Check if app sent 0 client id for Disconnection, in such case, use default gatt client ID */
+               if (client_id == 0) {
+                       BT_INFO("GATT CLient Disconnect request sent by an app without any client instance [%d]",
+                                       client_id);
+                       BT_INFO("Assign default GATT client id [%d]", gatt_default_client);
+                       client_id = gatt_default_client;
+               }
 
-       /* Check if app sent 0 client id for Disconnection, in such case, use default gatt client ID */
-       if (client_id == 0) {
-               BT_INFO("GATT CLient Disconnect request sent by an app without any client instance [%d]",
-                               client_id);
-               BT_INFO("Assign default GATT client id [%d]", gatt_default_client);
-               client_id = gatt_default_client;
-       }
+               BT_INFO("Disconnect remote gatt server using CLient ID [%d] Connection ID [%d]", client_id, conn_info->connection_id);
+               ret = gattc_disconnect(client_id, (bt_address_t*)(address),
+                               conn_info->connection_id);
+       } else {
+               /* check if remote client is connected */
+               rem_client_conn_info = __bt_find_remote_gatt_client_info(addr);
 
-       BT_INFO("Disconnect using CLient ID [%d] Connection ID [%d]", client_id, conn_info->connection_id);
-       ret = gattc_disconnect(client_id, (bt_address_t*)(address),
-                       conn_info->connection_id);
+               if (!rem_client_conn_info || client_id != 0) {
+                       BT_ERR("GATT device is not connected..");
+                       g_free(addr);
+                       return BLUETOOTH_ERROR_NOT_IN_OPERATION;
+               }
+
+               BT_INFO("Disconnect remote gatt client ");
+
+               ret = gatts_disconnect(rem_client_conn_info->instance_id,
+                       (bt_address_t*)(address), rem_client_conn_info->connection_id);
+       }
 
        if (ret != OAL_STATUS_SUCCESS) {
                BT_ERR("ret: %d", ret);