<commit_before>/******************************************************************************
 *
 *  Copyright (C) 2008-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  this file contains the main ATT functions
 *
 ******************************************************************************/

#include "common/bt_target.h"

#if BLE_INCLUDED == TRUE

#include "gatt_int.h"
#include "stack/l2c_api.h"
#include "btm_int.h"
#include "btm_ble_int.h"
#include "osi/allocator.h"

/* Configuration flags. */
#define GATT_L2C_CFG_IND_DONE   (1<<0)
#define GATT_L2C_CFG_CFM_DONE   (1<<1)

/* minimum GATT MTU size over BR/EDR link
*/
#define GATT_MIN_BR_MTU_SIZE       48

/********************************************************************************/
/*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
/********************************************************************************/
static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected,
                                   UINT16 reason, tBT_TRANSPORT transport);
static void gatt_le_data_ind (UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf);
static void gatt_le_cong_cback(BD_ADDR remote_bda, BOOLEAN congest);
#if (CLASSIC_BT_INCLUDED == TRUE)
static void gatt_l2cif_connect_ind_cback (BD_ADDR  bd_addr, UINT16 l2cap_cid,
        UINT16 psm, UINT8 l2cap_id);
static void gatt_l2cif_connect_cfm_cback (UINT16 l2cap_cid, UINT16 result);
static void gatt_l2cif_config_ind_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
static void gatt_l2cif_config_cfm_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
static void gatt_l2cif_disconnect_ind_cback (UINT16 l2cap_cid, BOOLEAN ack_needed);
static void gatt_l2cif_disconnect_cfm_cback (UINT16 l2cap_cid, UINT16 result);
static void gatt_l2cif_data_ind_cback (UINT16 l2cap_cid, BT_HDR *p_msg);
#endif  ///CLASSIC_BT_INCLUDED == TRUE
static void gatt_send_conn_cback (tGATT_TCB *p_tcb);
#if (CLASSIC_BT_INCLUDED == TRUE)
static void gatt_l2cif_congest_cback (UINT16 cid, BOOLEAN congested);
static const tL2CAP_APPL_INFO dyn_info = {
    gatt_l2cif_connect_ind_cback,
    gatt_l2cif_connect_cfm_cback,
    NULL,
    gatt_l2cif_config_ind_cback,
    gatt_l2cif_config_cfm_cback,
    gatt_l2cif_disconnect_ind_cback,
    gatt_l2cif_disconnect_cfm_cback,
    NULL,
    gatt_l2cif_data_ind_cback,
    gatt_l2cif_congest_cback,
    NULL
} ;
#endif  ///SMP_INCLUDED == TRUE

#if GATT_DYNAMIC_MEMORY == FALSE
tGATT_CB  gatt_cb;
#else
tGATT_CB  *gatt_cb_ptr;
#endif

tGATT_DEFAULT gatt_default;

/*******************************************************************************
**
** Function         gatt_init
**
** Description      This function is enable the GATT profile on the device.
**                  It clears out the control blocks, and registers with L2CAP.
**
** Returns          void
**
*******************************************************************************/
void gatt_init (void)
{
    tL2CAP_FIXED_CHNL_REG  fixed_reg;
#if GATT_DYNAMIC_MEMORY
    gatt_cb_ptr = (tGATT_CB *)osi_malloc(sizeof(tGATT_CB));
#endif /* #if GATT_DYNAMIC_MEMORY */
    memset (&gatt_cb, 0, sizeof(tGATT_CB));
    memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));

#if defined(GATT_INITIAL_TRACE_LEVEL)
    gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL;
#else
    gatt_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
