OSDN Git Service

LE: Add GATT disable functions
authorAndre Eisenbach <andre@broadcom.com>
Wed, 15 May 2013 11:55:08 +0000 (04:55 -0700)
committerMatthew Xie <mattx@google.com>
Wed, 14 Aug 2013 00:40:44 +0000 (00:40 +0000)
This patch adds required disable functions to the GATT sub-system to
properly unregister with the stack. Without the disable functions in
place, turning Bluetooth off with a GATT device connected may lead to
unexpected behaviour and cause GATT to fail on sub-sequent stack
restarts.

Change-Id: I7cb80e96109e2c09882991298d0487b506f5ffdd

14 files changed:
bta/dm/bta_dm_act.c
bta/gatt/bta_gattc_act.c
bta/gatt/bta_gattc_api.c
bta/gatt/bta_gattc_int.h
bta/gatt/bta_gattc_main.c
bta/gatt/bta_gatts_act.c
bta/gatt/bta_gatts_api.c
bta/gatt/bta_gatts_int.h
bta/gatt/bta_gatts_main.c
bta/include/bta_gatt_api.h
btif/src/btif_core.c
btif/src/btif_gatt.c
stack/gatt/gatt_api.c
stack/gatt/gatt_utils.c

index 2d0cf91..2a408f4 100644 (file)
@@ -102,6 +102,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
     #endif
 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key);
     #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE))
+static void bta_dm_gattc_register(void);
 static void btm_dm_start_gatt_discovery ( BD_ADDR bd_addr);
 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr);
 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
@@ -381,10 +382,6 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
         {
             BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS *)&id_key);
         }
-#if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE))
-        memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
-        BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
-#endif
 #endif
 
         BTM_SecRegister((tBTM_APPL_INFO*)&bta_security);
@@ -433,6 +430,11 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
             WBT_ExtAddPinCode();
 #endif
 #endif
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+        memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
+        bta_dm_gattc_register();
+#endif
+
     }
     else
         APPL_TRACE_DEBUG0(" --- ignored event");
@@ -1178,7 +1180,7 @@ void bta_dm_search_start (tBTA_DM_MSG *p_data)
 {
     tBTM_INQUIRY_CMPL result;
 
-#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
     UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->search.num_uuid);
 #endif
 
@@ -4950,6 +4952,27 @@ void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
 
 /*******************************************************************************
 **
+** Function         bta_dm_gattc_register
+**
+** Description      Register with GATTC in DM if BLE is needed.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_dm_gattc_register(void)
+{
+    tBT_UUID                app_uuid = {LEN_UUID_128,{0}};
+
+    if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF)
+    {
+        memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
+        BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         btm_dm_start_disc_gatt_services
 **
 ** Description      This function starts a GATT service search request.
index 8936e60..d6b621a 100644 (file)
@@ -25,9 +25,6 @@
 
 #include "bt_target.h"
 
-#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
-
-
 #include "utl.h"
 #include "gki.h"
 #include "bd.h"
@@ -39,6 +36,8 @@
 
 #include <string.h>
 
+#if BTA_GATT_INCLUDED && BLE_INCLUDED == TRUE
+
 /*****************************************************************************
 **  Constants
 *****************************************************************************/
@@ -48,6 +47,8 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
 static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
                                   tGATT_CL_COMPLETE *p_data);
 
