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

Commit ca21f0ce authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Eliminate recursive calling when handling GATT related errors

If there are errors when processing GATT related events (e.g.,
configuring the MTU), don't use recursive calls into
bta_gattc_sm_execute(), because it breaks the free-ing of some
of the memory.

Bug: 23756301
Change-Id: I3c685170e868ffbf4e488d2bb5a31904e3f7b39d
parent 6a08e85a
Loading
Loading
Loading
Loading
+48 −44
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@ 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_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
                                   tBTA_GATT_STATUS status,
                                   tGATT_CL_COMPLETE *p_data);

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);
@@ -933,7 +936,6 @@ void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data
*******************************************************************************/
void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
    tBTA_GATTC_OP_CMPL  op_cmpl;
    tBTA_GATT_STATUS    status;

    if (bta_gattc_enqueue(p_clcb, p_data))
@@ -943,13 +945,11 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
        /* if failed, return callback here */
        if (status != GATT_SUCCESS && status != GATT_CMD_STARTED)
        {
            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));

            op_cmpl.status  = status;
            op_cmpl.op_code = GATTC_OPTYPE_CONFIG;
            op_cmpl.p_cmpl  = NULL;
            /* Dequeue the data, if it was enqueued */
            if (p_clcb->p_q_cmd == p_data)
                p_clcb->p_q_cmd = NULL;

            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
            bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, status, NULL);
        }
    }
}
@@ -1091,10 +1091,9 @@ void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
    UINT16 handle = 0;
    tGATT_READ_PARAM    read_param;
    tBTA_GATTC_OP_CMPL  op_cmpl;
    tBTA_GATT_STATUS    status;

    memset (&read_param, 0 ,sizeof(tGATT_READ_PARAM));
    memset (&op_cmpl, 0 ,sizeof(tBTA_GATTC_OP_CMPL));

    if (bta_gattc_enqueue(p_clcb, p_data))
    {
@@ -1103,23 +1102,24 @@ void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
                                          &p_data->api_read.char_id,
                                          p_data->api_read.p_descr_type)) == 0)
        {
            op_cmpl.status = BTA_GATT_ERROR;
            status = BTA_GATT_ERROR;
        }
        else
        {
            read_param.by_handle.handle = handle;
            read_param.by_handle.auth_req = p_data->api_read.auth_req;

            op_cmpl.status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
            status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_HANDLE, &read_param);
        }

        /* read fail */
        if (op_cmpl.status != BTA_GATT_OK)
        if (status != BTA_GATT_OK)
        {
            op_cmpl.op_code = GATTC_OPTYPE_READ;
            op_cmpl.p_cmpl = NULL;
            /* Dequeue the data, if it was enqueued */
            if (p_clcb->p_q_cmd == p_data)
                p_clcb->p_q_cmd = NULL;

            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
            bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
        }
    }
}
@@ -1136,7 +1136,6 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
    UINT16              i, handle;
    tBTA_GATT_STATUS    status = BTA_GATT_OK;
    tGATT_READ_PARAM    read_param;
    tBTA_GATTC_OP_CMPL  op_cmpl;
    tBTA_GATTC_ATTR_ID  *p_id;

    if (bta_gattc_enqueue(p_clcb, p_data))
@@ -1185,13 +1184,11 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
        /* read fail */
        if (status != BTA_GATT_OK)
        {
            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));

            op_cmpl.status  = status;
            op_cmpl.op_code = GATTC_OPTYPE_READ;
            op_cmpl.p_cmpl  = NULL;
            /* Dequeue the data, if it was enqueued */
            if (p_clcb->p_q_cmd == p_data)
                p_clcb->p_q_cmd = NULL;

            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
            bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL);
        }
    }
}
@@ -1208,7 +1205,6 @@ void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
    UINT16              handle = 0;
    tGATT_VALUE         attr = {0};
    tBTA_GATTC_OP_CMPL  op_cmpl;
    tBTA_GATT_STATUS    status = BTA_GATT_OK;

    if (bta_gattc_enqueue(p_clcb, p_data))
@@ -1236,13 +1232,11 @@ void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
        /* write fail */
        if (status != BTA_GATT_OK)
        {
            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));

            op_cmpl.status  = status;
            op_cmpl.op_code = GATTC_OPTYPE_WRITE;
            op_cmpl.p_cmpl  = NULL;
            /* Dequeue the data, if it was enqueued */
            if (p_clcb->p_q_cmd == p_data)
                p_clcb->p_q_cmd = NULL;

            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
            bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_WRITE, status, NULL);
        }
    }
}
@@ -1256,7 +1250,6 @@ void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
*********************************************************************************/
void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
    tBTA_GATTC_OP_CMPL  op_cmpl;
    tBTA_GATT_STATUS    status;

    if (bta_gattc_enqueue(p_clcb, p_data))
@@ -1265,13 +1258,11 @@ void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)

        if (status != BTA_GATT_OK)
        {
            memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));

            op_cmpl.status  = status;
            op_cmpl.op_code = GATTC_OPTYPE_EXE_WRITE;
            op_cmpl.p_cmpl  = NULL;
            /* Dequeue the data, if it was enqueued */
            if (p_clcb->p_q_cmd == p_data)
                p_clcb->p_q_cmd = NULL;

            bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
            bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_EXE_WRITE, status, NULL);
        }
    }
}
@@ -1798,7 +1789,6 @@ static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
/*******************************************************************************
**
** Function         bta_gattc_conn_cback
**                  bta_gattc_cmpl_cback
**
** Description      callback functions to GATT client stack.
**
@@ -2138,9 +2128,6 @@ static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
                                  tGATT_CL_COMPLETE *p_data)
{
    tBTA_GATTC_CLCB     *p_clcb;
    tBTA_GATTC_OP_CMPL  *p_buf;
    UINT16              len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);

    APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
                      conn_id, op, status);

@@ -2164,7 +2151,26 @@ static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
        bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
    }

    if ((p_buf = (tBTA_GATTC_OP_CMPL *) GKI_getbuf(len)) != NULL)
    bta_gattc_cmpl_sendmsg(conn_id, op, status, p_data);
}

/*******************************************************************************
**
** Function         bta_gattc_cmpl_sendmsg
**
** Description      client operation complete send message
**
** Returns          None.
**
*******************************************************************************/
static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
                                   tBTA_GATT_STATUS status,
                                   tGATT_CL_COMPLETE *p_data)
{
    const UINT16         len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
    tBTA_GATTC_OP_CMPL  *p_buf = (tBTA_GATTC_OP_CMPL *) GKI_getbuf(len);

    if (p_buf != NULL)
    {
        memset(p_buf, 0, len);
        p_buf->hdr.event = BTA_GATTC_OP_CMPL_EVT;
@@ -2180,8 +2186,6 @@ static void bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS

        bta_sys_sendmsg(p_buf);
    }

    return;
}

/*******************************************************************************