#endif
    gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE;
    gatt_cb.sign_op_queue = fixed_queue_new(QUEUE_SIZE_MAX);
    gatt_cb.srv_chg_clt_q = fixed_queue_new(QUEUE_SIZE_MAX);
    gatt_cb.pending_new_srv_start_q = fixed_queue_new(QUEUE_SIZE_MAX);
    /* First, register fixed L2CAP channel for ATT over BLE */
    fixed_reg.fixed_chnl_opts.mode         = L2CAP_FCR_BASIC_MODE;
    fixed_reg.fixed_chnl_opts.max_transmit = 0xFF;
    fixed_reg.fixed_chnl_opts.rtrans_tout  = 2000;
    fixed_reg.fixed_chnl_opts.mon_tout     = 12000;
    fixed_reg.fixed_chnl_opts.mps          = 670;
    fixed_reg.fixed_chnl_opts.tx_win_sz    = 1;

    fixed_reg.pL2CA_FixedConn_Cb = gatt_le_connect_cback;
    fixed_reg.pL2CA_FixedData_Cb = gatt_le_data_ind;
    fixed_reg.pL2CA_FixedCong_Cb = gatt_le_cong_cback;      /* congestion callback */
    fixed_reg.default_idle_tout  = 0xffff;                  /* 0xffff default idle timeout */

    L2CA_RegisterFixedChannel (L2CAP_ATT_CID, &fixed_reg);
#if (CLASSIC_BT_INCLUDED == TRUE)
    /* Now, register with L2CAP for ATT PSM over BR/EDR */
    if (!L2CA_Register (BT_PSM_ATT, (tL2CAP_APPL_INFO *) &dyn_info)) {
        GATT_TRACE_ERROR ("ATT Dynamic Registration failed");
    }
#endif  ///CLASSIC_BT_INCLUDED == TRUE
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);

    gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE;
    gatt_cb.hdl_cfg.gap_start_hdl  = GATT_GAP_START_HANDLE;
    gatt_cb.hdl_cfg.app_start_hdl  = GATT_APP_START_HANDLE;
#if (GATTS_INCLUDED == TRUE)
    gatt_profile_db_init();
#endif  ///GATTS_INCLUDED == TRUE
    //init local MTU size
    gatt_default.local_mtu = GATT_MAX_MTU_SIZE;
}


/*******************************************************************************
**
** Function         gatt_free
**
** Description      This function frees resources used by the GATT profile.
**
** Returns          void
**
*******************************************************************************/
#if (GATT_INCLUDED == TRUE)
void gatt_free(void)
{
    int i;
    GATT_TRACE_DEBUG("gatt_free()");
    fixed_queue_free(gatt_cb.sign_op_queue, NULL);
    gatt_cb.sign_op_queue = NULL;
    fixed_queue_free(gatt_cb.srv_chg_clt_q, NULL);
    gatt_cb.srv_chg_clt_q = NULL;
    fixed_queue_free(gatt_cb.pending_new_srv_start_q, NULL);
    gatt_cb.pending_new_srv_start_q = NULL;

    for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++)
    {
        fixed_queue_free(gatt_cb.tcb[i].pending_enc_clcb, NULL);
        gatt_cb.tcb[i].pending_enc_clcb = NULL;

        fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
        gatt_cb.tcb[i].pending_ind_q = NULL;

        btu_free_timer(&gatt_cb.tcb[i].conf_timer_ent);
        memset(&gatt_cb.tcb[i].conf_timer_ent, 0, sizeof(TIMER_LIST_ENT));

        btu_free_timer(&gatt_cb.tcb[i].ind_ack_timer_ent);
        memset(&gatt_cb.tcb[i].ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT));

#if (GATTS_INCLUDED == TRUE)
        fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL);
        gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL;
#endif /* #if (GATTS_INCLUDED == TRUE) */
    }

#if (GATTS_INCLUDED == TRUE)
    for (i = 0; i < GATT_MAX_SR_PROFILES; i++) {
        gatt_free_hdl_buffer(&gatt_cb.hdl_list[i]);
    }
#endif /* #if (GATTS_INCLUDED == TRUE) */
#if GATT_DYNAMIC_MEMORY
    FREE_AND_RESET(gatt_cb_ptr);
#endif /* #if GATT_DYNAMIC_MEMORY */
}
#endif  ///GATTS_INCLUDED == TRUE

/*******************************************************************************
**
** Function         gatt_connect
**
** Description      This function is called to initiate a connection to a peer device.<commit_msg>Component/bt: fix memory leak in service change char<commit_after>/******************************************************************************
 *
 *  Copyright (C) 2008-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  this file contains the main ATT functions
 *
 ******************************************************************************/

#include "common/bt_target.h"

#if BLE_INCLUDED == TRUE