+static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
+
 static tGATT_CBACK bta_gattc_cl_cback =
 {
     bta_gattc_conn_cback,
@@ -84,6 +85,72 @@ static const char *bta_gattc_op_code_name[] =
 
 /*******************************************************************************
 **
+** Function         bta_gattc_enable
+**
+** Description      Enables GATTC module
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
+{
+    APPL_TRACE_DEBUG0("bta_gattc_enable");
+
+    if (p_cb->state == BTA_GATTC_STATE_DISABLED)
+    {
+        /* initialize control block */
+        memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
+        p_cb->state = BTA_GATTC_STATE_ENABLED;
+    }
+    else
+    {
+        APPL_TRACE_DEBUG0("GATTC is arelady enabled");
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         bta_gattc_disable
+**
+** Description      Disable GATTC module by cleaning up all active connections
+**                  and deregister all application.
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
+{
+    UINT8           i;
+
+    APPL_TRACE_DEBUG0("bta_gattc_disable");
+
+    if (p_cb->state != BTA_GATTC_STATE_ENABLED)
+    {
+        APPL_TRACE_ERROR0("not enabled or disable in pogress");
+        return;
+    }
+
+    for (i = 0; i <BTA_GATTC_CL_MAX; i ++)
+    {
+        if (p_cb->cl_rcb[i].in_use)
+        {
+            p_cb->state = BTA_GATTC_STATE_DISABLING;
+            bta_gattc_deregister(p_cb, &p_cb->cl_rcb[i]);
+        }
+    }
+
+    /* no registered apps, indicate disable completed */
+    if (p_cb->state != BTA_GATTC_STATE_DISABLING)
+    {
+        p_cb->state = BTA_GATTC_STATE_DISABLED;
+        memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         bta_gattc_register
 **
 ** Description      Register a GATT client application with BTA.
@@ -99,6 +166,13 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
     tBTA_GATTC_INT_START_IF  *p_buf;
     tBTA_GATT_STATUS         status = BTA_GATT_NO_RESOURCES;
 
+     APPL_TRACE_DEBUG1("bta_gattc_register state %d",p_cb->state);
+
+     /* check if  GATTC module is already enabled . Else enable */
+     if (p_cb->state == BTA_GATTC_STATE_DISABLED)
+     {
+         bta_gattc_enable (p_cb);
+     }
     /* todo need to check duplicate uuid */
     for (i = 0; i < BTA_GATTC_CL_MAX; i ++)
     {
@@ -128,6 +202,9 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
                 }
                 else
                 {
+                    GATT_Deregister(p_cb->cl_rcb[i].client_if);
+
+                    status = BTA_GATT_NO_RESOURCES;
                     memset( &p_cb->cl_rcb[i], 0 , sizeof(tBTA_GATTC_RCB));
                 }
                 break;
@@ -167,99 +244,6 @@ void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
 }
 /*******************************************************************************
 **
-** Function         bta_gattc_deregister_cmpl
-**
-** Description      De-Register a GATT client application with BTA completed.
-**
-** Returns          void
-**
-*******************************************************************************/
-void bta_gattc_int_deregister_cmpl(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_IF client_if)
-{
-    tBTA_GATTC_CBACK    *p_cback = p_clreg->p_cback;
-    tBTA_GATTC          cb_data;
-
-
-    APPL_TRACE_DEBUG1("bta_gattc_int_deregister_cmpl client_if=%d", client_if );
-
-    GATT_Deregister(p_clreg->client_if);
-    memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
-
-    cb_data.reg_oper.client_if = client_if;
-    cb_data.reg_oper.status    = BTA_GATT_OK;
-
-    if (p_cback)
-        /* callback with de-register event */
-        (*p_cback)(BTA_GATTC_DEREG_EVT,  (tBTA_GATTC *)&cb_data);
-}
-
-
-/*******************************************************************************
-**
-** Function         bta_gattc_deregister_cmpl
-**
-** Description      De-Register a GATT client application with BTA completed.
-**
-** Returns          void
-**
-*******************************************************************************/
-void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_IF client_if)
-{
-    tBTA_GATTC_INT_DEREG  *p_buf;
-
-    APPL_TRACE_DEBUG1("bta_gattc_deregister_cmpl client_if=%d", client_if );
-
-    if ((p_buf = (tBTA_GATTC_INT_DEREG *) GKI_getbuf(sizeof(tBTA_GATTC_INT_DEREG))) != NULL)
-    {
-        p_buf->hdr.event = BTA_GATTC_INT_DEREG_EVT;
-        p_buf->client_if = client_if;
-        bta_sys_sendmsg(p_buf);
-    }
-    else
-    {
-        APPL_TRACE_ERROR1("bta_gattc_deregister_cmpl unable to allocate buffer to complete dereg=%d", client_if);
-    }
-
-}
-/*******************************************************************************
-**
-** Function         bta_gattc_deregister
-**
-** Description      De-Register a GATT client application with BTA.
-**
-** Returns          void
-**
-*******************************************************************************/
-void bta_gattc_int_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
-{
-
-    tBTA_GATTC_IF       client_if = p_data->int_dereg.client_if;
-    tBTA_GATTC_CBACK    *p_cback;
-    tBTA_GATTC          cb_data;
-    tBTA_GATTC_RCB      *p_clreg;
-
-
-    APPL_TRACE_DEBUG1("bta_gattc_int_deregister_cmpl client_if=%d", client_if );
-
-    if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
-    {
-        p_cback = p_clreg->p_cback;
-        GATT_Deregister(client_if);
-        memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
-        cb_data.reg_oper.client_if = client_if;
-        cb_data.reg_oper.status    = BTA_GATT_OK;
-
-        if (p_cback)
-            /* callback with de-register event */
-            (*p_cback)(BTA_GATTC_DEREG_EVT,  (tBTA_GATTC *)&cb_data);
-    }
-    else
-    {
-        APPL_TRACE_ERROR1("bta_gattc_int_deregister Deregister Failed, unknown client_if: %d", p_data->int_dereg.client_if);
-    }
-}
-/*******************************************************************************
-**
 ** Function         bta_gattc_deregister
 **
 ** Description      De-Register a GATT client application with BTA.
@@ -267,14 +251,30 @@ void bta_gattc_int_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
 ** Returns          void
 **
 *******************************************************************************/
-void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
+void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB  *p_clreg)
 {
-    tBTA_GATTC_RCB      *p_clreg;
     UINT8               i;
     BT_HDR              buf;
 
-    if ((p_clreg = bta_gattc_cl_get_regcb(p_data->api_dereg.client_if)) != NULL)
+    if (p_clreg != NULL)
     {
+        /* remove bg connection associated with this rcb */
+        for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++)
+        {
+            if (p_cb->bg_track[i].in_use)
+            {
+                if (p_cb->bg_track[i].cif_mask & (1 <<(p_clreg->client_if - 1)))
+                {
+                    bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, FALSE);
+                    GATT_CancelConnect(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE);
+                }
+                if (p_cb->bg_track[i].cif_adv_mask & (1 <<(p_clreg->client_if - 1)))
+                {
+                    bta_gattc_mark_bg_conn(p_clreg->client_if, p_cb->bg_track[i].remote_bda, FALSE, TRUE);
+                }
+            }
+        }
+
         if (p_clreg->num_clcb > 0)
         {
             /* close all CLCB related to this app */
@@ -291,11 +291,11 @@ void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
             }
         }
         else
