Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 095e7dc1 authored by Andre Eisenbach's avatar Andre Eisenbach Committed by Matthew Xie
Browse files

LE fixes

- Null pointer exception check added.

An exception occurs at the memcpy in the bta_dm_gatt_disc_result.
User removed the battery on Ble device(Smart Nudge) during bonding
and connection. This exception occurs sometimes.
I used Broadcom LE Explorer to reproduce it.

- Fixed disconnect and encryption behaviour

Disconnect will now disconnect the physical link immediately when no
other application is interested in the device anymore. Also, the
connection to a remote device is now dropped if encryption fails.

- Deep copy buffers when transfering context

Certain BTA server event types require a deep copy of the request
data buffers when transfering context. Shallow copy of the pointers
involved may cause a crash when overlapping read and write requests
are received.

- 2nd encryption has not started

need to send encryption complete callback
when the encryption fail due to link drop without a complete event.
Otherwise BTA layer would not be able to clean up the status,
and no further encryption can be started.

Change-Id: If93e0a188e8779830c8991e4193b96dc95e23e5d
parent 08b9a225
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -4978,10 +4978,17 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
    {
        APPL_TRACE_DEBUG3("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x", service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used);

        if(bta_dm_search_cb.p_ble_rawdata)
        {
            memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
                   sizeof(service_id) );

            bta_dm_search_cb.ble_raw_used += sizeof(service_id);
        }
        else
        {
            APPL_TRACE_ERROR0("p_ble_rawdata is NULL");
        }

    }
    else
+1 −4
Original line number Diff line number Diff line
@@ -712,10 +712,7 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
    cb_data.close.reason    = p_clcb->reason;
    bdcpy(cb_data.close.remote_bda, p_clcb->bda);

    if (p_clcb->status == BTA_GATT_OK)
    {
    bta_gattc_clcb_dealloc(p_clcb);
    }

    ( * p_cback)(BTA_GATTC_CLOSE_EVT,   (tBTA_GATTC *)&cb_data);

+11 −13
Original line number Diff line number Diff line
@@ -470,8 +470,6 @@ tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p

        if (param.s_handle > param.e_handle)
        {
            APPL_TRACE_ERROR2("discover range invalid: [0x%04x ~ 0x%04x]", param.s_handle, param.e_handle);

            return GATT_ERROR;
        }
    }
