Fix unintended unregister issue for gatt server instance
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / gatt / bt-service-gatt.c
index abcba75..a0413c0 100644 (file)
@@ -251,14 +251,14 @@ static void __bt_handle_client_characteristic_read_data(event_gattc_read_data *e
 static void __bt_handle_client_descriptor_read_data(event_gattc_read_data *event_data);
 static void __bt_handle_client_characteristic_write_data(event_gattc_write_data *event_data);
 static void __bt_handle_client_descriptor_write_data(event_gattc_write_data *event_data);
-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
 
-static int __bt_do_unregister_server_instance(int server_instance);
+static int __bt_unregister_gatt_server_instance(int server_instance);
 
 /* Linked List of GATT requests from Remote GATT Clients */
 static GSList *gatt_server_requests = NULL;
@@ -318,7 +318,7 @@ void _bt_check_adv_app_termination(const char *name)
                if (apps[k] == 1) {
                        BT_INFO("Unregister app[%d]", k);
                        /* Unregister server instance */
-                       __bt_do_unregister_server_instance(k);
+                       __bt_unregister_gatt_server_instance(k);
                }
        }
 }
@@ -595,58 +595,7 @@ void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len,
        }
 }
 
-#ifdef TIZEN_GATT_CLIENT
-static int __bt_do_unregister_gatt_instance(int instance_id)
-{
-       int ret = OAL_STATUS_SUCCESS;
-       int k;
-
-       BT_INFO("DeAllocate server or client instance ID [%d]", instance_id);
-
-       /* Reset data: instance_id parameter could be either for GATT Server or for GATT client  */
-       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
-               if (numapps[k].instance_id == instance_id) {
-                       BT_INFO("This is a GATT server app, unregister: Slot [%d] vacant", k);
-                       numapps[k].is_initialized = FALSE;
-                       numapps[k].instance_id = -1;
-                       numapps[k].adv_handle = 0;
-                       numapps[k].adv_instance = -1;
-                       memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
-                       memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
-                       memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
-                       memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
-                       numapps[k].adv_data_len = 0;
-                       numapps[k].scan_rsp_len = 0;
-
-                       /* Its a GATT Server Instance */
-                       ret = gatts_unregister(instance_id);
-                       if (ret != OAL_STATUS_SUCCESS) {
-                               BT_ERR("DeAllocate server instance with stack Fail ret: %d", ret);
-                               return BLUETOOTH_ERROR_INTERNAL;
-                       }
-                       break;
-               } else if (numapps[k].client_id == instance_id) {
-                       BT_INFO("This is a GATT client app, unregister: Slot [%d] vacant", k);
-                       numapps[k].client_id = -1;
-                       numapps[k].is_initialized = FALSE;
-                       memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
-                       memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
-                       memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
-
-                       /* Its a GATT Client Instance */
-                       ret = gattc_deregister(instance_id);
-                       if (ret != OAL_STATUS_SUCCESS) {
-                               BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
-                               return BLUETOOTH_ERROR_INTERNAL;
-                       }
-                       break;
-               }
-       }
-       return BLUETOOTH_ERROR_NONE;
-}
-#endif
-
-static int __bt_do_unregister_server_instance(int server_instance)
+static int __bt_unregister_gatt_server_instance(int server_instance)
 {
        int ret = OAL_STATUS_SUCCESS;
        int k;
@@ -757,7 +706,7 @@ int _bt_unregister_server_instance(const char *sender, int adv_handle)
                if (!numapps[server_instance].service_handles) {
                        BT_INFO("There are no Service handles with this app, safe to unregister");
                        /* Unregister server instance only if this sender does not have any gatt services in it */
-                       result = __bt_do_unregister_server_instance(server_instance);
+                       result = __bt_unregister_gatt_server_instance(server_instance);
                } else {
                        numapps[server_instance].adv_handle = 0;
                        memset(numapps[server_instance].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
@@ -773,7 +722,7 @@ int _bt_unregister_server_instance(const char *sender, int adv_handle)
                if (apps[k] == 1) {
                        BT_INFO("Unregister app[%d]", k);
                        /* Unregister server instance */
-                       __bt_do_unregister_server_instance(k);
+                       __bt_unregister_gatt_server_instance(k);
                }
        }
 
@@ -841,8 +790,9 @@ static void __bt_gatt_handle_pending_request_info(int result,
        ret_if(data == NULL);
        BT_DBG("+");
 
-       for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
+       for (l = _bt_get_invocation_list(); l != NULL; ) {
                req_info = l->data;
+               l = g_slist_next(l);
                if (req_info == NULL || req_info->service_function != service_function)
                        continue;
 
@@ -1454,6 +1404,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);
 
@@ -1503,6 +1457,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;
@@ -1653,6 +1610,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;
@@ -1953,6 +1988,16 @@ static void __bt_gatt_event_handler(int event_type, gpointer event_data)
                __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");
                __bt_handle_gatt_server_indicate_confirmed((event_gatts_ind_cnfrm_t *)event_data);
@@ -2039,6 +2084,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;
@@ -2237,6 +2287,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)
@@ -2342,7 +2429,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;
        }
 
@@ -2351,8 +2438,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;
 }
 
@@ -2560,13 +2654,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;
@@ -2759,6 +2853,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");
 }
@@ -3432,7 +3528,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++)
@@ -3790,6 +3886,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)
 {
@@ -4171,6 +4352,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(
@@ -4389,6 +4664,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;
@@ -4415,23 +4691,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);
@@ -4468,29 +4754,37 @@ int _bt_gatt_watch_service_changed_indication(const char *sender,
 
 int _bt_unregister_gatt_client_instance(const char *sender, int client_id)
 {
-       BT_INFO("Unregister Allocated GATT CLient instance [%s] Client ID [%d]",
-                       sender, client_id);
-       int result = BLUETOOTH_ERROR_NONE;
-       int k;
+       bt_service_app_info_t *info = NULL;
+       int k, ret;
+
+       BT_INFO("Unregister Allocated GATT Client instance [%s] Client ID [%d]", sender, client_id);
 
        /* Unregister CLient instance associated with address X. It is possible that another app still
           has client_id valid for same remote address */
-       bt_service_app_info_t *info = NULL;
-
        for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
                info = &numapps[k];
 
                /* Exact matching of sender */
                if (!g_strcmp0(info->sender, sender) && info->client_id == client_id) {  /* Check for only valid GATT client Instance */
                        BT_INFO("Unregister GATT client instance [%d]", info->client_id);
-                       result = __bt_do_unregister_gatt_instance(info->client_id);
-                       if (result != BLUETOOTH_ERROR_NONE)
-                               BT_ERR("Error in unregistering GATT Client Interface");
+                       numapps[k].client_id = -1;
+                       numapps[k].is_initialized = FALSE;
+                       memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
+                       memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
+                       memset(&numapps[k].address.addr, 0x00, sizeof(bluetooth_device_address_t));
 
-                       break;
+                       /* Its a GATT Client Instance */
+                       ret = gattc_deregister(client_id);
+                       if (ret != OAL_STATUS_SUCCESS) {
+                               BT_ERR("DeAllocate GATT Client instance with stack Fail ret: %d", ret);
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       } else {
+                               return BLUETOOTH_ERROR_NONE;
+                       }
                }
        }
-       return result;
+
+       return BLUETOOTH_ERROR_NOT_FOUND;
 }
 
 #endif