-            bta_gattc_deregister_cmpl(p_clreg, p_clreg->client_if);
+            bta_gattc_deregister_cmpl(p_clreg);
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_gattc_deregister Deregister Failed, unknown client_if: %d", p_data->api_dereg.client_if);
+        APPL_TRACE_ERROR0("bta_gattc_deregister Deregister Failedm unknown client cif");
     }
 }
 /*******************************************************************************
@@ -417,7 +417,7 @@ void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
     APPL_TRACE_ERROR0("Connection already opened. wrong state");
 
     bta_gattc_send_open_cback(p_clcb->p_rcb,
-                              BTA_GATT_ALREADY_OPEN,
+                              BTA_GATT_OK,
                               p_clcb->bda,
                               p_clcb->bta_conn_id);
 }
@@ -432,7 +432,11 @@ void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 *******************************************************************************/
 void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 {
-    bta_gattc_open_error(p_clcb, p_data);
+    bta_gattc_send_open_cback(p_clcb->p_rcb,
+                              BTA_GATT_ERROR,
+                              p_clcb->bda,
+                              p_clcb->bta_conn_id);
+
     /* open failure, remove clcb */
     bta_gattc_clcb_dealloc(p_clcb);
 }
@@ -702,22 +706,22 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 
     APPL_TRACE_DEBUG1("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id);
 
-    if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT)
-        p_clcb->status = GATT_Disconnect(p_clcb->bta_conn_id);
-
     cb_data.close.client_if = p_clcb->p_rcb->client_if;
     cb_data.close.conn_id   = p_clcb->bta_conn_id;
-    cb_data.close.status    = p_clcb->status;
     cb_data.close.reason    = p_clcb->reason;
+    cb_data.close.status    = p_clcb->status;
     bdcpy(cb_data.close.remote_bda, p_clcb->bda);
 
     bta_gattc_clcb_dealloc(p_clcb);
 
+    if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT)
+        cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
+
     ( * p_cback)(BTA_GATTC_CLOSE_EVT,   (tBTA_GATTC *)&cb_data);
 
     if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending)
     {
-        bta_gattc_deregister_cmpl(p_clreg, p_clreg->client_if);
+        bta_gattc_deregister_cmpl(p_clreg);
     }
 }
 /*******************************************************************************
@@ -1494,7 +1498,7 @@ void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
     {
         p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
         p_clcb->p_srcb->attr_index = 0;
-        /* cache open failure, start discovery */
+        /* cache load failure, start discovery */
         bta_gattc_start_discover(p_clcb, NULL);
     }
 }
