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

Commit 6456cf60 authored by Zhihai Xu's avatar Zhihai Xu
Browse files

BLE HID device connection failure due to security error.

When HID BLE device start encryption, if some other GATT application
already start encryption(but not finished yet) by calling
gatt_security_check_start. The HID BLE device will be failed to start
encryption, which will cause it to disconnect the BLE HID connection.
The solution is to check whether we already started the encryption
, If the encryption is already started, wait until the encryption
finished, then continue to start security check for BLE HID device.
add encrytion complete event to notify all GATT client encryption done.
filter the event just for BTA HH LE GATT client.

bug:11636246
Change-Id: If58e57c623cc8cfa05208587b010bec68c71306c
parent 29299953
Loading
Loading
Loading
Loading
+76 −1
Original line number Diff line number Diff line
@@ -52,13 +52,16 @@ static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS

static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);

static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);

static tGATT_CBACK bta_gattc_cl_cback =
{
    bta_gattc_conn_cback,
    bta_gattc_cmpl_cback,
    bta_gattc_disc_res_cback,
    bta_gattc_disc_cmpl_cback,
    NULL
    NULL,
    bta_gattc_enc_cmpl_cback
};

/* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
@@ -399,6 +402,34 @@ void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p

    }
}

/*******************************************************************************
**
** Function         bta_gattc_process_enc_cmpl
**
** Description      process encryption complete message.
**
** Returns          void
**
*******************************************************************************/
void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
{
    tBTA_GATTC_RCB *p_clreg;
    tBTA_GATTC cb_data;

    p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);

    if (p_clreg && p_clreg->p_cback)
    {
        memset(&cb_data, 0, sizeof(tBTA_GATTC));

        cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
        bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);

        (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
    }
}

/*******************************************************************************
**
** Function         bta_gattc_cancel_open_error
@@ -1633,6 +1664,50 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
            }
        }

/*******************************************************************************
**
** Function         bta_gattc_enc_cmpl_cback
**
** Description      encryption complete callback function to GATT client stack.
**
** Returns          void
**
*******************************************************************************/
static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
{
    tBTA_GATTC_DATA *p_buf;
    tBTA_GATTC_CLCB *p_clcb = NULL;

    if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
    {
        return;
    }

#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
    /* filter this event just for BTA HH LE GATT client,
       In the future, if we want to enable encryption complete event
       for all GATT clients, we can remove this code */
    if (!bta_hh_le_is_hh_gatt_if(gattc_if))
    {
        return;
    }
#endif

    APPL_TRACE_DEBUG1("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);

    if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
    {
        memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));

        p_buf->enc_cmpl.hdr.event            = BTA_GATTC_ENC_CMPL_EVT;
        p_buf->enc_cmpl.hdr.layer_specific   = p_clcb->bta_conn_id;
        p_buf->enc_cmpl.client_if            = gattc_if;
        bdcpy(p_buf->enc_cmpl.remote_bda, bda);

        bta_sys_sendmsg(p_buf);
    }
}

/*******************************************************************************
**
** Function         bta_gattc_process_api_refresh
+11 −1
Original line number Diff line number Diff line
@@ -69,7 +69,8 @@ enum
    BTA_GATTC_API_REG_EVT,
    BTA_GATTC_API_DEREG_EVT,
    BTA_GATTC_API_LISTEN_EVT,
    BTA_GATTC_API_DISABLE_EVT
    BTA_GATTC_API_DISABLE_EVT,
    BTA_GATTC_ENC_CMPL_EVT
};
typedef UINT16 tBTA_GATTC_INT_EVT;

@@ -195,6 +196,13 @@ typedef struct
    tGATT_DISCONN_REASON    reason;
}tBTA_GATTC_INT_CONN;

typedef struct
{
    BT_HDR                  hdr;
    BD_ADDR                 remote_bda;
    tBTA_GATTC_IF           client_if;
}tBTA_GATTC_ENC_CMPL;

typedef union
{
    BT_HDR                      hdr;
@@ -213,6 +221,7 @@ typedef union
    tBTA_GATTC_CI_EVT           ci_save;
    tBTA_GATTC_CI_LOAD          ci_load;
    tBTA_GATTC_INT_CONN         int_conn;
    tBTA_GATTC_ENC_CMPL         enc_cmpl;

    tBTA_GATTC_INT_START_IF     int_start_if;
    tBTA_GATTC_INT_DEREG        int_dereg;
@@ -433,6 +442,7 @@ 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_RCB  *p_clreg);
extern void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);

/* function within state machine */
extern void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
+5 −0
Original line number Diff line number Diff line
@@ -386,6 +386,11 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
            bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;
#endif

        case BTA_GATTC_ENC_CMPL_EVT:
            bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        default:
            if (p_msg->event == BTA_GATTC_INT_CONN_EVT)
                p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
+2 −1
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ static tGATT_CBACK bta_gatts_cback =
    NULL,
    NULL,
    NULL,
    bta_gatts_send_request_cback
    bta_gatts_send_request_cback,
    NULL
};

tGATT_APPL_INFO bta_gatts_nv_cback =
+4 −1
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ enum
    BTA_HH_GATT_READ_DESCR_CMPL_EVT,
    BTA_HH_GATT_WRITE_DESCR_CMPL_EVT,
    BTA_HH_API_SCPP_UPDATE_EVT,
    BTA_HH_GATT_ENC_CMPL_EVT,
#endif

    /* not handled by execute state machine */
@@ -182,6 +183,7 @@ typedef union
    tBTA_HH_LE_CLOSE         le_close;
    tBTA_GATTC_OPEN          le_open;
    tBTA_HH_SCPP_UPDATE      le_scpp_update;
    tBTA_GATTC_ENC_CMPL_CB   le_enc_cmpl;
#endif
} tBTA_HH_DATA;

@@ -283,6 +285,7 @@ typedef struct
    UINT8               scps_notify;   /* scan refresh supported/notification enabled */
#endif

    BOOLEAN             security_pending;
} tBTA_HH_DEV_CB;

/* key board parsing control block */
@@ -404,7 +407,7 @@ extern void bta_hh_le_write_char_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
extern void bta_hh_security_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
extern void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);

extern void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);

#if BTA_HH_DEBUG
extern void bta_hh_trace_dev_db(void);
Loading