#include "gatt_int.h"
#include "stack/l2c_api.h"
#include "btm_int.h"
#include "btm_ble_int.h"
#include "osi/allocator.h"

/* Configuration flags. */
#define GATT_L2C_CFG_IND_DONE   (1<<0)
#define GATT_L2C_CFG_CFM_DONE   (1<<1)

/* minimum GATT MTU size over BR/EDR link
*/
#define GATT_MIN_BR_MTU_SIZE       48

/********************************************************************************/
/*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
/********************************************************************************/
static void gatt_le_connect_cback (UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected,
                                   UINT16 reason, tBT_TRANSPORT transport);
static void gatt_le_data_ind (UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf);
static void gatt_le_cong_cback(BD_ADDR remote_bda, BOOLEAN congest);
#if (CLASSIC_BT_INCLUDED == TRUE)
static void gatt_l2cif_connect_ind_cback (BD_ADDR  bd_addr, UINT16 l2cap_cid,
        UINT16 psm, UINT8 l2cap_id);
static void gatt_l2cif_connect_cfm_cback (UINT16 l2cap_cid, UINT16 result);
static void gatt_l2cif_config_ind_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
static void gatt_l2cif_config_cfm_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
static void gatt_l2cif_disconnect_ind_cback (UINT16 l2cap_cid, BOOLEAN ack_needed);
static void gatt_l2cif_disconnect_cfm_cback (UINT16 l2cap_cid, UINT16 result);
static void gatt_l2cif_data_ind_cback (UINT16 l2cap_cid, BT_HDR *p_msg);
#endif  ///CLASSIC_BT_INCLUDED == TRUE
static void gatt_send_conn_cback (tGATT_TCB *p_tcb);
#if (CLASSIC_BT_INCLUDED == TRUE)
static void gatt_l2cif_congest_cback (UINT16 cid, BOOLEAN congested);
static const tL2CAP_APPL_INFO dyn_info = {
    gatt_l2cif_connect_ind_cback,
    gatt_l2cif_connect_cfm_cback,
    NULL,
    gatt_l2cif_config_ind_cback,
    gatt_l2cif_config_cfm_cback,
    gatt_l2cif_disconnect_ind_cback,
    gatt_l2cif_disconnect_cfm_cback,
    NULL,
    gatt_l2cif_data_ind_cback,
    gatt_l2cif_congest_cback,
    NULL
} ;
#endif  ///SMP_INCLUDED == TRUE

#if GATT_DYNAMIC_MEMORY == FALSE
tGATT_CB  gatt_cb;
#else
tGATT_CB  *gatt_cb_ptr;
#endif

tGATT_DEFAULT gatt_default;

/*******************************************************************************
**
** Function         gatt_init
**
** Description      This function is enable the GATT profile on the device.
**                  It clears out the control blocks, and registers with L2CAP.
**
** Returns          void
**
*******************************************************************************/
void gatt_init (void)
{
    tL2CAP_FIXED_CHNL_REG  fixed_reg;
#if GATT_DYNAMIC_MEMORY
    gatt_cb_ptr = (tGATT_CB *)osi_malloc(sizeof(tGATT_CB));
#endif /* #if GATT_DYNAMIC_MEMORY */
    memset (&gatt_cb, 0, sizeof(tGATT_CB));
    memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));

#if defined(GATT_INITIAL_TRACE_LEVEL)
    gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL;
#else
    gatt_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
#endif
    gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE;
    gatt_cb.sign_op_queue = fixed_queue_new(QUEUE_SIZE_MAX);
    gatt_cb.srv_chg_clt_q = fixed_queue_new(QUEUE_SIZE_MAX);
    gatt_cb.pending_new_srv_start_q = fixed_queue_new(QUEUE_SIZE_MAX);
    /* First, register fixed L2CAP channel for ATT over BLE */
    fixed_reg.fixed_chnl_opts.mode         = L2CAP_FCR_BASIC_MODE;
    fixed_reg.fixed_chnl_opts.max_transmit = 0xFF;
    fixed_reg.fixed_chnl_opts.rtrans_tout  = 2000;
    fixed_reg.fixed_chnl_opts.mon_tout     = 12000;
    fixed_reg.fixed_chnl_opts.mps          = 670;
    fixed_reg.fixed_chnl_opts.tx_win_sz    = 1;

    fixed_reg.pL2CA_FixedConn_Cb = gatt_le_connect_cback;
    fixed_reg.pL2CA_FixedData_Cb = gatt_le_data_ind;
    fixed_reg.pL2CA_FixedCong_Cb = gatt_le_cong_cback;      /* congestion callback */
    fixed_reg.default_idle_tout  = 0xffff;                  /* 0xffff default idle timeout */

    L2CA_RegisterFixedChannel (L2CAP_ATT_CID, &fixed_reg);