@@ -1535,6 +1539,40 @@ void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
         APPL_TRACE_ERROR1("operation not supported at current state [%d]", p_clcb->state);
     }
 }
+
+/*******************************************************************************
+**
+** Function         bta_gattc_deregister_cmpl
+**
+** Description      De-Register a GATT client application with BTA completed.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
+{
+    tBTA_GATTC_CB       *p_cb = &bta_gattc_cb;
+    tBTA_GATTC_IF       client_if = p_clreg->client_if;
+    tBTA_GATTC          cb_data;
+    tBTA_GATTC_CBACK    *p_cback = p_clreg->p_cback;
+
+    memset(&cb_data, 0, sizeof(tBTA_GATTC));
+
+    GATT_Deregister(p_clreg->client_if);
+    memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
+
+    cb_data.reg_oper.client_if = client_if;
+    cb_data.reg_oper.status    = BTA_GATT_OK;
+
+    if (p_cback)
+        /* callback with de-register event */
+        (*p_cback)(BTA_GATTC_DEREG_EVT,  (tBTA_GATTC *)&cb_data);
+
+    if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING)
+    {
+        p_cb->state = BTA_GATTC_STATE_DISABLED;
+    }
+}
 /*******************************************************************************
 **
 ** Function         bta_gattc_conn_cback
@@ -1550,25 +1588,21 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
 {
     BT_HDR          *p_buf;
     tBTA_GATTC_CLCB *p_clcb = NULL;
-#if BLE_INCLUDED == TRUE
     UINT8           role ;
-#endif
+
     APPL_TRACE_DEBUG4("bta_gattc_conn_cback: cif = %d connected = %d conn_id = %d reaosn = 0x%04x",
                       gattc_if, connected, conn_id, reason);
 
     if (connected)
     {
-#if BLE_INCLUDED == TRUE
         role = L2CA_GetBleConnRole(bda);
 
         if (role == HCI_ROLE_SLAVE)
             bta_gattc_conn_find_alloc(bda);
-#endif
 
         /* outgoing connection : locate a logic channel */
         if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
         {
-#if BLE_INCLUDED == TRUE
             /* for a background connection or listening connection */
             if (/* L2CA_GetBleConnRole(bda)== HCI_ROLE_MASTER && */
                 bta_gattc_check_bg_conn(gattc_if, bda, role))
@@ -1576,7 +1610,6 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
                 /* allocate a new channel */
                 p_clcb = bta_gattc_clcb_alloc(gattc_if, bda);
             }
-#endif
         }
         if (p_clcb != NULL)
         {
@@ -1883,7 +1916,6 @@ static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
         return;
     }
 
-
     if ((p_buf = (tBTA_GATTC_OP_CMPL *) GKI_getbuf(len)) != NULL)
     {
         memset(p_buf, 0, len);
index 59a9544..2341aa6 100644 (file)
 #include "bta_gatt_api.h"
 #include "bta_gattc_int.h"
 
-
-/*****************************************************************************
-**  Externs
-*****************************************************************************/
-#if BTA_DYNAMIC_MEMORY == FALSE
-extern tBTA_GATTC_CB  bta_gattc_cb;
-#endif
-
 /*****************************************************************************
 **  Constants
 *****************************************************************************/
 
-static const tBTA_SYS_REG bta_gatt_reg =
+static const tBTA_SYS_REG bta_gattc_reg =
 {
     bta_gattc_hdl_event,
-    NULL        /* need a disable functino to be called when BT is disabled */
+    BTA_GATTC_Disable
 };
 
+
 /*******************************************************************************
 **
-** Function         BTA_GATTC_Init
+** Function         BTA_GATTC_Disable
 **
-** Description     This function is called to initalize GATTC module
+** Description      This function is called to disable GATTC module
 **
-** Parameters       None
+** Parameters       None.
 **
 ** Returns          None
 **
 *******************************************************************************/
-void BTA_GATTC_Init()
+void BTA_GATTC_Disable(void)
 {
-    memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
+    BT_HDR  *p_buf;
+
+    if (bta_sys_is_register(BTA_ID_GATTC) == FALSE)
+    {
+        APPL_TRACE_WARNING0("GATTC Module not enabled/already disabled");
+        return;
+    }
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_GATTC_API_DISABLE_EVT;
+        bta_sys_sendmsg(p_buf);
+    }
+    bta_sys_deregister(BTA_ID_GATTC);
+
 }
 
 /*******************************************************************************
@@ -83,10 +89,12 @@ void BTA_GATTC_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTC_CBACK *p_client_cb)
 {
     tBTA_GATTC_API_REG  *p_buf;
 
-    /* register with BTA system manager */
-    GKI_sched_lock();
-    bta_sys_register(BTA_ID_GATTC, &bta_gatt_reg);
-    GKI_sched_unlock();
+    if (bta_sys_is_register(BTA_ID_GATTC) == FALSE)
+    {
+        GKI_sched_lock();
+        bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
+        GKI_sched_unlock();
+    }
 
     if ((p_buf = (tBTA_GATTC_API_REG *) GKI_getbuf(sizeof(tBTA_GATTC_API_REG))) != NULL)
     {
index d3cff47..2228d24 100644 (file)
@@ -68,7 +68,7 @@ enum
     BTA_GATTC_INT_START_IF_EVT,
     BTA_GATTC_API_REG_EVT,
     BTA_GATTC_API_DEREG_EVT,
-    BTA_GATTC_INT_DEREG_EVT
+    BTA_GATTC_API_DISABLE_EVT
 
 };
 typedef UINT16 tBTA_GATTC_INT_EVT;
