Home | History | Annotate | Download | only in gatt
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2008-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  this file contains the main ATT functions
     22  *
     23  ******************************************************************************/
     24 
     25 #include "bt_target.h"
     26 
     27 #if BLE_INCLUDED == TRUE
     28 
     29 #include "gki.h"
     30 #include "gatt_int.h"
     31 #include "l2c_api.h"
     32 #include "btm_int.h"
     33 #include "btm_ble_int.h"
     34 #include "bt_utils.h"
     35 
     36 /* Configuration flags. */
     37 #define GATT_L2C_CFG_IND_DONE   (1<<0)
     38 #define GATT_L2C_CFG_CFM_DONE   (1<<1)
     39 
     40 /* minimum GATT MTU size over BR/EDR link
     41 */
     42 #define GATT_MIN_BR_MTU_SIZE       48
     43 
     44 /********************************************************************************/
     45 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
     46 /********************************************************************************/
     47 static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport);
     48 static void gatt_le_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf);
     49 static void gatt_le_cong_cback(BD_ADDR remote_bda, BOOLEAN congest);
     50 
     51 static void gatt_l2cif_connect_ind_cback (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
     52 static void gatt_l2cif_connect_cfm_cback (UINT16 l2cap_cid, UINT16 result);
     53 static void gatt_l2cif_config_ind_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
     54 static void gatt_l2cif_config_cfm_cback (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
     55 static void gatt_l2cif_disconnect_ind_cback (UINT16 l2cap_cid, BOOLEAN ack_needed);
     56 static void gatt_l2cif_disconnect_cfm_cback (UINT16 l2cap_cid, UINT16 result);
     57 static void gatt_l2cif_data_ind_cback (UINT16 l2cap_cid, BT_HDR *p_msg);
     58 static void gatt_send_conn_cback (tGATT_TCB *p_tcb);
     59 static void gatt_l2cif_congest_cback (UINT16 cid, BOOLEAN congested);
     60 
     61 static const tL2CAP_APPL_INFO dyn_info =
     62 {
     63     gatt_l2cif_connect_ind_cback,
     64     gatt_l2cif_connect_cfm_cback,
     65     NULL,
     66     gatt_l2cif_config_ind_cback,
     67     gatt_l2cif_config_cfm_cback,
     68     gatt_l2cif_disconnect_ind_cback,
     69     gatt_l2cif_disconnect_cfm_cback,
     70     NULL,
     71     gatt_l2cif_data_ind_cback,
     72     gatt_l2cif_congest_cback,
     73     NULL
     74 } ;
     75 
     76 #if GATT_DYNAMIC_MEMORY == FALSE
     77 tGATT_CB  gatt_cb;
     78 #endif
     79 
     80 /*******************************************************************************
     81 **
     82 ** Function         gatt_init
     83 **
     84 ** Description      This function is enable the GATT profile on the device.
     85 **                  It clears out the control blocks, and registers with L2CAP.
     86 **
     87 ** Returns          void
     88 **
     89 *******************************************************************************/
     90 void gatt_init (void)
     91 {
     92     tL2CAP_FIXED_CHNL_REG  fixed_reg;
     93 
     94     GATT_TRACE_DEBUG("gatt_init()");
     95 
     96     memset (&gatt_cb, 0, sizeof(tGATT_CB));
     97 
     98 #if defined(GATT_INITIAL_TRACE_LEVEL)
     99     gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL;
    100 #else
    101     gatt_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
    102 #endif
    103     gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE;
    104     GKI_init_q (&gatt_cb.sign_op_queue);
    105     /* First, register fixed L2CAP channel for ATT over BLE */
    106     fixed_reg.fixed_chnl_opts.mode         = L2CAP_FCR_BASIC_MODE;
    107     fixed_reg.fixed_chnl_opts.max_transmit = 0xFF;
    108     fixed_reg.fixed_chnl_opts.rtrans_tout  = 2000;
    109     fixed_reg.fixed_chnl_opts.mon_tout     = 12000;
    110     fixed_reg.fixed_chnl_opts.mps          = 670;
    111     fixed_reg.fixed_chnl_opts.tx_win_sz    = 1;
    112 
    113     fixed_reg.pL2CA_FixedConn_Cb = gatt_le_connect_cback;
    114     fixed_reg.pL2CA_FixedData_Cb = gatt_le_data_ind;
    115     fixed_reg.pL2CA_FixedCong_Cb = gatt_le_cong_cback;      /* congestion callback */
    116     fixed_reg.default_idle_tout  = 0xffff;                  /* 0xffff default idle timeout */
    117 
    118     L2CA_RegisterFixedChannel (L2CAP_ATT_CID, &fixed_reg);
    119 
    120     /* Now, register with L2CAP for ATT PSM over BR/EDR */
    121     if (!L2CA_Register (BT_PSM_ATT, (tL2CAP_APPL_INFO *) &dyn_info))
    122     {
    123         GATT_TRACE_ERROR ("ATT Dynamic Registration failed");
    124     }
    125 
    126     BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);
    127     BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT, 0, 0);
    128 
    129     gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE;
    130     gatt_cb.hdl_cfg.gap_start_hdl  = GATT_GAP_START_HANDLE;
    131     gatt_cb.hdl_cfg.app_start_hdl  = GATT_APP_START_HANDLE;
    132     gatt_profile_db_init();
    133 
    134 }
    135 
    136 
    137 
    138 /*******************************************************************************
    139 **
    140 ** Function         gatt_connect
    141 **
    142 ** Description      This function is called to initiate a connection to a peer device.
    143 **
    144 ** Parameter        rem_bda: remote device address to connect to.
    145 **
    146 ** Returns          TRUE if connection is started, otherwise return FALSE.
    147 **
    148 *******************************************************************************/
    149 BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport)
    150 {
    151     BOOLEAN             gatt_ret = FALSE;
    152 
    153     if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
    154         gatt_set_ch_state(p_tcb, GATT_CH_CONN);
    155 
    156     if (transport == BT_TRANSPORT_LE)
    157     {
    158         p_tcb->att_lcid = L2CAP_ATT_CID;
    159         gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda);
    160     }
    161     else
    162     {
    163         if ((p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda)) != 0)
    164             gatt_ret = TRUE;
    165     }
    166 
    167     return gatt_ret;
    168 }
    169 
    170 /*******************************************************************************
    171 **
    172 ** Function         gatt_disconnect
    173 **
    174 ** Description      This function is called to disconnect to an ATT device.
    175 **
    176 ** Parameter        p_tcb: pointer to the TCB to disconnect.
    177 **
    178 ** Returns          TRUE: if connection found and to be disconnected; otherwise
    179 **                  return FALSE.
    180 **
    181 *******************************************************************************/
    182 BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb)
    183 {
    184     BOOLEAN             ret = FALSE;
    185     tGATT_CH_STATE      ch_state;
    186     GATT_TRACE_DEBUG ("gatt_disconnect ");
    187 
    188     if (p_tcb != NULL)
    189     {
    190         ret = TRUE;
    191         if ( (ch_state = gatt_get_ch_state(p_tcb)) != GATT_CH_CLOSING )
    192         {
    193             if (p_tcb->att_lcid == L2CAP_ATT_CID)
    194             {
    195                 if (ch_state == GATT_CH_OPEN)
    196                 {
    197                     /* only LCB exist between remote device and local */
    198                     ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, p_tcb->peer_bda);
    199                 }
    200                 else
    201                 {
    202                     gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
    203                     ret = L2CA_CancelBleConnectReq (p_tcb->peer_bda);
    204                 }
    205             }
    206             else
    207             {
    208                 ret = L2CA_DisconnectReq(p_tcb->att_lcid);
    209             }
    210         }
    211         else
    212         {
    213             GATT_TRACE_DEBUG ("gatt_disconnect already in closing state");
    214         }
    215     }
    216 
    217     return ret;
    218 }
    219 
    220 /*******************************************************************************
    221 **
    222 ** Function         gatt_update_app_hold_link_status
    223 **
    224 ** Description      Update the application use link status
    225 **
    226 ** Returns          void.
    227 **
    228 *******************************************************************************/
    229 void gatt_update_app_hold_link_status (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add)
    230 {
    231     UINT8 i;
    232     BOOLEAN found=FALSE;
    233 
    234     if (p_tcb == NULL)
    235     {
    236         GATT_TRACE_ERROR("gatt_update_app_hold_link_status p_tcb=NULL");
    237         return;
    238     }
    239 
    240 
    241     for (i=0; i<GATT_MAX_APPS; i++)
    242     {
    243         if (p_tcb->app_hold_link[i] ==  gatt_if)
    244         {
    245             found = TRUE;
    246             if (!is_add)
    247             {
    248                 p_tcb->app_hold_link[i] = 0;
    249                 break;
    250             }
    251         }
    252     }
    253 
    254     if (!found && is_add)
    255     {
    256         for (i=0; i<GATT_MAX_APPS; i++)
    257         {
    258             if (p_tcb->app_hold_link[i] ==  0)
    259             {
    260                 p_tcb->app_hold_link[i] = gatt_if;
    261                 found = TRUE;
    262                 break;
    263             }
    264         }
    265     }
    266 
    267     GATT_TRACE_DEBUG("gatt_update_app_hold_link_status found=%d[1-found] idx=%d gatt_if=%d is_add=%d", found, i, gatt_if, is_add);
    268 
    269 }
    270 
    271 /*******************************************************************************
    272 **
    273 ** Function         gatt_update_app_use_link_flag
    274 **
    275 ** Description      Update the application use link flag and optional to check the acl link
    276 **                  if the link is up then set the idle time out accordingly
    277 **
    278 ** Returns          void.
    279 **
    280 *******************************************************************************/
    281 void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link)
    282 {
    283     GATT_TRACE_DEBUG("gatt_update_app_use_link_flag  is_add=%d chk_link=%d",
    284                       is_add, check_acl_link);
    285 
    286     gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add);
    287 
    288     if (check_acl_link &&
    289         p_tcb &&
    290          p_tcb->att_lcid == L2CAP_ATT_CID && /* only update link idle timer for fixed channel */
    291         (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) != GATT_INVALID_ACL_HANDLE))
    292     {
    293         if (is_add)
    294         {
    295             GATT_TRACE_DEBUG("GATT disables link idle timer");
    296             /* acl link is connected disable the idle timeout */
    297             GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
    298         }
    299         else
    300         {
    301             if (!gatt_num_apps_hold_link(p_tcb))
    302             {
    303                 /* acl link is connected but no application needs to use the link
    304                    so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */
    305                 GATT_TRACE_DEBUG("GATT starts link idle timer =%d sec", GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
    306                 GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport);
    307             }
    308 
    309         }
    310     }
    311 }
    312 
    313 /*******************************************************************************
    314 **
    315 ** Function         gatt_act_connect
    316 **
    317 ** Description      GATT connection initiation.
    318 **
    319 ** Returns          void.
    320 **
    321 *******************************************************************************/
    322 BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport)
    323 {
    324     BOOLEAN     ret = FALSE;
    325     tGATT_TCB   *p_tcb;
    326     UINT8       st;
    327 
    328     if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL)
    329     {
    330         ret = TRUE;
    331         st = gatt_get_ch_state(p_tcb);
    332 
    333         /* before link down, another app try to open a GATT connection */
    334         if(st == GATT_CH_OPEN &&  gatt_num_apps_hold_link(p_tcb) == 0 &&
    335             transport == BT_TRANSPORT_LE )
    336         {
    337             if (!gatt_connect(bd_addr,  p_tcb, transport))
    338                 ret = FALSE;
    339         }
    340         else if(st == GATT_CH_CLOSING)
    341         {
    342             /* need to complete the closing first */
    343             ret = FALSE;
    344         }
    345     }
    346     else
    347     {
    348         if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport)) != NULL)
    349         {
    350             if (!gatt_connect(bd_addr,  p_tcb, transport))
    351             {
    352                 GATT_TRACE_ERROR("gatt_connect failed");
    353                 memset(p_tcb, 0, sizeof(tGATT_TCB));
    354             }
    355             else
    356                 ret = TRUE;
    357         }
    358         else
    359         {
    360             ret = 0;
    361             GATT_TRACE_ERROR("Max TCB for gatt_if [%d] reached.", p_reg->gatt_if);
    362         }
    363     }
    364 
    365     if (ret)
    366     {
    367         gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, FALSE);
    368     }
    369 
    370     return ret;
    371 }
    372 
    373 /*******************************************************************************
    374 **
    375 ** Function         gatt_le_connect_cback
    376 **
    377 ** Description      This callback function is called by L2CAP to indicate that
    378 **                  the ATT fixed channel for LE is
    379 **                      connected (conn = TRUE)/disconnected (conn = FALSE).
    380 **
    381 *******************************************************************************/
    382 static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected,
    383                                    UINT16 reason, tBT_TRANSPORT transport)
    384 {
    385 
    386     tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
    387     BOOLEAN                 check_srv_chg = FALSE;
    388     tGATTS_SRV_CHG          *p_srv_chg_clt=NULL;
    389 
    390     /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */
    391     if (transport == BT_TRANSPORT_BR_EDR)
    392         return;
    393 
    394     GATT_TRACE_DEBUG ("GATT   ATT protocol channel with BDA: %08x%04x is %s",
    395                        (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
    396                        (bd_addr[4]<<8)+bd_addr[5], (connected) ? "connected" : "disconnected");
    397 
    398     if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL)
    399     {
    400         check_srv_chg = TRUE;
    401     }
    402     else
    403     {
    404         if (btm_sec_is_a_bonded_dev(bd_addr))
    405             gatt_add_a_bonded_dev_for_srv_chg(bd_addr);
    406     }
    407 
    408     if (connected)
    409     {
    410         /* do we have a channel initiating a connection? */
    411         if (p_tcb)
    412         {
    413             /* we are initiating connection */
    414             if ( gatt_get_ch_state(p_tcb) == GATT_CH_CONN)
    415             {
    416                 /* send callback */
    417                 gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
    418                 p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;
    419 
    420                 gatt_send_conn_cback(p_tcb);
    421             }
    422             if (check_srv_chg)
    423                 gatt_chk_srv_chg (p_srv_chg_clt);
    424         }
    425         /* this is incoming connection or background connection callback */
    426 
    427         else
    428         {
    429             if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE)) != NULL)
    430             {
    431                 p_tcb->att_lcid = L2CAP_ATT_CID;
    432 
    433                 gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
    434 
    435                 p_tcb->payload_size = GATT_DEF_BLE_MTU_SIZE;
    436 
    437                 gatt_send_conn_cback (p_tcb);
    438                 if (check_srv_chg)
    439                 {
    440                     gatt_chk_srv_chg (p_srv_chg_clt);
    441                 }
    442             }
    443             else
    444             {
    445                 GATT_TRACE_ERROR("CCB max out, no rsources");
    446             }
    447         }
    448     }
    449     else
    450     {
    451         gatt_cleanup_upon_disc(bd_addr, reason, transport);
    452         GATT_TRACE_DEBUG ("ATT disconnected");
    453     }
    454 }
    455 
    456 /*******************************************************************************
    457 **
    458 ** Function         gatt_channel_congestion
    459 **
    460 ** Description      This function is called to process the congestion callback
    461 **                  from lcb
    462 **
    463 ** Returns          void
    464 **
    465 *******************************************************************************/
    466 static void gatt_channel_congestion(tGATT_TCB *p_tcb, BOOLEAN congested)
    467 {
    468     UINT8 i = 0;
    469     tGATT_REG *p_reg=NULL;
    470     UINT16 conn_id;
    471 
    472     /* if uncongested, check to see if there is any more pending data */
    473     if (p_tcb != NULL && congested == FALSE)
    474     {
    475         gatt_cl_send_next_cmd_inq(p_tcb);
    476     }
    477     /* notifying all applications for the connection up event */
    478     for (i = 0, p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++)
    479     {
    480         if (p_reg->in_use)
    481         {
    482             if (p_reg->app_cb.p_congestion_cb)
    483             {
    484                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
    485                 (*p_reg->app_cb.p_congestion_cb)(conn_id, congested);
    486             }
    487         }
    488     }
    489 }
    490 
    491 /*******************************************************************************
    492 **
    493 ** Function         gatt_le_cong_cback
    494 **
    495 ** Description      This function is called when GATT fixed channel is congested
    496 **                  or uncongested.
    497 **
    498 ** Returns          void
    499 **
    500 *******************************************************************************/
    501 static void gatt_le_cong_cback(BD_ADDR remote_bda, BOOLEAN congested)
    502 {
    503     tGATT_TCB *p_tcb = gatt_find_tcb_by_addr(remote_bda, BT_TRANSPORT_LE);
    504 
    505     /* if uncongested, check to see if there is any more pending data */
    506     if (p_tcb != NULL)
    507     {
    508         gatt_channel_congestion(p_tcb, congested);
    509     }
    510 }
    511 
    512 /*******************************************************************************
    513 **
    514 ** Function         gatt_le_data_ind
    515 **
    516 ** Description      This function is called when data is received from L2CAP.
    517 **                  if we are the originator of the connection, we are the ATT
    518 **                  client, and the received message is queued up for the client.
    519 **
    520 **                  If we are the destination of the connection, we are the ATT
    521 **                  server, so the message is passed to the server processing
    522 **                  function.
    523 **
    524 ** Returns          void
    525 **
    526 *******************************************************************************/
    527 static void gatt_le_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf)
    528 {
    529     tGATT_TCB    *p_tcb;
    530 
    531     /* Find CCB based on bd addr */
    532     if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, BT_TRANSPORT_LE)) != NULL &&
    533         gatt_get_ch_state(p_tcb) >= GATT_CH_OPEN)
    534     {
    535         gatt_data_process(p_tcb, p_buf);
    536     }
    537     else
    538     {
    539         GKI_freebuf (p_buf);
    540 
    541         if (p_tcb != NULL)
    542         {
    543             GATT_TRACE_WARNING ("ATT - Ignored L2CAP data while in state: %d",
    544                                  gatt_get_ch_state(p_tcb));
    545         }
    546     }
    547 }
    548 
    549 /*******************************************************************************
    550 **
    551 ** Function         gatt_l2cif_connect_ind
    552 **
    553 ** Description      This function handles an inbound connection indication
    554 **                  from L2CAP. This is the case where we are acting as a
    555 **                  server.
    556 **
    557 ** Returns          void
    558 **
    559 *******************************************************************************/
    560 static void gatt_l2cif_connect_ind_cback (BD_ADDR  bd_addr, UINT16 lcid, UINT16 psm, UINT8 id)
    561 {
    562     /* do we already have a control channel for this peer? */
    563     UINT8       result = L2CAP_CONN_OK;
    564     tL2CAP_CFG_INFO cfg;
    565     tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR);
    566     UNUSED(psm);
    567 
    568     GATT_TRACE_ERROR("Connection indication cid = %d", lcid);
    569     /* new connection ? */
    570     if (p_tcb == NULL)
    571     {
    572         /* allocate tcb */
    573         if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
    574         {
    575             /* no tcb available, reject L2CAP connection */
    576             result = L2CAP_CONN_NO_RESOURCES;
    577         }
    578         else
    579             p_tcb->att_lcid = lcid;
    580 
    581     }
    582     else /* existing connection , reject it */
    583     {
    584         result = L2CAP_CONN_NO_RESOURCES;
    585     }
    586 
    587     /* Send L2CAP connect rsp */
    588     L2CA_ConnectRsp(bd_addr, id, lcid, result, 0);
    589 
    590     /* if result ok, proceed with connection */
    591     if (result == L2CAP_CONN_OK)
    592     {
    593         /* transition to configuration state */
    594         gatt_set_ch_state(p_tcb, GATT_CH_CFG);
    595 
    596         /* Send L2CAP config req */
    597         memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
    598         cfg.mtu_present = TRUE;
    599         cfg.mtu = GATT_MAX_MTU_SIZE;
    600 
    601         L2CA_ConfigReq(lcid, &cfg);
    602     }
    603 }
    604 
    605 /*******************************************************************************
    606 **
    607 ** Function         gatt_l2c_connect_cfm_cback
    608 **
    609 ** Description      This is the L2CAP connect confirm callback function.
    610 **
    611 **
    612 ** Returns          void
    613 **
    614 *******************************************************************************/
    615 static void gatt_l2cif_connect_cfm_cback(UINT16 lcid, UINT16 result)
    616 {
    617     tGATT_TCB       *p_tcb;
    618     tL2CAP_CFG_INFO cfg;
    619 
    620     /* look up clcb for this channel */
    621     if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
    622     {
    623         GATT_TRACE_DEBUG("gatt_l2c_connect_cfm_cback result: %d ch_state: %d, lcid:0x%x", result, gatt_get_ch_state(p_tcb), p_tcb->att_lcid);
    624 
    625         /* if in correct state */
    626         if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN)
    627         {
    628             /* if result successful */
    629             if (result == L2CAP_CONN_OK)
    630             {
    631                 /* set channel state */
    632                 gatt_set_ch_state(p_tcb, GATT_CH_CFG);
    633 
    634                 /* Send L2CAP config req */
    635                 memset(&cfg, 0, sizeof(tL2CAP_CFG_INFO));
    636                 cfg.mtu_present = TRUE;
    637                 cfg.mtu = GATT_MAX_MTU_SIZE;
    638                 L2CA_ConfigReq(lcid, &cfg);
    639             }
    640             /* else initiating connection failure */
    641             else
    642             {
    643                 gatt_cleanup_upon_disc(p_tcb->peer_bda, result, GATT_TRANSPORT_BR_EDR);
    644             }
    645         }
    646         else /* wrong state, disconnect it */
    647         {
    648             if (result == L2CAP_CONN_OK)
    649             {
    650                 /* just in case the peer also accepts our connection - Send L2CAP disconnect req */
    651                 L2CA_DisconnectReq(lcid);
    652             }
    653         }
    654     }
    655 }
    656 
    657 /*******************************************************************************
    658 **
    659 ** Function         gatt_l2cif_config_cfm_cback
    660 **
    661 ** Description      This is the L2CAP config confirm callback function.
    662 **
    663 **
    664 ** Returns          void
    665 **
    666 *******************************************************************************/
    667 void gatt_l2cif_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
    668 {
    669     tGATT_TCB       *p_tcb;
    670     tGATTS_SRV_CHG  *p_srv_chg_clt=NULL;
    671 
    672     /* look up clcb for this channel */
    673     if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
    674     {
    675         /* if in correct state */
    676         if ( gatt_get_ch_state(p_tcb) == GATT_CH_CFG)
    677         {
    678             /* if result successful */
    679             if (p_cfg->result == L2CAP_CFG_OK)
    680             {
    681                 /* update flags */
    682                 p_tcb->ch_flags |= GATT_L2C_CFG_CFM_DONE;
    683 
    684                 /* if configuration complete */
    685                 if (p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE)
    686                 {
    687                     gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
    688 
    689                     if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda)) != NULL)
    690                     {
    691                         gatt_chk_srv_chg(p_srv_chg_clt);
    692                     }
    693                     else
    694                     {
    695                         if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
    696                             gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
    697                     }
    698 
    699                     /* send callback */
    700                     gatt_send_conn_cback(p_tcb);
    701                 }
    702             }
    703             /* else failure */
    704             else
    705             {
    706                 /* Send L2CAP disconnect req */
    707                 L2CA_DisconnectReq(lcid);
    708             }
    709         }
    710     }
    711 }
    712 
    713 /*******************************************************************************
    714 **
    715 ** Function         gatt_l2cif_config_ind_cback
    716 **
    717 ** Description      This is the L2CAP config indication callback function.
    718 **
    719 **
    720 ** Returns          void
    721 **
    722 *******************************************************************************/
    723 void gatt_l2cif_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
    724 {
    725     tGATT_TCB       *p_tcb;
    726     tGATTS_SRV_CHG  *p_srv_chg_clt=NULL;
    727     /* look up clcb for this channel */
    728     if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
    729     {
    730         /* GATT uses the smaller of our MTU and peer's MTU  */
    731         if ( p_cfg->mtu_present &&
    732              (p_cfg->mtu >= GATT_MIN_BR_MTU_SIZE && p_cfg->mtu < L2CAP_DEFAULT_MTU))
    733             p_tcb->payload_size = p_cfg->mtu;
    734         else
    735             p_tcb->payload_size = L2CAP_DEFAULT_MTU;
    736 
    737         /* send L2CAP configure response */
    738         memset(p_cfg, 0, sizeof(tL2CAP_CFG_INFO));
    739         p_cfg->result = L2CAP_CFG_OK;
    740         L2CA_ConfigRsp(lcid, p_cfg);
    741 
    742         /* if first config ind */
    743         if ((p_tcb->ch_flags & GATT_L2C_CFG_IND_DONE) == 0)
    744         {
    745             /* update flags */
    746             p_tcb->ch_flags |= GATT_L2C_CFG_IND_DONE;
    747 
    748             /* if configuration complete */
    749             if (p_tcb->ch_flags & GATT_L2C_CFG_CFM_DONE)
    750             {
    751                 gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
    752                 if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda)) != NULL)
    753                 {
    754                     gatt_chk_srv_chg(p_srv_chg_clt);
    755                 }
    756                 else
    757                 {
    758                     if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
    759                         gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
    760                 }
    761 
    762                 /* send callback */
    763                 gatt_send_conn_cback(p_tcb);
    764             }
    765         }
    766     }
    767 }
    768 
    769 /*******************************************************************************
    770 **
    771 ** Function         gatt_l2cif_disconnect_ind_cback
    772 **
    773 ** Description      This is the L2CAP disconnect indication callback function.
    774 **
    775 **
    776 ** Returns          void
    777 **
    778 *******************************************************************************/
    779 void gatt_l2cif_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
    780 {
    781     tGATT_TCB       *p_tcb;
    782     UINT16          reason;
    783 
    784     /* look up clcb for this channel */
    785     if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
    786     {
    787         if (ack_needed)
    788         {
    789             /* send L2CAP disconnect response */
    790             L2CA_DisconnectRsp(lcid);
    791         }
    792         if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL)
    793         {
    794             if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
    795                 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
    796         }
    797         /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */
    798         if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0)
    799             reason = GATT_CONN_TERMINATE_PEER_USER;
    800 
    801         /* send disconnect callback */
    802         gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
    803     }
    804 }
    805 
    806 /*******************************************************************************
    807 **
    808 ** Function         gatt_l2cif_disconnect_cfm_cback
    809 **
    810 ** Description      This is the L2CAP disconnect confirm callback function.
    811 **
    812 **
    813 ** Returns          void
    814 **
    815 *******************************************************************************/
    816 static void gatt_l2cif_disconnect_cfm_cback(UINT16 lcid, UINT16 result)
    817 {
    818     tGATT_TCB       *p_tcb;
    819     UINT16          reason;
    820     UNUSED(result);
    821 
    822     /* look up clcb for this channel */
    823     if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL)
    824     {
    825         /* If the device is not in the service changed client list, add it... */
    826         if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL)
    827         {
    828             if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
    829                 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
    830         }
    831 
    832         /* send disconnect callback */
    833         /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */
    834         if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0)
    835             reason = GATT_CONN_TERMINATE_LOCAL_HOST;
    836 
    837         gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
    838     }
    839 }
    840 
    841 /*******************************************************************************
    842 **
    843 ** Function         gatt_l2cif_data_ind_cback
    844 **
    845 ** Description      This is the L2CAP data indication callback function.
    846 **
    847 **
    848 ** Returns          void
    849 **
    850 *******************************************************************************/
    851 static void gatt_l2cif_data_ind_cback(UINT16 lcid, BT_HDR *p_buf)
    852 {
    853     tGATT_TCB       *p_tcb;
    854 
    855     /* look up clcb for this channel */
    856     if ((p_tcb = gatt_find_tcb_by_cid(lcid)) != NULL &&
    857         gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)
    858     {
    859         /* process the data */
    860         gatt_data_process(p_tcb, p_buf);
    861     }
    862     else /* prevent buffer leak */
    863         GKI_freebuf(p_buf);
    864 }
    865 
    866 /*******************************************************************************
    867 **
    868 ** Function         gatt_l2cif_congest_cback
    869 **
    870 ** Description      L2CAP congestion callback
    871 **
    872 ** Returns          void
    873 **
    874 *******************************************************************************/
    875 static void gatt_l2cif_congest_cback (UINT16 lcid, BOOLEAN congested)
    876 {
    877     tGATT_TCB *p_tcb = gatt_find_tcb_by_cid(lcid);
    878 
    879     if (p_tcb != NULL)
    880     {
    881         gatt_channel_congestion(p_tcb, congested);
    882     }
    883 }
    884 
    885 /*******************************************************************************
    886 **
    887 ** Function         gatt_send_conn_cback
    888 **
    889 ** Description      Callback used to notify layer above about a connection.
    890 **
    891 **
    892 ** Returns          void
    893 **
    894 *******************************************************************************/
    895 static void gatt_send_conn_cback(tGATT_TCB *p_tcb)
    896 {
    897     UINT8               i;
    898     tGATT_REG           *p_reg;
    899     tGATT_BG_CONN_DEV   *p_bg_dev=NULL;
    900     UINT16              conn_id;
    901 
    902     p_bg_dev = gatt_find_bg_dev(p_tcb->peer_bda);
    903 
    904     /* notifying all applications for the connection up event */
    905     for (i = 0,  p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++)
    906     {
    907         if (p_reg->in_use)
    908         {
    909             if (p_bg_dev && gatt_is_bg_dev_for_app(p_bg_dev, p_reg->gatt_if))
    910                 gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, TRUE);
    911 
    912             if (p_reg->app_cb.p_conn_cb)
    913             {
    914                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
    915                 (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id,
    916                                           TRUE, 0, p_tcb->transport);
    917             }
    918         }
    919     }
    920 
    921 
    922     if (gatt_num_apps_hold_link(p_tcb) &&  p_tcb->att_lcid == L2CAP_ATT_CID )
    923     {
    924         /* disable idle timeout if one or more clients are holding the link disable the idle timer */
    925         GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
    926     }
    927 }
    928 
    929 /*******************************************************************************
    930 **
    931 ** Function         gatt_le_data_ind
    932 **
    933 ** Description      This function is called when data is received from L2CAP.
    934 **                  if we are the originator of the connection, we are the ATT
    935 **                  client, and the received message is queued up for the client.
    936 **
    937 **                  If we are the destination of the connection, we are the ATT
    938 **                  server, so the message is passed to the server processing
    939 **                  function.
    940 **
    941 ** Returns          void
    942 **
    943 *******************************************************************************/
    944 void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf)
    945 {
    946     UINT8   *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
    947     UINT8   op_code, pseudo_op_code;
    948     UINT16  msg_len;
    949 
    950 
    951     if (p_buf->len > 0)
    952     {
    953         msg_len = p_buf->len - 1;
    954         STREAM_TO_UINT8(op_code, p);
    955 
    956         /* remove the two MSBs associated with sign write and write cmd */
    957         pseudo_op_code = op_code & (~GATT_WRITE_CMD_MASK);
    958 
    959         if (pseudo_op_code < GATT_OP_CODE_MAX)
    960         {
    961             if (op_code == GATT_SIGN_CMD_WRITE)
    962             {
    963                 gatt_verify_signature(p_tcb, p_buf);
    964             }
    965             else
    966             {
    967                 /* message from client */
    968                 if ((op_code % 2) == 0)
    969                     gatt_server_handle_client_req (p_tcb, op_code, msg_len, p);
    970                 else
    971                     gatt_client_handle_server_rsp (p_tcb, op_code, msg_len, p);
    972             }
    973         }
    974         else
    975         {
    976             GATT_TRACE_ERROR ("ATT - Rcvd L2CAP data, unknown cmd: 0x%x", op_code);
    977         }
    978     }
    979     else
    980     {
    981         GATT_TRACE_ERROR ("invalid data length, ignore");
    982     }
    983 
    984     GKI_freebuf (p_buf);
    985 }
    986 
    987 /*******************************************************************************
    988 **
    989 ** Function         gatt_add_a_bonded_dev_for_srv_chg
    990 **
    991 ** Description      Add a bonded dev to the service changed client list
    992 **
    993 ** Returns          void
    994 **
    995 *******************************************************************************/
    996 void gatt_add_a_bonded_dev_for_srv_chg (BD_ADDR bda)
    997 {
    998     tGATTS_SRV_CHG *p_buf;
    999     tGATTS_SRV_CHG_REQ req;
   1000     tGATTS_SRV_CHG srv_chg_clt;
   1001 
   1002     memcpy(srv_chg_clt.bda, bda, BD_ADDR_LEN);
   1003     srv_chg_clt.srv_changed = FALSE;
   1004     if ((p_buf = gatt_add_srv_chg_clt(&srv_chg_clt)) != NULL)
   1005     {
   1006         memcpy(req.srv_chg.bda, bda, BD_ADDR_LEN);
   1007         req.srv_chg.srv_changed = FALSE;
   1008         if (gatt_cb.cb_info.p_srv_chg_callback)
   1009             (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_ADD_CLIENT, &req, NULL);
   1010     }
   1011 
   1012 }
   1013 
   1014 /*******************************************************************************
   1015 **
   1016 ** Function         gatt_send_srv_chg_ind
   1017 **
   1018 ** Description      This function is called to send a service chnaged indication to
   1019 **                  the specified bd address
   1020 **
   1021 ** Returns          void
   1022 **
   1023 *******************************************************************************/
   1024 void gatt_send_srv_chg_ind (BD_ADDR peer_bda)
   1025 {
   1026     UINT8   handle_range[GATT_SIZE_OF_SRV_CHG_HNDL_RANGE];
   1027     UINT8   *p = handle_range;
   1028     UINT16  conn_id;
   1029 
   1030     GATT_TRACE_DEBUG("gatt_send_srv_chg_ind");
   1031 
   1032     if (gatt_cb.handle_of_h_r)
   1033     {
   1034         if ((conn_id = gatt_profile_find_conn_id_by_bd_addr(peer_bda)) != GATT_INVALID_CONN_ID)
   1035         {
   1036             UINT16_TO_STREAM (p, 1);
   1037             UINT16_TO_STREAM (p, 0xFFFF);
   1038             GATTS_HandleValueIndication (conn_id,
   1039                                          gatt_cb.handle_of_h_r,
   1040                                          GATT_SIZE_OF_SRV_CHG_HNDL_RANGE,
   1041                                          handle_range);
   1042         }
   1043         else
   1044         {
   1045             GATT_TRACE_ERROR("Unable to find conn_id for  %08x%04x ",
   1046                               (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3],
   1047                               (peer_bda[4]<<8)+peer_bda[5] );
   1048         }
   1049     }
   1050 }
   1051 
   1052 /*******************************************************************************
   1053 **
   1054 ** Function         gatt_chk_srv_chg
   1055 **
   1056 ** Description      Check sending service chnaged Indication is required or not
   1057 **                  if required then send the Indication
   1058 **
   1059 ** Returns          void
   1060 **
   1061 *******************************************************************************/
   1062 void gatt_chk_srv_chg(tGATTS_SRV_CHG *p_srv_chg_clt)
   1063 {
   1064     GATT_TRACE_DEBUG("gatt_chk_srv_chg srv_changed=%d", p_srv_chg_clt->srv_changed );
   1065 
   1066     if (p_srv_chg_clt->srv_changed)
   1067     {
   1068         gatt_send_srv_chg_ind(p_srv_chg_clt->bda);
   1069     }
   1070 }
   1071 
   1072 /*******************************************************************************
   1073 **
   1074 ** Function         gatt_init_srv_chg
   1075 **
   1076 ** Description      This function is used to initialize the service changed
   1077 **                  attribute value
   1078 **
   1079 ** Returns          void
   1080 **
   1081 *******************************************************************************/
   1082 void gatt_init_srv_chg (void)
   1083 {
   1084     tGATTS_SRV_CHG_REQ req;
   1085     tGATTS_SRV_CHG_RSP rsp;
   1086     BOOLEAN status;
   1087     UINT8 num_clients,i;
   1088     tGATTS_SRV_CHG  srv_chg_clt;
   1089 
   1090     GATT_TRACE_DEBUG("gatt_init_srv_chg");
   1091     if (gatt_cb.cb_info.p_srv_chg_callback)
   1092     {
   1093         status = (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_READ_NUM_CLENTS, NULL, &rsp);
   1094 
   1095         if (status && rsp.num_clients)
   1096         {
   1097             GATT_TRACE_DEBUG("gatt_init_srv_chg num_srv_chg_clt_clients=%d", rsp.num_clients);
   1098             num_clients = rsp.num_clients;
   1099             i = 1; /* use one based index */
   1100             while ((i <= num_clients) && status)
   1101             {
   1102                 req.client_read_index = i;
   1103                 if ((status = (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_READ_CLENT, &req, &rsp)) == TRUE)
   1104                 {
   1105                     memcpy(&srv_chg_clt, &rsp.srv_chg ,sizeof(tGATTS_SRV_CHG));
   1106                     if (gatt_add_srv_chg_clt(&srv_chg_clt) == NULL)
   1107                     {
   1108                         GATT_TRACE_ERROR("Unable to add a service change client");
   1109                         status = FALSE;
   1110                     }
   1111                 }
   1112                 i++;
   1113             }
   1114         }
   1115     }
   1116     else
   1117     {
   1118         GATT_TRACE_DEBUG("gatt_init_srv_chg callback not registered yet");
   1119     }
   1120 }
   1121 
   1122 /*******************************************************************************
   1123 **
   1124 ** Function         gatt_proc_srv_chg
   1125 **
   1126 ** Description      This function is process the service changed request
   1127 **
   1128 ** Returns          void
   1129 **
   1130 *******************************************************************************/
   1131 void gatt_proc_srv_chg (void)
   1132 {
   1133     UINT8               start_idx, found_idx;
   1134     BD_ADDR             bda;
   1135     BOOLEAN             srv_chg_ind_pending=FALSE;
   1136     tGATT_TCB           *p_tcb;
   1137     tBT_TRANSPORT      transport;
   1138 
   1139     GATT_TRACE_DEBUG ("gatt_proc_srv_chg");
   1140 
   1141     if (gatt_cb.cb_info.p_srv_chg_callback && gatt_cb.handle_of_h_r)
   1142     {
   1143         gatt_set_srv_chg();
   1144         start_idx =0;
   1145         while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport))
   1146         {
   1147             p_tcb = &gatt_cb.tcb[found_idx];;
   1148             srv_chg_ind_pending  = gatt_is_srv_chg_ind_pending(p_tcb);
   1149 
   1150             if (!srv_chg_ind_pending)
   1151             {
   1152                 gatt_send_srv_chg_ind(bda);
   1153             }
   1154             else
   1155             {
   1156                 GATT_TRACE_DEBUG ("discard srv chg - already has one in the queue");
   1157             }
   1158             start_idx = ++found_idx;
   1159         }
   1160     }
   1161 }
   1162 
   1163 /*******************************************************************************
   1164 **
   1165 ** Function         gatt_set_ch_state
   1166 **
   1167 ** Description      This function set the ch_state in tcb
   1168 **
   1169 ** Returns          none
   1170 **
   1171 *******************************************************************************/
   1172 void gatt_set_ch_state(tGATT_TCB *p_tcb, tGATT_CH_STATE ch_state)
   1173 {
   1174     if (p_tcb)
   1175     {
   1176         GATT_TRACE_DEBUG ("gatt_set_ch_state: old=%d new=%d", p_tcb->ch_state, ch_state);
   1177         p_tcb->ch_state = ch_state;
   1178     }
   1179 }
   1180 
   1181 /*******************************************************************************
   1182 **
   1183 ** Function         gatt_get_ch_state
   1184 **
   1185 ** Description      This function get the ch_state in tcb
   1186 **
   1187 ** Returns          none
   1188 **
   1189 *******************************************************************************/
   1190 tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB *p_tcb)
   1191 {
   1192     tGATT_CH_STATE ch_state = GATT_CH_CLOSE;
   1193     if (p_tcb)
   1194     {
   1195         GATT_TRACE_DEBUG ("gatt_get_ch_state: ch_state=%d", p_tcb->ch_state);
   1196         ch_state = p_tcb->ch_state;
   1197     }
   1198     return ch_state;
   1199 }
   1200 
   1201 #endif /* BLE_INCLUDED */
   1202