#if (CLASSIC_BT_INCLUDED == TRUE)
    /* Now, register with L2CAP for ATT PSM over BR/EDR */
    if (!L2CA_Register (BT_PSM_ATT, (tL2CAP_APPL_INFO *) &dyn_info)) {
        GATT_TRACE_ERROR ("ATT Dynamic Registration failed");
    }
#endif  ///CLASSIC_BT_INCLUDED == TRUE
    BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);
    BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);

    gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE;
    gatt_cb.hdl_cfg.gap_start_hdl  = GATT_GAP_START_HANDLE;
    gatt_cb.hdl_cfg.app_start_hdl  = GATT_APP_START_HANDLE;
#if (GATTS_INCLUDED == TRUE)
    gatt_profile_db_init();
#endif  ///GATTS_INCLUDED == TRUE
    //init local MTU size
    gatt_default.local_mtu = GATT_MAX_MTU_SIZE;
}


/*******************************************************************************
**
** Function         gatt_free
**
** Description      This function frees resources used by the GATT profile.
**
** Returns          void
**
*******************************************************************************/
#if (GATT_INCLUDED == TRUE)
void gatt_free(void)
{
    int i;
    GATT_TRACE_DEBUG("gatt_free()");
    fixed_queue_free(gatt_cb.sign_op_queue, NULL);
    gatt_cb.sign_op_queue = NULL;
    fixed_queue_free(gatt_cb.srv_chg_clt_q, NULL);
    gatt_cb.srv_chg_clt_q = NULL;
    fixed_queue_free(gatt_cb.pending_new_srv_start_q, NULL);
    gatt_cb.pending_new_srv_start_q = NULL;

    for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++)
    {
        fixed_queue_free(gatt_cb.tcb[i].pending_enc_clcb, NULL);
        gatt_cb.tcb[i].pending_enc_clcb = NULL;

        fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
        gatt_cb.tcb[i].pending_ind_q = NULL;

        btu_free_timer(&gatt_cb.tcb[i].conf_timer_ent);
        memset(&gatt_cb.tcb[i].conf_timer_ent, 0, sizeof(TIMER_LIST_ENT));

        btu_free_timer(&gatt_cb.tcb[i].ind_ack_timer_ent);
        memset(&gatt_cb.tcb[i].ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT));

#if (GATTS_INCLUDED == TRUE)
        fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL);
        gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL;
#endif /* #if (GATTS_INCLUDED == TRUE) */
    }

#if (GATTS_INCLUDED == TRUE)
    for (i = 0; i < GATT_MAX_SR_PROFILES; i++) {
        gatt_remove_an_item_from_list(&gatt_cb.hdl_list_info, &gatt_cb.hdl_list[i]);
        gatt_free_attr_value_buffer(&gatt_cb.hdl_list[i]);
        gatt_free_hdl_buffer(&gatt_cb.hdl_list[i]);
    }
#endif /* #if (GATTS_INCLUDED == TRUE) */
#if GATT_DYNAMIC_MEMORY
    FREE_AND_RESET(gatt_cb_ptr);
#endif /* #if GATT_DYNAMIC_MEMORY */
}
#endif  ///GATTS_INCLUDED == TRUE

/*******************************************************************************
**
** Function         gatt_connect
**
** Description      This function is called to initiate a connection to a peer device.
{'fraction_non_alphanumeric': 0.19567827130852342, 'fraction_numerical': 0.014658494976938144, 'mean_word_length': 4.520753400767353, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1451723', 'n_tokens_mistral': 5983, 'n_tokens_neox': 5744, 'n_words': 1091}