@@ -91,6 +91,7 @@ typedef UINT16 tBTA_GATTC_INT_EVT;
 
 #define BTA_GATTC_WRITE_PREPARE          GATT_WRITE_PREPARE
 
+
 /* internal strucutre for GATTC register API  */
 typedef struct
 {
@@ -363,8 +364,18 @@ typedef struct
     BD_ADDR             remote_bda;
 }tBTA_GATTC_CONN;
 
+enum
+{
+   BTA_GATTC_STATE_DISABLED,
+   BTA_GATTC_STATE_ENABLING,
+   BTA_GATTC_STATE_ENABLED,
+   BTA_GATTC_STATE_DISABLING
+};
+
 typedef struct
 {
+    UINT8             state;
+
     tBTA_GATTC_CONN     conn_track[BTA_GATTC_CONN_MAX];
     tBTA_GATTC_BG_TCK   bg_track[BTA_GATTC_KNOWN_SR_MAX];
     tBTA_GATTC_RCB      cl_rcb[BTA_GATTC_CL_MAX];
@@ -395,12 +406,12 @@ extern BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg);
 extern void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
 
 /* function processed outside SM */
+extern void bta_gattc_disable(tBTA_GATTC_CB *p_cb);
 extern void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
 extern void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
 extern void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 extern void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
-extern void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
-extern void bta_gattc_int_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
+extern void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB  *p_clreg);
 
 /* function within state machine */
 extern void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
index 01a0224..e6c6819 100644 (file)
@@ -346,12 +346,16 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
 {
     tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
     tBTA_GATTC_CLCB *p_clcb = NULL;
-
+    tBTA_GATTC_RCB      *p_clreg;
 #if BTA_GATT_DEBUG == TRUE
     APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
 #endif
     switch (p_msg->event)
     {
+        case BTA_GATTC_API_DISABLE_EVT:
+            bta_gattc_disable(p_cb);
+            break;
+
         case BTA_GATTC_API_REG_EVT:
             bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
             break;
@@ -361,11 +365,8 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
             break;
 
         case BTA_GATTC_API_DEREG_EVT:
-            bta_gattc_deregister(p_cb, (tBTA_GATTC_DATA *) p_msg);
-            break;
-
-        case BTA_GATTC_INT_DEREG_EVT:
-            bta_gattc_int_deregister(p_cb, (tBTA_GATTC_DATA *) p_msg);
+            p_clreg = bta_gattc_cl_get_regcb(((tBTA_GATTC_DATA *)p_msg)->api_dereg.client_if);
+            bta_gattc_deregister(p_cb, p_clreg);
             break;
 
         case BTA_GATTC_API_OPEN_EVT:
@@ -465,6 +466,10 @@ static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code)
             return "BTA_GATTC_API_DEREG_EVT";
         case BTA_GATTC_API_REFRESH_EVT:
             return "BTA_GATTC_API_REFRESH_EVT";
+        case BTA_GATTC_API_DISABLE_EVT:
+            return "BTA_GATTC_API_DISABLE_EVT";
+        case BTA_GATTC_API_ENABLE_EVT:
+            return "BTA_GATTC_API_ENABLE_EVT";
         default:
             return "unknown GATTC event code";
     }
