diff options
author | Andre Eisenbach <andre@broadcom.com> | 2013-05-15 04:55:08 -0700 |
---|---|---|
committer | Matthew Xie <mattx@google.com> | 2013-08-14 00:40:44 +0000 |
commit | e1202caae4920139ea0cfed5c51f5f76b2dc8bc4 (patch) | |
tree | 4cf11db521cf31dd8c01effc546329113fb4bf43 | |
parent | f052217962d0c06392eb79687820c9469cd6a75a (diff) | |
download | android_system_bt-e1202caae4920139ea0cfed5c51f5f76b2dc8bc4.tar.gz android_system_bt-e1202caae4920139ea0cfed5c51f5f76b2dc8bc4.tar.bz2 android_system_bt-e1202caae4920139ea0cfed5c51f5f76b2dc8bc4.zip |
LE: Add GATT disable functions
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
-rw-r--r-- | bta/dm/bta_dm_act.c | 33 | ||||
-rw-r--r-- | bta/gatt/bta_gattc_act.c | 264 | ||||
-rw-r--r-- | bta/gatt/bta_gattc_api.c | 46 | ||||
-rw-r--r-- | bta/gatt/bta_gattc_int.h | 17 | ||||
-rw-r--r-- | bta/gatt/bta_gattc_main.c | 17 | ||||
-rw-r--r-- | bta/gatt/bta_gatts_act.c | 67 | ||||
-rw-r--r-- | bta/gatt/bta_gatts_api.c | 41 | ||||
-rw-r--r-- | bta/gatt/bta_gatts_int.h | 6 | ||||
-rw-r--r-- | bta/gatt/bta_gatts_main.c | 4 | ||||
-rw-r--r-- | bta/include/bta_gatt_api.h | 27 | ||||
-rw-r--r-- | btif/src/btif_core.c | 4 | ||||
-rw-r--r-- | btif/src/btif_gatt.c | 8 | ||||
-rw-r--r-- | stack/gatt/gatt_api.c | 5 | ||||
-rw-r--r-- | stack/gatt/gatt_utils.c | 28 |
14 files changed, 370 insertions, 197 deletions
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c index 2d0cf9163..2a408f430 100644 --- a/bta/dm/bta_dm_act.c +++ b/bta/dm/bta_dm_act.c @@ -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. diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c index 8936e60dc..d6b621aee 100644 --- a/bta/gatt/bta_gattc_act.c +++ b/bta/gatt/bta_gattc_act.c @@ -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); diff --git a/bta/gatt/bta_gattc_api.c b/bta/gatt/bta_gattc_api.c index 59a9544d4..2341aa691 100644 --- a/bta/gatt/bta_gattc_api.c +++ b/bta/gatt/bta_gattc_api.c @@ -32,38 +32,44 @@ #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) { diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h index d3cff47ea..2228d2467 100644 --- a/bta/gatt/bta_gattc_int.h +++ b/bta/gatt/bta_gattc_int.h @@ -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); diff --git a/bta/gatt/bta_gattc_main.c b/bta/gatt/bta_gattc_main.c index 01a0224ce..e6c6819c3 100644 --- a/bta/gatt/bta_gattc_main.c +++ b/bta/gatt/bta_gattc_main.c @@ -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"; } diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c index 5504df0b6..b22429d80 100644 --- a/bta/gatt/bta_gatts_act.c +++ b/bta/gatt/bta_gatts_act.c @@ -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 ++) { diff --git a/bta/gatt/bta_gatts_api.c b/bta/gatt/bta_gatts_api.c index d30878e61..7d5d541f5 100644 --- a/bta/gatt/bta_gatts_api.c +++ b/bta/gatt/bta_gatts_api.c @@ -33,36 +33,43 @@ #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) { diff --git a/bta/gatt/bta_gatts_int.h b/bta/gatt/bta_gatts_int.h index 9f0ec7e2f..ce9553a56 100644 --- a/bta/gatt/bta_gatts_int.h +++ b/bta/gatt/bta_gatts_int.h @@ -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); diff --git a/bta/gatt/bta_gatts_main.c b/bta/gatt/bta_gatts_main.c index e2b2494f9..f7637661c 100644 --- a/bta/gatt/bta_gatts_main.c +++ b/bta/gatt/bta_gatts_main.c @@ -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; diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h index 78bdf134a..a63afb3bd 100644 --- a/bta/include/bta_gatt_api.h +++ b/bta/include/bta_gatt_api.h @@ -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 diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c index b5cd94911..40f19d076 100644 --- a/btif/src/btif_core.c +++ b/btif/src/btif_core.c @@ -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()) { diff --git a/btif/src/btif_gatt.c b/btif/src/btif_gatt.c index bc01c2ec5..1ed5b0ce6 100644 --- a/btif/src/btif_gatt.c +++ b/btif/src/btif_gatt.c @@ -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 = { diff --git a/stack/gatt/gatt_api.c b/stack/gatt/gatt_api.c index ef437e130..91eca96fc 100644 --- a/stack/gatt/gatt_api.c +++ b/stack/gatt/gatt_api.c @@ -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. ** diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c index 5470f4ef8..5b375b54f 100644 --- a/stack/gatt/gatt_utils.c +++ b/stack/gatt/gatt_utils.c @@ -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); } } } |