@@ -489,8 +487,6 @@ tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p
*******************************************************************************/
tBTA_GATT_STATUS bta_gattc_start_disc_include_srvc(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
{
    APPL_TRACE_DEBUG0("starting discovery included service");

    return bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_INC_SRVC);
}
/*******************************************************************************
@@ -506,8 +502,6 @@ tBTA_GATT_STATUS bta_gattc_start_disc_char(UINT16 conn_id, tBTA_GATTC_SERV *p_sr
{
    p_srvc_cb->total_char = 0;

    APPL_TRACE_DEBUG0("starting discover characteristics");

    return bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_CHAR);
}
/*******************************************************************************
@@ -606,8 +600,6 @@ static void bta_gattc_char_disc_cmpl(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
{
    tBTA_GATTC_ATTR_REC *p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->cur_char_idx;

    APPL_TRACE_DEBUG1("Total %d Char found ", p_srvc_cb->total_char);

    /* if there are characteristic needs to be explored */
    if (p_srvc_cb->total_char > 0)
    {
@@ -709,7 +701,7 @@ static tBTA_GATT_STATUS bta_gattc_add_srvc_to_list(tBTA_GATTC_SERV *p_srvc_cb,
    tBTA_GATTC_ATTR_REC *p_rec = NULL;
    tBTA_GATT_STATUS    status = BTA_GATT_OK;

    if (p_srvc_cb->next_avail_idx < BTA_GATTC_MAX_CACHE_CHAR)
    if (p_srvc_cb->p_srvc_list && p_srvc_cb->next_avail_idx < BTA_GATTC_MAX_CACHE_CHAR)
    {
        p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->next_avail_idx;

@@ -731,7 +723,7 @@ static tBTA_GATT_STATUS bta_gattc_add_srvc_to_list(tBTA_GATTC_SERV *p_srvc_cb,
    {   /* allocate bigger buffer ?? */
        status = GATT_DB_FULL;

        APPL_TRACE_ERROR0("char not added, no resources");
        APPL_TRACE_ERROR0("service not added, no resources or wrong state");
    }
    return status;
}
@@ -913,10 +905,11 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
{
    tBTA_GATTC_SERV * p_srvc_cb = NULL;
    BOOLEAN          pri_srvc;
    tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);

    p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id);

    if (p_srvc_cb != NULL)
    if (p_srvc_cb != NULL && p_clcb != NULL && p_clcb->state == BTA_GATTC_DISCOVER_ST)
    {
        switch (disc_type)
        {
@@ -981,6 +974,7 @@ void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT

    if ( p_clcb && (status != GATT_SUCCESS || p_clcb->status != GATT_SUCCESS) )
    {
        if (p_clcb->status == GATT_SUCCESS)
            p_clcb->status = status;
        bta_gattc_sm_execute(p_clcb, BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
        return;
@@ -1080,7 +1074,7 @@ UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service
                        if (bta_gattc_uuid_compare(descr_uuid, attr_uuid, TRUE))
                        {
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
                            APPL_TRACE_DEBUG0("found descripotor!!");
                            APPL_TRACE_DEBUG0("found descriptor!!");
#endif
                            handle = p_attr->attr_handle;
                            done = TRUE;
@@ -1335,7 +1329,9 @@ static tBTA_GATT_STATUS bta_gattc_find_record(tBTA_GATTC_SERV *p_srcb,
                            attr_type == p_attr->attr_type)
                        {

#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
                            APPL_TRACE_DEBUG0("found char handle mapping characteristic");
#endif
                            p_result->inst_id = p_attr->inst_id;

                            if (p_param != NULL)
@@ -1354,10 +1350,12 @@ static tBTA_GATT_STATUS bta_gattc_find_record(tBTA_GATTC_SERV *p_srcb,
                }
                p_attr = p_attr->p_next;
            }
#if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
            if (status)
            {
                APPL_TRACE_ERROR0("In the given service, can not find matching record");
            }
#endif
            break;
        }

+1 −2
Original line number Diff line number Diff line
@@ -2256,9 +2256,8 @@ static void btif_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
        /*Map the HCI fail reason  to  bt status  */
        switch (p_auth_cmpl->fail_reason)
        {

            btif_dm_remove_ble_bonding_keys();
            default:
                btif_dm_remove_ble_bonding_keys();
                status =  BT_STATUS_FAIL;
                break;
        }
+52 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@

#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))

#include "gki.h"
#include "bta_api.h"
#include "bta_gatt_api.h"
#include "bd.h"
@@ -116,6 +117,54 @@ extern const btgatt_callbacks_t *bt_gatt_callbacks;
**  Static functions
************************************************************************************/

static void btapp_gatts_copy_req_data(UINT16 event, char *p_dest, char *p_src)
{
    tBTA_GATTS *p_dest_data = (tBTA_GATTS*) p_dest;
    tBTA_GATTS *p_src_data = (tBTA_GATTS*) p_src;

    if (!p_src_data || !p_dest_data)
        return;

    // Copy basic structure first
    memcpy(p_dest_data, p_src_data, sizeof(tBTA_GATTS));

    // Allocate buffer for request data if necessary
    switch (event)
    {
        case BTA_GATTS_READ_EVT:
        case BTA_GATTS_WRITE_EVT:
        case BTA_GATTS_EXEC_WRITE_EVT:
        case BTA_GATTS_MTU_EVT:
            p_dest_data->req_data.p_data = GKI_getbuf(sizeof(tBTA_GATTS_REQ_DATA));
            if (p_dest_data->req_data.p_data != NULL)
            {
                memcpy(p_dest_data->req_data.p_data, p_src_data->req_data.p_data,
                    sizeof(tBTA_GATTS_REQ_DATA));
            }
            break;

        default:
            break;
    }
}

static void btapp_gatts_free_req_data(UINT16 event, tBTA_GATTS *p_data)
{
    switch (event)
    {
        case BTA_GATTS_READ_EVT:
        case BTA_GATTS_WRITE_EVT:
        case BTA_GATTS_EXEC_WRITE_EVT:
        case BTA_GATTS_MTU_EVT:
            if (p_data && p_data->req_data.p_data)
                GKI_freebuf(p_data->req_data.p_data);
            break;

        default:
            break;
    }
}

static void btapp_gatts_handle_cback(uint16_t event, char* p_param)
{
    ALOGD("%s: Event %d", __FUNCTION__, event);
@@ -284,13 +333,15 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param)
            ALOGE("%s: Unhandled event (%d)!", __FUNCTION__, event);
            break;
    }

    btapp_gatts_free_req_data(event, p_data);
}

static void btapp_gatts_cback(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
{
    bt_status_t status;
    status = btif_transfer_context(btapp_gatts_handle_cback, (uint16_t) event,
        (void*)p_data, sizeof(tBTA_GATTS), NULL);
        (void*)p_data, sizeof(tBTA_GATTS), btapp_gatts_copy_req_data);
    ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}

Loading