index 5504df0..b22429d 100644 (file)
@@ -105,24 +105,66 @@ void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
 {
     UINT8 index=0;
     tBTA_GATTS_HNDL_RANGE handle_range;
+    tBTA_GATT_STATUS    status = BTA_GATT_OK;
 
-    p_cb->enabled = TRUE;
-
-    APPL_TRACE_DEBUG0("bta_gatts_enable");
-    while ( bta_gatts_co_load_handle_range(index, &handle_range))
+    if (p_cb->enabled)
     {
-        GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
-        memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
-        index++;
+        APPL_TRACE_DEBUG0("GATTS already enabled.");
     }
+    else
+    {
+        memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
 
-    APPL_TRACE_DEBUG1("bta_gatts_enable: num of handle range added=%d", index);
+        p_cb->enabled = TRUE;
 
-    if (!GATTS_NVRegister(&bta_gatts_nv_cback))
+        while ( bta_gatts_co_load_handle_range(index, &handle_range))
+        {
+            GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
+            memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
+            index++;
+        }
+
+        APPL_TRACE_DEBUG1("bta_gatts_enable: num of handle range added=%d", index);
+
+        if (!GATTS_NVRegister(&bta_gatts_nv_cback))
+        {
+            APPL_TRACE_ERROR0("BTA GATTS NV register failed.");
+            status = BTA_GATT_ERROR;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_gatts_api_disable
+**
+** Description      disable BTA GATTS module.
+**
+** Returns          none.
+**
+*******************************************************************************/
+void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
+{
+    UINT8 i;
+    tBTA_GATT_STATUS    status = BTA_GATT_OK;
+
+    if (p_cb->enabled)
+    {
+        for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
+        {
+            if (p_cb->rcb[i].in_use)
+            {
+                GATT_Deregister(p_cb->rcb[i].gatt_if);
+            }
+        }
+        memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
+    }
+    else
     {
-        APPL_TRACE_ERROR0("BTA GATTS NV register failed.");
+        APPL_TRACE_ERROR0("GATTS not enabled");
     }
 }
+
 /*******************************************************************************
 **
 ** Function         bta_gatts_register
@@ -139,9 +181,10 @@ void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
     tBTA_GATT_STATUS         status = BTA_GATT_OK;
     UINT8                    i, first_unuse = 0xff;
 
-    if (!p_cb->enabled)
+    if (p_cb->enabled == FALSE)
+    {
         bta_gatts_enable(p_cb);
-
+    }
 
     for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++)
     {
index d30878e..7d5d541 100644 (file)
 #include "bta_gatts_int.h"
 
 /*****************************************************************************
-**  Externs
-*****************************************************************************/
-#if BTA_DYNAMIC_MEMORY == FALSE
-extern tBTA_GATTS_CB  bta_gatts_cb;
-#endif
-
-/*****************************************************************************
 **  Constants
 *****************************************************************************/
 
 static const tBTA_SYS_REG bta_gatts_reg =
 {
     bta_gatts_hdl_event,
-    NULL        /* need a disable functino to be called when BT is disabled */
+    BTA_GATTS_Disable
 };
 
 /*******************************************************************************
 **
-** Function         BTA_GATTS_Init
+** Function         BTA_GATTS_Disable
 **
-** Description     This function is called to initalize GATTS module
+** Description      This function is called to disable GATTS module
 **
-** Parameters       None
+** Parameters       None.
 **
 ** Returns          None
 **
 *******************************************************************************/
-void BTA_GATTS_Init()
+void BTA_GATTS_Disable(void)
 {
-    memset(&bta_gatts_cb, 0, sizeof(tBTA_GATTS_CB));
+    BT_HDR  *p_buf;
+
+    if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
+    {
+        APPL_TRACE_WARNING0("GATTS Module not enabled/already disabled");
+        return;
+    }
+
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_GATTS_API_DISABLE_EVT;
+        bta_sys_sendmsg(p_buf);
+    }
+    bta_sys_deregister(BTA_ID_GATTS);
+
 }
 
 /*******************************************************************************
@@ -83,12 +90,12 @@ void BTA_GATTS_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTS_CBACK *p_cback)
     tBTA_GATTS_API_REG  *p_buf;
 
     /* register with BTA system manager */
-    GKI_sched_lock();
-    if (!bta_gatts_cb.enabled)
-    {
+   if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
+   {
+        GKI_sched_lock();
         bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
+        GKI_sched_unlock();
     }
-    GKI_sched_unlock();
 
     if ((p_buf = (tBTA_GATTS_API_REG *) GKI_getbuf(sizeof(tBTA_GATTS_API_REG))) != NULL)
     {
index 9f0ec7e..ce9553a 100644 (file)
@@ -52,8 +52,8 @@ enum
     BTA_GATTS_API_OPEN_EVT,
     BTA_GATTS_API_CANCEL_OPEN_EVT,
     BTA_GATTS_API_CLOSE_EVT,
-    BTA_GATTS_API_LISTEN_EVT
-
+    BTA_GATTS_API_LISTEN_EVT,
+    BTA_GATTS_API_DISABLE_EVT
 };
 typedef UINT16 tBTA_GATTS_INT_EVT;
 
@@ -224,6 +224,8 @@ extern tBTA_GATTS_CB *bta_gatts_cb_ptr;
 *****************************************************************************/
 extern BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg);
 
+extern void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb);
+extern void bta_gatts_api_enable(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_data);
 extern void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
 extern void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
index e2b2494..f763766 100644 (file)
@@ -67,6 +67,10 @@ BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg)
 
     switch (p_msg->event)
     {
+        case BTA_GATTS_API_DISABLE_EVT:
+            bta_gatts_api_disable(p_cb);
+            break;
+
         case BTA_GATTS_API_REG_EVT:
             bta_gatts_register(p_cb, (tBTA_GATTS_DATA *) p_msg);
             break;
index 78bdf13..a63afb3 100644 (file)
@@ -364,6 +364,9 @@ typedef union
     BD_ADDR                 remote_bda;     /* service change event */
 } tBTA_GATTC;
 
+/* GATTC enable callback function */
+typedef void (tBTA_GATTC_ENB_CBACK)(tBTA_GATT_STATUS status);
+
 /* Client callback function */
 typedef void (tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
 
@@ -547,9 +550,12 @@ typedef union
 
 }tBTA_GATTS;
 
+/* GATTS enable callback function */
+typedef void (tBTA_GATTS_ENB_CBACK)(tBTA_GATT_STATUS status);
 
 /* Server callback function */
 typedef void (tBTA_GATTS_CBACK)(tBTA_GATTS_EVT event,  tBTA_GATTS *p_data);
+
 /*****************************************************************************
 **  External Function Declarations
 *****************************************************************************/
@@ -565,16 +571,16 @@ extern "C"
 
 /*******************************************************************************
 **
-** Function         BTA_GATTC_Init
+** Function         BTA_GATTC_Disable
 **
-** Description      This function is called to initalize GATTC module
+** Description      This function is called to disable the GATTC module
 **
-** Parameters       None
+** Parameters       None.
 **
 ** Returns          None
 **
 *******************************************************************************/
-BTA_API extern void BTA_GATTC_Init();
+BTA_API extern void BTA_GATTC_Disable(void);
 
 /*******************************************************************************
 **
@@ -1017,6 +1023,19 @@ BTA_API extern void BTA_GATTC_Refresh(BD_ADDR remote_bda);
 
 /*******************************************************************************
 **
+** Function         BTA_GATTS_Disable
+**
+** Description      This function is called to disable GATTS module
+**
+** Parameters       None.
+**
+** Returns          None
+**
+*******************************************************************************/
+    BTA_API extern void BTA_GATTS_Disable(void);
+
+/*******************************************************************************
+**
 ** Function         BTA_GATTS_AppRegister
 **
 ** Description      This function is called to register application callbacks
index b5cd949..40f19d0 100644 (file)
@@ -1417,7 +1417,7 @@ bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id)
 
     btif_enabled_services |= (1 << service_id);
 
-    BTIF_TRACE_ERROR2("%s: current services:0x%x", __FUNCTION__, btif_enabled_services);
+    BTIF_TRACE_DEBUG2("%s: current services:0x%x", __FUNCTION__, btif_enabled_services);
 
     if (btif_is_enabled())
     {
@@ -1450,7 +1450,7 @@ bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id)
 
     btif_enabled_services &=  (tBTA_SERVICE_MASK)(~(1<<service_id));
 
-    BTIF_TRACE_ERROR2("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services);
+    BTIF_TRACE_DEBUG2("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services);
 
     if (btif_is_enabled())
     {
index bc01c2e..1ed5b0c 100644 (file)
@@ -58,16 +58,13 @@ extern btgatt_server_interface_t btgattServerInterface;
 **
 ** Description      Initializes the GATT interface
 **
-** Returns    s      bt_status_t
+** Returns          bt_status_t
 **
 *******************************************************************************/
 static bt_status_t btif_gatt_init( const btgatt_callbacks_t* callbacks )
 {
     bt_gatt_callbacks = callbacks;
 
-    BTA_GATTC_Init();
-    BTA_GATTS_Init();
-
     return BT_STATUS_SUCCESS;
 }
 
@@ -84,6 +81,9 @@ static void  btif_gatt_cleanup( void )
 {
     if (bt_gatt_callbacks)
         bt_gatt_callbacks = NULL;
+
+    BTA_GATTC_Disable();
+    BTA_GATTS_Disable();
 }
 
 static const btgatt_interface_t btgattInterface = {
index ef437e1..91eca96 100644 (file)
@@ -1293,6 +1293,9 @@ void GATT_Deregister (tGATT_IF gatt_if)
     }
 
     gatt_deregister_bgdev_list(gatt_if);
+    /* update the listen mode */
+    GATT_Listen(gatt_if, FALSE, NULL);
+
     memset (p_reg, 0, sizeof(tGATT_REG));
 }
 
@@ -1564,7 +1567,7 @@ BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_c
 ** Parameters       gatt_if: applicaiton interface
 **                  p_bd_addr: listen for specific address connection, or NULL for
 **                             listen to all device connection.
-**                  start: is a direct conenection or a background auto connection
+**                  start: start or stop listening.
 **
 ** Returns          TRUE if advertisement is started; FALSE if adv start failure.
 **
index 5470f4e..5b375b5 100644 (file)
@@ -2322,6 +2322,8 @@ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_init
                     p_dev->gatt_if[i] = gatt_if;
                     if (i == 0)
                         ret = BTM_BleUpdateBgConnDev(TRUE, bd_addr);
+                    else
+                        ret = TRUE;
                     break;
                 }
             }
@@ -2342,6 +2344,8 @@ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_init
 
                     if (i == 0)
                         ret = BTM_BleUpdateAdvWhitelist(TRUE, bd_addr);
+                    else
+                        ret = TRUE;
                     break;
                 }
             }
@@ -2515,26 +2519,38 @@ void gatt_deregister_bgdev_list(tGATT_IF gatt_if)
 {
     tGATT_BG_CONN_DEV    *p_dev_list = &gatt_cb.bgconn_dev[0];
     UINT8 i , j, k;
+    tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
 
+    /* update the BG conn device list */
     for (i = 0 ; i <GATT_MAX_BG_CONN_DEV; i ++, p_dev_list ++ )
     {
         if (p_dev_list->in_use)
         {
             for (j = 0; j < GATT_MAX_APPS; j ++)
             {
-                if (p_dev_list->gatt_if[j] == 0)
+                if (p_dev_list->gatt_if[j] == 0 && p_dev_list->listen_gif[j] == 0)
                     break;
-                else if (p_dev_list->gatt_if[j] == gatt_if)
+
+                if (p_dev_list->gatt_if[j] == gatt_if)
                 {
                     for (k = j + 1; k < GATT_MAX_APPS; k ++)
                         p_dev_list->gatt_if[k - 1] = p_dev_list->gatt_if[k];
 
                     if (p_dev_list->gatt_if[0] == 0)
-                    {
                         BTM_BleUpdateBgConnDev(FALSE, p_dev_list->remote_bda);
-                        memset(p_dev_list, 0, sizeof(tGATT_BG_CONN_DEV));
-                        break;
-                    }
+                }
+
+                if (p_dev_list->listen_gif[j] == gatt_if)
+                {
+                    p_dev_list->listen_gif[j] = 0;
+                    p_reg->listening --;
+
+                    /* move all element behind one forward */
+                    for (k = j + 1; k < GATT_MAX_APPS; k ++)
+                        p_dev_list->listen_gif[k - 1] = p_dev_list->listen_gif[k];
+
+                    if (p_dev_list->listen_gif[0] == 0)
+                        BTM_BleUpdateAdvWhitelist(FALSE, p_dev_list->remote_bda);
                 }
             }
         }