Home | History | Annotate | Download | only in l2cap
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-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 functions relating to BLE management.
     22  *
     23  ******************************************************************************/
     24 
     25 #include <string.h>
     26 #include "bt_target.h"
     27 #include "bt_utils.h"
     28 #include "l2cdefs.h"
     29 #include "l2c_int.h"
     30 #include "btu.h"
     31 #include "btm_int.h"
     32 #include "hcimsgs.h"
     33 #include "device/include/controller.h"
     34 #include "stack_config.h"
     35 
     36 #if (BLE_INCLUDED == TRUE)
     37 
     38 extern fixed_queue_t *btu_general_alarm_queue;
     39 
     40 static void l2cble_start_conn_update (tL2C_LCB *p_lcb);
     41 
     42 /*******************************************************************************
     43 **
     44 **  Function        L2CA_CancelBleConnectReq
     45 **
     46 **  Description     Cancel a pending connection attempt to a BLE device.
     47 **
     48 **  Parameters:     BD Address of remote
     49 **
     50 **  Return value:   TRUE if connection was cancelled
     51 **
     52 *******************************************************************************/
     53 BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
     54 {
     55     tL2C_LCB *p_lcb;
     56 
     57     /* There can be only one BLE connection request outstanding at a time */
     58     if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
     59     {
     60         L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - no connection pending");
     61         return(FALSE);
     62     }
     63 
     64     if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN))
     65     {
     66         L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - different  BDA Connecting: %08x%04x  Cancel: %08x%04x",
     67                               (l2cb.ble_connecting_bda[0]<<24)+(l2cb.ble_connecting_bda[1]<<16)+(l2cb.ble_connecting_bda[2]<<8)+l2cb.ble_connecting_bda[3],
     68                               (l2cb.ble_connecting_bda[4]<<8)+l2cb.ble_connecting_bda[5],
     69                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
     70 
     71         return(FALSE);
     72     }
     73 
     74     if (btsnd_hcic_ble_create_conn_cancel())
     75     {
     76         p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
     77         /* Do not remove lcb if an LE link is already up as a peripheral */
     78         if (p_lcb != NULL &&
     79             !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(rem_bda)))
     80         {
     81             p_lcb->disc_reason = L2CAP_CONN_CANCEL;
     82             l2cu_release_lcb (p_lcb);
     83         }
     84         /* update state to be cancel, wait for connection cancel complete */
     85         btm_ble_set_conn_st (BLE_CONN_CANCEL);
     86 
     87         return(TRUE);
     88     }
     89     else
     90         return(FALSE);
     91 }
     92 
     93 /*******************************************************************************
     94 **
     95 **  Function        L2CA_UpdateBleConnParams
     96 **
     97 **  Description     Update BLE connection parameters.
     98 **
     99 **  Parameters:     BD Address of remote
    100 **
    101 **  Return value:   TRUE if update started
    102 **
    103 *******************************************************************************/
    104 BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int,
    105                                             UINT16 latency, UINT16 timeout)
    106 {
    107     tL2C_LCB            *p_lcb;
    108     tACL_CONN           *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);
    109 
    110     /* See if we have a link control block for the remote device */
    111     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
    112 
    113     /* If we don't have one, create one and accept the connection. */
    114     if (!p_lcb || !p_acl_cb)
    115     {
    116         L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
    117                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
    118                               (rem_bda[4]<<8)+rem_bda[5]);
    119         return(FALSE);
    120     }
    121 
    122     if (p_lcb->transport != BT_TRANSPORT_LE)
    123     {
    124         L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
    125                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
    126                               (rem_bda[4]<<8)+rem_bda[5]);
    127         return(FALSE);
    128     }
    129 
    130     p_lcb->min_interval = min_int;
    131     p_lcb->max_interval = max_int;
    132     p_lcb->latency = latency;
    133     p_lcb->timeout = timeout;
    134     p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
    135 
    136     l2cble_start_conn_update(p_lcb);
    137 
    138     return(TRUE);
    139 }
    140 
    141 
    142 /*******************************************************************************
    143 **
    144 **  Function        L2CA_EnableUpdateBleConnParams
    145 **
    146 **  Description     Enable or disable update based on the request from the peer
    147 **
    148 **  Parameters:     BD Address of remote
    149 **
    150 **  Return value:   TRUE if update started
    151 **
    152 *******************************************************************************/
    153 BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
    154 {
    155     if (stack_config_get_interface()->get_pts_conn_updates_disabled())
    156         return false;
    157 
    158     tL2C_LCB            *p_lcb;
    159 
    160     /* See if we have a link control block for the remote device */
    161     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
    162 
    163     if (!p_lcb)
    164     {
    165         L2CAP_TRACE_WARNING ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
    166             (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
    167             (rem_bda[4]<<8)+rem_bda[5]);
    168         return (FALSE);
    169     }
    170 
    171     L2CAP_TRACE_API ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__,
    172         (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
    173         (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask);
    174 
    175     if (p_lcb->transport != BT_TRANSPORT_LE)
    176     {
    177         L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE (link role %d)", __FUNCTION__,
    178                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
    179                               (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
    180         return (FALSE);
    181     }
    182 
    183     if (enable)
    184         p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE;
    185     else
    186         p_lcb->conn_update_mask |= L2C_BLE_CONN_UPDATE_DISABLE;
    187 
    188     l2cble_start_conn_update(p_lcb);
    189 
    190     return (TRUE);
    191 }
    192 
    193 
    194 /*******************************************************************************
    195 **
    196 ** Function         L2CA_GetBleConnRole
    197 **
    198 ** Description      This function returns the connection role.
    199 **
    200 ** Returns          link role.
    201 **
    202 *******************************************************************************/
    203 UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr)
    204 {
    205     UINT8       role = HCI_ROLE_UNKNOWN;
    206 
    207     tL2C_LCB *p_lcb;
    208 
    209     if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL)
    210         role = p_lcb->link_role;
    211 
    212     return role;
    213 }
    214 /*******************************************************************************
    215 **
    216 ** Function         L2CA_GetDisconnectReason
    217 **
    218 ** Description      This function returns the disconnect reason code.
    219 **
    220 ** Returns          disconnect reason
    221 **
    222 *******************************************************************************/
    223 UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
    224 {
    225     tL2C_LCB            *p_lcb;
    226     UINT16              reason = 0;
    227 
    228     if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL)
    229         reason = p_lcb->disc_reason;
    230 
    231     L2CAP_TRACE_DEBUG ("L2CA_GetDisconnectReason=%d ",reason);
    232 
    233     return reason;
    234 }
    235 
    236 void l2cble_use_preferred_conn_params(BD_ADDR bda) {
    237     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
    238     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (bda);
    239 
    240     /* If there are any preferred connection parameters, set them now */
    241     if ( (p_dev_rec->conn_params.min_conn_int     >= BTM_BLE_CONN_INT_MIN ) &&
    242          (p_dev_rec->conn_params.min_conn_int     <= BTM_BLE_CONN_INT_MAX ) &&
    243          (p_dev_rec->conn_params.max_conn_int     >= BTM_BLE_CONN_INT_MIN ) &&
    244          (p_dev_rec->conn_params.max_conn_int     <= BTM_BLE_CONN_INT_MAX ) &&
    245          (p_dev_rec->conn_params.slave_latency    <= BTM_BLE_CONN_LATENCY_MAX ) &&
    246          (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
    247          (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
    248          ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int &&
    249           p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
    250           (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) ||
    251           (p_lcb->latency > p_dev_rec->conn_params.slave_latency) ||
    252           (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout)))
    253     {
    254         L2CAP_TRACE_DEBUG ("%s: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d", __func__,
    255                             p_lcb->handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int,
    256                             p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout);
    257 
    258         p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int;
    259         p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int;
    260         p_lcb->timeout      = p_dev_rec->conn_params.supervision_tout;
    261         p_lcb->latency      = p_dev_rec->conn_params.slave_latency;
    262 
    263         btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
    264                                            p_dev_rec->conn_params.min_conn_int,
    265                                            p_dev_rec->conn_params.max_conn_int,
    266                                            p_dev_rec->conn_params.slave_latency,
    267                                            p_dev_rec->conn_params.supervision_tout,
    268                                            0, 0);
    269     }
    270 }
    271 
    272 /*******************************************************************************
    273 **
    274 ** Function l2cble_notify_le_connection
    275 **
    276 ** Description This function notifiy the l2cap connection to the app layer
    277 **
    278 ** Returns none
    279 **
    280 *******************************************************************************/
    281 void l2cble_notify_le_connection (BD_ADDR bda)
    282 {
    283     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
    284     tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ;
    285     tL2C_CCB *p_ccb;
    286 
    287     if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED)
    288     {
    289         /* update link status */
    290         btm_establish_continue(p_acl);
    291         /* update l2cap link status and send callback */
    292         p_lcb->link_state = LST_CONNECTED;
    293         l2cu_process_fixed_chnl_resp (p_lcb);
    294     }
    295 
    296     /* For all channels, send the event through their FSMs */
    297     for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
    298     {
    299         if (p_ccb->chnl_state == CST_CLOSED)
    300             l2c_csm_execute (p_ccb, L2CEVT_LP_CONNECT_CFM, NULL);
    301     }
    302 
    303     l2cble_use_preferred_conn_params(bda);
    304 }
    305 
    306 /*******************************************************************************
    307 **
    308 ** Function         l2cble_scanner_conn_comp
    309 **
    310 ** Description      This function is called when an HCI Connection Complete
    311 **                  event is received while we are a scanner (so we are master).
    312 **
    313 ** Returns          void
    314 **
    315 *******************************************************************************/
    316 void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
    317                                UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
    318 {
    319     tL2C_LCB            *p_lcb;
    320     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (bda);
    321 
    322     L2CAP_TRACE_DEBUG ("l2cble_scanner_conn_comp: HANDLE=%d addr_type=%d conn_interval=%d slave_latency=%d supervision_tout=%d",
    323                         handle,  type, conn_interval, conn_latency, conn_timeout);
    324 
    325     l2cb.is_ble_connecting = FALSE;
    326 
    327     /* See if we have a link control block for the remote device */
    328     p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
    329 
    330     /* If we don't have one, create one. this is auto connection complete. */
    331     if (!p_lcb)
    332     {
    333         p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
    334         if (!p_lcb)
    335         {
    336             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    337             L2CAP_TRACE_ERROR ("l2cble_scanner_conn_comp - failed to allocate LCB");
    338             return;
    339         }
    340         else
    341         {
    342             if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
    343             {
    344                 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    345                 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB");
    346                 return ;
    347             }
    348         }
    349     }
    350     else if (p_lcb->link_state != LST_CONNECTING)
    351     {
    352         L2CAP_TRACE_ERROR ("L2CAP got BLE scanner conn_comp in bad state: %d", p_lcb->link_state);
    353         return;
    354     }
    355     alarm_cancel(p_lcb->l2c_lcb_timer);
    356 
    357     /* Save the handle */
    358     p_lcb->handle = handle;
    359 
    360     /* Connected OK. Change state to connected, we were scanning so we are master */
    361     p_lcb->link_role  = HCI_ROLE_MASTER;
    362     p_lcb->transport  = BT_TRANSPORT_LE;
    363 
    364     /* update link parameter, set slave link as non-spec default upon link up */
    365     p_lcb->min_interval =  p_lcb->max_interval = conn_interval;
    366     p_lcb->timeout      =  conn_timeout;
    367     p_lcb->latency      =  conn_latency;
    368     p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
    369 
    370     /* Tell BTM Acl management about the link */
    371     btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
    372 
    373     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
    374 
    375     btm_ble_set_conn_st(BLE_CONN_IDLE);
    376 
    377 #if BLE_PRIVACY_SPT == TRUE
    378     btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, TRUE);
    379 #endif
    380 }
    381 
    382 
    383 /*******************************************************************************
    384 **
    385 ** Function         l2cble_advertiser_conn_comp
    386 **
    387 ** Description      This function is called when an HCI Connection Complete
    388 **                  event is received while we are an advertiser (so we are slave).
    389 **
    390 ** Returns          void
    391 **
    392 *******************************************************************************/
    393 void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
    394                                   UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
    395 {
    396     tL2C_LCB            *p_lcb;
    397     tBTM_SEC_DEV_REC    *p_dev_rec;
    398     UNUSED(type);
    399     UNUSED(conn_interval);
    400     UNUSED(conn_latency);
    401     UNUSED(conn_timeout);
    402 
    403     /* See if we have a link control block for the remote device */
    404     p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
    405 
    406     /* If we don't have one, create one and accept the connection. */
    407     if (!p_lcb)
    408     {
    409         p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
    410         if (!p_lcb)
    411         {
    412             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    413             L2CAP_TRACE_ERROR ("l2cble_advertiser_conn_comp - failed to allocate LCB");
    414             return;
    415         }
    416         else
    417         {
    418             if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
    419             {
    420                 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    421                 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB");
    422                 return ;
    423             }
    424         }
    425     }
    426 
    427     /* Save the handle */
    428     p_lcb->handle = handle;
    429 
    430     /* Connected OK. Change state to connected, we were advertising, so we are slave */
    431     p_lcb->link_role  = HCI_ROLE_SLAVE;
    432     p_lcb->transport  = BT_TRANSPORT_LE;
    433 
    434     /* update link parameter, set slave link as non-spec default upon link up */
    435     p_lcb->min_interval = p_lcb->max_interval = conn_interval;
    436     p_lcb->timeout      =  conn_timeout;
    437     p_lcb->latency      =  conn_latency;
    438     p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM;
    439 
    440     /* Tell BTM Acl management about the link */
    441     p_dev_rec = btm_find_or_alloc_dev (bda);
    442 
    443     btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
    444 
    445 #if BLE_PRIVACY_SPT == TRUE
    446     btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, TRUE);
    447 #endif
    448 
    449     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
    450 
    451     if (!HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(controller_get_interface()->get_features_ble()->as_array))
    452     {
    453         p_lcb->link_state = LST_CONNECTED;
    454         l2cu_process_fixed_chnl_resp (p_lcb);
    455     }
    456 
    457     /* when adv and initiating are both active, cancel the direct connection */
    458     if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0)
    459     {
    460         L2CA_CancelBleConnectReq(bda);
    461     }
    462 }
    463 
    464 /*******************************************************************************
    465 **
    466 ** Function         l2cble_conn_comp
    467 **
    468 ** Description      This function is called when an HCI Connection Complete
    469 **                  event is received.
    470 **
    471 ** Returns          void
    472 **
    473 *******************************************************************************/
    474 void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
    475                       UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
    476 {
    477     btm_ble_update_link_topology_mask(role, TRUE);
    478 
    479     if (role == HCI_ROLE_MASTER)
    480     {
    481         l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
    482     }
    483     else
    484     {
    485         l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
    486     }
    487 }
    488 
    489 /*******************************************************************************
    490 **
    491 **  Function        l2cble_start_conn_update
    492 **
    493 **  Description     start BLE connection parameter update process based on status
    494 **
    495 **  Parameters:     lcb : l2cap link control block
    496 **
    497 **  Return value:   none
    498 **
    499 *******************************************************************************/
    500 static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
    501 {
    502     UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout;
    503     tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
    504 
    505     // TODO(armansito): The return value of this call wasn't being used but the
    506     // logic of this function might be depending on its side effects. We should
    507     // verify if this call is needed at all and remove it otherwise.
    508     btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
    509 
    510     if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) return;
    511 
    512     if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE)
    513     {
    514         /* application requests to disable parameters update.
    515            If parameters are already updated, lets set them
    516            up to what has been requested during connection establishement */
    517         if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM &&
    518             /* current connection interval is greater than default min */
    519             p_lcb->min_interval > BTM_BLE_CONN_INT_MIN)
    520         {
    521             /* use 7.5 ms as fast connection parameter, 0 slave latency */
    522             min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN;
    523             slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF;
    524             supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF;
    525 
    526             /* if both side 4.1, or we are master device, send HCI command */
    527             if (p_lcb->link_role == HCI_ROLE_MASTER
    528 #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
    529                 || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) &&
    530                     HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))
    531 #endif
    532                  )
    533             {
    534                 btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, min_conn_int, max_conn_int,
    535                                                   slave_latency, supervision_tout, 0, 0);
    536                 p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
    537             }
    538             else
    539             {
    540                 l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout);
    541             }
    542             p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM;
    543             p_lcb->conn_update_mask |=  L2C_BLE_NEW_CONN_PARAM;
    544          }
    545     }
    546     else
    547     {
    548         /* application allows to do update, if we were delaying one do it now */
    549         if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM)
    550         {
    551              /* if both side 4.1, or we are master device, send HCI command */
    552             if (p_lcb->link_role == HCI_ROLE_MASTER
    553 #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
    554                 || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) &&
    555                     HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features))
    556 #endif
    557                  )
    558             {
    559                 btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval,
    560                     p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0);
    561                 p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING;
    562             }
    563             else
    564             {
    565                 l2cu_send_peer_ble_par_req (p_lcb, p_lcb->min_interval, p_lcb->max_interval,
    566                                             p_lcb->latency, p_lcb->timeout);
    567             }
    568             p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM;
    569             p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM;
    570         }
    571     }
    572 }
    573 
    574 /*******************************************************************************
    575 **
    576 ** Function         l2cble_process_conn_update_evt
    577 **
    578 ** Description      This function enables the connection update request from remote
    579 **                  after a successful connection update response is received.
    580 **
    581 ** Returns          void
    582 **
    583 *******************************************************************************/
    584 void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status)
    585 {
    586     tL2C_LCB *p_lcb;
    587 
    588     L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt");
    589 
    590     /* See if we have a link control block for the remote device */
    591     p_lcb = l2cu_find_lcb_by_handle(handle);
    592     if (!p_lcb)
    593     {
    594         L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Invalid handle: %d", handle);
    595         return;
    596     }
    597 
    598     p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
    599 
    600     if (status != HCI_SUCCESS)
    601     {
    602         L2CAP_TRACE_WARNING("l2cble_process_conn_update_evt: Error status: %d", status);
    603     }
    604 
    605     l2cble_start_conn_update(p_lcb);
    606 
    607     L2CAP_TRACE_DEBUG("l2cble_process_conn_update_evt: conn_update_mask=%d", p_lcb->conn_update_mask);
    608 }
    609 /*******************************************************************************
    610 **
    611 ** Function         l2cble_process_sig_cmd
    612 **
    613 ** Description      This function is called when a signalling packet is received
    614 **                  on the BLE signalling CID
    615 **
    616 ** Returns          void
    617 **
    618 *******************************************************************************/
    619 void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
    620 {
    621     UINT8           *p_pkt_end;
    622     UINT8           cmd_code, id;
    623     UINT16          cmd_len;
    624     UINT16          min_interval, max_interval, latency, timeout;
    625     tL2C_CONN_INFO  con_info;
    626     UINT16          lcid = 0, rcid = 0, mtu = 0, mps = 0, initial_credit = 0;
    627     tL2C_CCB        *p_ccb = NULL, *temp_p_ccb = NULL;
    628     tL2C_RCB        *p_rcb;
    629     UINT16          credit;
    630     p_pkt_end = p + pkt_len;
    631 
    632     STREAM_TO_UINT8  (cmd_code, p);
    633     STREAM_TO_UINT8  (id, p);
    634     STREAM_TO_UINT16 (cmd_len, p);
    635 
    636     /* Check command length does not exceed packet length */
    637     if ((p + cmd_len) > p_pkt_end)
    638     {
    639         L2CAP_TRACE_WARNING ("L2CAP - LE - format error, pkt_len: %d  cmd_len: %d  code: %d", pkt_len, cmd_len, cmd_code);
    640         return;
    641     }
    642 
    643     switch (cmd_code)
    644     {
    645         case L2CAP_CMD_REJECT:
    646             p += 2;
    647             break;
    648 
    649         case L2CAP_CMD_ECHO_REQ:
    650         case L2CAP_CMD_ECHO_RSP:
    651         case L2CAP_CMD_INFO_RSP:
    652         case L2CAP_CMD_INFO_REQ:
    653             l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
    654             break;
    655 
    656         case L2CAP_CMD_BLE_UPDATE_REQ:
    657             STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */
    658             STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */
    659             STREAM_TO_UINT16 (latency, p);  /* 0x0000 - 0x03E8 */
    660             STREAM_TO_UINT16 (timeout, p);  /* 0x000A - 0x0C80 */
    661             /* If we are a master, the slave wants to update the parameters */
    662             if (p_lcb->link_role == HCI_ROLE_MASTER)
    663             {
    664                 if (min_interval < BTM_BLE_CONN_INT_MIN_LIMIT)
    665                     min_interval = BTM_BLE_CONN_INT_MIN_LIMIT;
    666 
    667                 if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX ||
    668                     max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX ||
    669                     latency  > BTM_BLE_CONN_LATENCY_MAX ||
    670                     /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/
    671                     timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX ||
    672                     max_interval < min_interval)
    673                 {
    674                     l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id);
    675                 }
    676                 else
    677                 {
    678 
    679                     l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id);
    680 
    681                      p_lcb->min_interval = min_interval;
    682                      p_lcb->max_interval = max_interval;
    683                      p_lcb->latency = latency;
    684                      p_lcb->timeout = timeout;
    685                      p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
    686 
    687                      l2cble_start_conn_update(p_lcb);
    688                 }
    689             }
    690             else
    691                 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
    692             break;
    693 
    694         case L2CAP_CMD_BLE_UPDATE_RSP:
    695             p += 2;
    696             break;
    697 
    698         case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ:
    699             STREAM_TO_UINT16 (con_info.psm, p);
    700             STREAM_TO_UINT16 (rcid, p);
    701             STREAM_TO_UINT16 (mtu, p);
    702             STREAM_TO_UINT16 (mps, p);
    703             STREAM_TO_UINT16 (initial_credit, p);
    704 
    705             L2CAP_TRACE_DEBUG ("Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ with "
    706                     "mtu = %d, "
    707                     "mps = %d, "
    708                     "initial credit = %d", mtu, mps, initial_credit);
    709 
    710             if ((p_rcb = l2cu_find_ble_rcb_by_psm (con_info.psm)) == NULL)
    711             {
    712                 L2CAP_TRACE_WARNING ("L2CAP - rcvd conn req for unknown PSM: 0x%04x", con_info.psm);
    713                 l2cu_reject_ble_connection (p_lcb, id, L2CAP_LE_NO_PSM);
    714                 break;
    715             }
    716             else
    717             {
    718                 if (!p_rcb->api.pL2CA_ConnectInd_Cb)
    719                 {
    720                     L2CAP_TRACE_WARNING ("L2CAP - rcvd conn req for outgoing-only connection PSM: %d", con_info.psm);
    721                     l2cu_reject_ble_connection (p_lcb, id, L2CAP_CONN_NO_PSM);
    722                     break;
    723                 }
    724             }
    725 
    726             /* Allocate a ccb for this.*/
    727             if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL)
    728             {
    729                 L2CAP_TRACE_ERROR ("L2CAP - unable to allocate CCB");
    730                 l2cu_reject_ble_connection (p_lcb, id, L2CAP_CONN_NO_RESOURCES);
    731                 break;
    732             }
    733 
    734             /* validate the parameters */
    735             if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MPS || mps > L2CAP_LE_MAX_MPS)
    736             {
    737                 L2CAP_TRACE_ERROR ("L2CAP don't like the params");
    738                 l2cu_reject_ble_connection (p_lcb, id, L2CAP_CONN_NO_RESOURCES);
    739                 break;
    740             }
    741 
    742             p_ccb->remote_id = id;
    743             p_ccb->p_rcb = p_rcb;
    744             p_ccb->remote_cid = rcid;
    745 
    746             p_ccb->peer_conn_cfg.mtu = mtu;
    747             p_ccb->peer_conn_cfg.mps = mps;
    748             p_ccb->peer_conn_cfg.credits = initial_credit;
    749 
    750             p_ccb->tx_mps = mps;
    751             p_ccb->ble_sdu = NULL;
    752             p_ccb->ble_sdu_length = 0;
    753             p_ccb->is_first_seg = TRUE;
    754             p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
    755 
    756             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info);
    757             break;
    758 
    759         case L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES:
    760             L2CAP_TRACE_DEBUG ("Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES");
    761             /* For all channels, see whose identifier matches this id */
    762             for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb; temp_p_ccb = temp_p_ccb->p_next_ccb)
    763             {
    764                 if (temp_p_ccb->local_id == id)
    765                 {
    766                     p_ccb = temp_p_ccb;
    767                     break;
    768                 }
    769             }
    770             if (p_ccb)
    771             {
    772                 L2CAP_TRACE_DEBUG ("I remember the connection req");
    773                 STREAM_TO_UINT16 (p_ccb->remote_cid, p);
    774                 STREAM_TO_UINT16 (p_ccb->peer_conn_cfg.mtu, p);
    775                 STREAM_TO_UINT16 (p_ccb->peer_conn_cfg.mps, p);
    776                 STREAM_TO_UINT16 (p_ccb->peer_conn_cfg.credits, p);
    777                 STREAM_TO_UINT16 (con_info.l2cap_result, p);
    778                 con_info.remote_cid = p_ccb->remote_cid;
    779 
    780                 L2CAP_TRACE_DEBUG ("remote_cid = %d, "
    781                         "mtu = %d, "
    782                         "mps = %d, "
    783                         "initial_credit = %d, "
    784                         "con_info.l2cap_result = %d",
    785                         p_ccb->remote_cid, p_ccb->peer_conn_cfg.mtu, p_ccb->peer_conn_cfg.mps,
    786                         p_ccb->peer_conn_cfg.credits, con_info.l2cap_result);
    787 
    788                 /* validate the parameters */
    789                 if (p_ccb->peer_conn_cfg.mtu < L2CAP_LE_MIN_MTU ||
    790                         p_ccb->peer_conn_cfg.mps < L2CAP_LE_MIN_MPS ||
    791                         p_ccb->peer_conn_cfg.mps > L2CAP_LE_MAX_MPS)
    792                 {
    793                     L2CAP_TRACE_ERROR ("L2CAP don't like the params");
    794                     con_info.l2cap_result = L2CAP_LE_NO_RESOURCES;
    795                     l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
    796                     break;
    797                 }
    798 
    799                 p_ccb->tx_mps = p_ccb->peer_conn_cfg.mps;
    800                 p_ccb->ble_sdu = NULL;
    801                 p_ccb->ble_sdu_length = 0;
    802                 p_ccb->is_first_seg = TRUE;
    803                 p_ccb->peer_cfg.fcr.mode = L2CAP_FCR_LE_COC_MODE;
    804 
    805                 if (con_info.l2cap_result == L2CAP_LE_CONN_OK)
    806                     l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP, &con_info);
    807                 else
    808                     l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
    809             }
    810             else
    811             {
    812                 L2CAP_TRACE_DEBUG ("I DO NOT remember the connection req");
    813                 con_info.l2cap_result = L2CAP_LE_INVALID_SOURCE_CID;
    814                 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
    815             }
    816             break;
    817 
    818         case L2CAP_CMD_BLE_FLOW_CTRL_CREDIT:
    819             STREAM_TO_UINT16(lcid, p);
    820             if((p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, lcid)) == NULL)
    821             {
    822                 L2CAP_TRACE_DEBUG ("%s Credit received for unknown channel id %d", __func__, lcid);
    823                 break;
    824             }
    825 
    826             STREAM_TO_UINT16(credit ,p);
    827             l2c_csm_execute(p_ccb, L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT, &credit);
    828             L2CAP_TRACE_DEBUG ("%s Credit received", __func__);
    829             break;
    830 
    831         case L2CAP_CMD_DISC_REQ:
    832             STREAM_TO_UINT16 (lcid, p);
    833             STREAM_TO_UINT16 (rcid, p);
    834 
    835             if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL)
    836             {
    837                 if (p_ccb->remote_cid == rcid)
    838                 {
    839                     p_ccb->remote_id = id;
    840                     l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, NULL);
    841                 }
    842             }
    843             else
    844                 l2cu_send_peer_disc_rsp (p_lcb, id, lcid, rcid);
    845 
    846             break;
    847 
    848          case L2CAP_CMD_DISC_RSP:
    849             STREAM_TO_UINT16 (rcid, p);
    850             STREAM_TO_UINT16 (lcid, p);
    851 
    852             if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL)
    853             {
    854                 if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id))
    855                     l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, NULL);
    856             }
    857             break;
    858 
    859         default:
    860             L2CAP_TRACE_WARNING ("L2CAP - LE - unknown cmd code: %d", cmd_code);
    861             l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
    862             break;
    863     }
    864 }
    865 
    866 /*******************************************************************************
    867 **
    868 ** Function         l2cble_init_direct_conn
    869 **
    870 ** Description      This function is to initate a direct connection
    871 **
    872 ** Returns          TRUE connection initiated, FALSE otherwise.
    873 **
    874 *******************************************************************************/
    875 BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
    876 {
    877     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
    878     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
    879     UINT16 scan_int;
    880     UINT16 scan_win;
    881     BD_ADDR peer_addr;
    882     UINT8 peer_addr_type = BLE_ADDR_PUBLIC;
    883     UINT8 own_addr_type = BLE_ADDR_PUBLIC;
    884 
    885     /* There can be only one BLE connection request outstanding at a time */
    886     if (p_dev_rec == NULL)
    887     {
    888         L2CAP_TRACE_WARNING ("unknown device, can not initate connection");
    889         return(FALSE);
    890     }
    891 
    892     scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
    893     scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
    894 
    895     peer_addr_type = p_lcb->ble_addr_type;
    896     memcpy(peer_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
    897 
    898 #if ( (defined BLE_PRIVACY_SPT) && (BLE_PRIVACY_SPT == TRUE))
    899     own_addr_type = btm_cb.ble_ctr_cb.privacy_mode ? BLE_ADDR_RANDOM : BLE_ADDR_PUBLIC;
    900     if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)
    901     {
    902         if (btm_cb.ble_ctr_cb.privacy_mode >=  BTM_PRIVACY_1_2)
    903             own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
    904 
    905         btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
    906         btm_random_pseudo_to_identity_addr(peer_addr, &peer_addr_type);
    907     } else {
    908         btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, TRUE);
    909 
    910         // If we have a current RPA, use that instead.
    911         if (!bdaddr_is_empty((const bt_bdaddr_t *)p_dev_rec->ble.cur_rand_addr)) {
    912             memcpy(peer_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
    913         }
    914     }
    915 #endif
    916 
    917     if (!btm_ble_topology_check(BTM_BLE_STATE_INIT))
    918     {
    919         l2cu_release_lcb (p_lcb);
    920         L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation");
    921         return FALSE;
    922     }
    923 
    924     if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int      */
    925                                         scan_win, /* UINT16 scan_win      */
    926                                         FALSE,                   /* UINT8 white_list     */
    927                                         peer_addr_type,          /* UINT8 addr_type_peer */
    928                                         peer_addr,               /* BD_ADDR bda_peer     */
    929                                         own_addr_type,         /* UINT8 addr_type_own  */
    930         (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
    931         p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),  /* UINT16 conn_int_min  */
    932         (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
    933         p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),  /* UINT16 conn_int_max  */
    934         (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
    935         p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency  */
    936         (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
    937         p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */
    938                                         0,                       /* UINT16 min_len       */
    939                                         0))                      /* UINT16 max_len       */
    940     {
    941         l2cu_release_lcb (p_lcb);
    942         L2CAP_TRACE_ERROR("initate direct connection fail, no resources");
    943         return (FALSE);
    944     }
    945     else
    946     {
    947         p_lcb->link_state = LST_CONNECTING;
    948         l2cb.is_ble_connecting = TRUE;
    949         memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
    950         alarm_set_on_queue(p_lcb->l2c_lcb_timer,
    951                            L2CAP_BLE_LINK_CONNECT_TIMEOUT_MS,
    952                            l2c_lcb_timer_timeout, p_lcb,
    953                            btu_general_alarm_queue);
    954         btm_ble_set_conn_st (BLE_DIR_CONN);
    955 
    956         return (TRUE);
    957     }
    958 }
    959 
    960 /*******************************************************************************
    961 **
    962 ** Function         l2cble_create_conn
    963 **
    964 ** Description      This function initiates an acl connection via HCI
    965 **
    966 ** Returns          TRUE if successful, FALSE if connection not started.
    967 **
    968 *******************************************************************************/
    969 BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb)
    970 {
    971     tBTM_BLE_CONN_ST     conn_st = btm_ble_get_conn_st();
    972     BOOLEAN         rt = FALSE;
    973 
    974     /* There can be only one BLE connection request outstanding at a time */
    975     if (conn_st == BLE_CONN_IDLE)
    976     {
    977         rt = l2cble_init_direct_conn(p_lcb);
    978     }
    979     else
    980     {
    981         L2CAP_TRACE_WARNING ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st);
    982 
    983         btm_ble_enqueue_direct_conn_req(p_lcb);
    984 
    985         if (conn_st == BLE_BG_CONN)
    986             btm_ble_suspend_bg_conn();
    987 
    988         rt = TRUE;
    989     }
    990     return rt;
    991 }
    992 
    993 /*******************************************************************************
    994 **
    995 ** Function         l2c_link_processs_ble_num_bufs
    996 **
    997 ** Description      This function is called when a "controller buffer size"
    998 **                  event is first received from the controller. It updates
    999 **                  the L2CAP values.
   1000 **
   1001 ** Returns          void
   1002 **
   1003 *******************************************************************************/
   1004 void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs)
   1005 {
   1006     if (num_lm_ble_bufs == 0)
   1007     {
   1008         num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;
   1009         l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED;
   1010     }
   1011 
   1012     l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs;
   1013 }
   1014 
   1015 /*******************************************************************************
   1016 **
   1017 ** Function         l2c_ble_link_adjust_allocation
   1018 **
   1019 ** Description      This function is called when a link is created or removed
   1020 **                  to calculate the amount of packets each link may send to
   1021 **                  the HCI without an ack coming back.
   1022 **
   1023 **                  Currently, this is a simple allocation, dividing the
   1024 **                  number of Controller Packets by the number of links. In
   1025 **                  the future, QOS configuration should be examined.
   1026 **
   1027 ** Returns          void
   1028 **
   1029 *******************************************************************************/
   1030 void l2c_ble_link_adjust_allocation (void)
   1031 {
   1032     UINT16      qq, yy, qq_remainder;
   1033     tL2C_LCB    *p_lcb;
   1034     UINT16      hi_quota, low_quota;
   1035     UINT16      num_lowpri_links = 0;
   1036     UINT16      num_hipri_links  = 0;
   1037     UINT16      controller_xmit_quota = l2cb.num_lm_ble_bufs;
   1038     UINT16      high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
   1039 
   1040     /* If no links active, reset buffer quotas and controller buffers */
   1041     if (l2cb.num_ble_links_active == 0)
   1042     {
   1043         l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
   1044         l2cb.ble_round_robin_quota = l2cb.ble_round_robin_unacked = 0;
   1045         return;
   1046     }
   1047 
   1048     /* First, count the links */
   1049     for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++)
   1050     {
   1051         if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE)
   1052         {
   1053             if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
   1054                 num_hipri_links++;
   1055             else
   1056                 num_lowpri_links++;
   1057         }
   1058     }
   1059 
   1060     /* now adjust high priority link quota */
   1061     low_quota = num_lowpri_links ? 1 : 0;
   1062     while ( (num_hipri_links * high_pri_link_quota + low_quota) > controller_xmit_quota )
   1063         high_pri_link_quota--;
   1064 
   1065 
   1066     /* Work out the xmit quota and buffer quota high and low priorities */
   1067     hi_quota  = num_hipri_links * high_pri_link_quota;
   1068     low_quota = (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
   1069 
   1070     /* Work out and save the HCI xmit quota for each low priority link */
   1071 
   1072     /* If each low priority link cannot have at least one buffer */
   1073     if (num_lowpri_links > low_quota)
   1074     {
   1075         l2cb.ble_round_robin_quota = low_quota;
   1076         qq = qq_remainder = 0;
   1077     }
   1078     /* If each low priority link can have at least one buffer */
   1079     else if (num_lowpri_links > 0)
   1080     {
   1081         l2cb.ble_round_robin_quota = 0;
   1082         l2cb.ble_round_robin_unacked = 0;
   1083         qq = low_quota / num_lowpri_links;
   1084         qq_remainder = low_quota % num_lowpri_links;
   1085     }
   1086     /* If no low priority link */
   1087     else
   1088     {
   1089         l2cb.ble_round_robin_quota = 0;
   1090         l2cb.ble_round_robin_unacked = 0;
   1091         qq = qq_remainder = 0;
   1092     }
   1093     L2CAP_TRACE_EVENT ("l2c_ble_link_adjust_allocation  num_hipri: %u  num_lowpri: %u  low_quota: %u  round_robin_quota: %u  qq: %u",
   1094                         num_hipri_links, num_lowpri_links, low_quota,
   1095                         l2cb.ble_round_robin_quota, qq);
   1096 
   1097     /* Now, assign the quotas to each link */
   1098     for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++)
   1099     {
   1100         if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE)
   1101         {
   1102             if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
   1103             {
   1104                 p_lcb->link_xmit_quota   = high_pri_link_quota;
   1105             }
   1106             else
   1107             {
   1108                 /* Safety check in case we switched to round-robin with something outstanding */
   1109                 /* if sent_not_acked is added into round_robin_unacked then don't add it again */
   1110                 /* l2cap keeps updating sent_not_acked for exiting from round robin */
   1111                 if (( p_lcb->link_xmit_quota > 0 )&&( qq == 0 ))
   1112                     l2cb.ble_round_robin_unacked += p_lcb->sent_not_acked;
   1113 
   1114                 p_lcb->link_xmit_quota   = qq;
   1115                 if (qq_remainder > 0)
   1116                 {
   1117                     p_lcb->link_xmit_quota++;
   1118                     qq_remainder--;
   1119                 }
   1120             }
   1121 
   1122             L2CAP_TRACE_EVENT("l2c_ble_link_adjust_allocation LCB %d   Priority: %d  XmitQuota: %d",
   1123                                 yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
   1124 
   1125             L2CAP_TRACE_EVENT("        SentNotAcked: %d  RRUnacked: %d",
   1126                                 p_lcb->sent_not_acked, l2cb.round_robin_unacked);
   1127 
   1128             /* There is a special case where we have readjusted the link quotas and  */
   1129             /* this link may have sent anything but some other link sent packets so  */
   1130             /* so we may need a timer to kick off this link's transmissions.         */
   1131             if ( (p_lcb->link_state == LST_CONNECTED)
   1132               && (!list_is_empty(p_lcb->link_xmit_data_q))
   1133                  && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota) ) {
   1134                 alarm_set_on_queue(p_lcb->l2c_lcb_timer,
   1135                                    L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
   1136                                    l2c_lcb_timer_timeout, p_lcb,
   1137                                    btu_general_alarm_queue);
   1138             }
   1139         }
   1140     }
   1141 }
   1142 
   1143 #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
   1144 /*******************************************************************************
   1145 **
   1146 ** Function         l2cble_process_rc_param_request_evt
   1147 **
   1148 ** Description      process LE Remote Connection Parameter Request Event.
   1149 **
   1150 ** Returns          void
   1151 **
   1152 *******************************************************************************/
   1153 void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
   1154                                      UINT16 latency, UINT16 timeout)
   1155 {
   1156     tL2C_LCB    *p_lcb = l2cu_find_lcb_by_handle (handle);
   1157 
   1158     if (p_lcb != NULL)
   1159     {
   1160         p_lcb->min_interval = int_min;
   1161         p_lcb->max_interval = int_max;
   1162         p_lcb->latency = latency;
   1163         p_lcb->timeout = timeout;
   1164 
   1165         /* if update is enabled, always accept connection parameter update */
   1166         if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0)
   1167         {
   1168             btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
   1169         }
   1170         else
   1171         {
   1172             L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled");
   1173             p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
   1174             btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL);
   1175         }
   1176 
   1177     }
   1178     else
   1179     {
   1180         L2CAP_TRACE_WARNING("No link to update connection parameter")
   1181     }
   1182 }
   1183 #endif
   1184 
   1185 /*******************************************************************************
   1186 **
   1187 ** Function         l2cble_update_data_length
   1188 **
   1189 ** Description      This function update link tx data length if applicable
   1190 **
   1191 ** Returns          void
   1192 **
   1193 *******************************************************************************/
   1194 void l2cble_update_data_length(tL2C_LCB *p_lcb)
   1195 {
   1196     UINT16 tx_mtu = 0;
   1197     UINT16 i = 0;
   1198 
   1199     L2CAP_TRACE_DEBUG("%s", __FUNCTION__);
   1200 
   1201     /* See if we have a link control block for the connection */
   1202     if (p_lcb == NULL)
   1203         return;
   1204 
   1205     for (i = 0; i < L2CAP_NUM_FIXED_CHNLS; i++)
   1206     {
   1207         if (i + L2CAP_FIRST_FIXED_CHNL != L2CAP_BLE_SIGNALLING_CID)
   1208         {
   1209             if ((p_lcb->p_fixed_ccbs[i] != NULL) &&
   1210                     (tx_mtu < (p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD)))
   1211                 tx_mtu = p_lcb->p_fixed_ccbs[i]->tx_data_len + L2CAP_PKT_OVERHEAD;
   1212         }
   1213     }
   1214 
   1215     if (tx_mtu > BTM_BLE_DATA_SIZE_MAX)
   1216         tx_mtu = BTM_BLE_DATA_SIZE_MAX;
   1217 
   1218     /* update TX data length if changed */
   1219     if (p_lcb->tx_data_len != tx_mtu)
   1220         BTM_SetBleDataLength(p_lcb->remote_bd_addr, tx_mtu);
   1221 
   1222 }
   1223 
   1224 /*******************************************************************************
   1225 **
   1226 ** Function         l2cble_process_data_length_change_evt
   1227 **
   1228 ** Description      This function process the data length change event
   1229 **
   1230 ** Returns          void
   1231 **
   1232 *******************************************************************************/
   1233 void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len, UINT16 rx_data_len)
   1234 {
   1235     tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
   1236 
   1237     L2CAP_TRACE_DEBUG("%s TX data len = %d", __FUNCTION__, tx_data_len);
   1238     if (p_lcb == NULL)
   1239         return;
   1240 
   1241     if (tx_data_len > 0)
   1242         p_lcb->tx_data_len = tx_data_len;
   1243 
   1244     /* ignore rx_data len for now */
   1245 }
   1246 
   1247 /*******************************************************************************
   1248 **
   1249 ** Function         l2cble_set_fixed_channel_tx_data_length
   1250 **
   1251 ** Description      This function update max fixed channel tx data length if applicable
   1252 **
   1253 ** Returns          void
   1254 **
   1255 *******************************************************************************/
   1256 void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, UINT16 tx_mtu)
   1257 {
   1258     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(remote_bda, BT_TRANSPORT_LE);
   1259     UINT16 cid = fix_cid - L2CAP_FIRST_FIXED_CHNL;
   1260 
   1261     L2CAP_TRACE_DEBUG("%s TX MTU = %d", __FUNCTION__, tx_mtu);
   1262 
   1263     if (!controller_get_interface()->supports_ble_packet_extension())
   1264     {
   1265         L2CAP_TRACE_WARNING("%s, request not supported", __FUNCTION__);
   1266         return;
   1267     }
   1268 
   1269     /* See if we have a link control block for the connection */
   1270     if (p_lcb == NULL)
   1271         return;
   1272 
   1273     if (p_lcb->p_fixed_ccbs[cid] != NULL)
   1274     {
   1275         if (tx_mtu > BTM_BLE_DATA_SIZE_MAX)
   1276             tx_mtu = BTM_BLE_DATA_SIZE_MAX;
   1277 
   1278         p_lcb->p_fixed_ccbs[cid]->tx_data_len = tx_mtu;
   1279     }
   1280 
   1281     l2cble_update_data_length(p_lcb);
   1282 }
   1283 
   1284 /*******************************************************************************
   1285 **
   1286 ** Function         l2cble_credit_based_conn_req
   1287 **
   1288 ** Description      This function sends LE Credit Based Connection Request for
   1289 **                  LE connection oriented channels.
   1290 **
   1291 ** Returns          void
   1292 **
   1293 *******************************************************************************/
   1294 void l2cble_credit_based_conn_req (tL2C_CCB *p_ccb)
   1295 {
   1296     if (!p_ccb)
   1297         return;
   1298 
   1299     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
   1300     {
   1301         L2CAP_TRACE_WARNING ("LE link doesn't exist");
   1302         return;
   1303     }
   1304 
   1305     l2cu_send_peer_ble_credit_based_conn_req (p_ccb);
   1306     return;
   1307 }
   1308 
   1309 /*******************************************************************************
   1310 **
   1311 ** Function         l2cble_credit_based_conn_res
   1312 **
   1313 ** Description      This function sends LE Credit Based Connection Response for
   1314 **                  LE connection oriented channels.
   1315 **
   1316 ** Returns          void
   1317 **
   1318 *******************************************************************************/
   1319 void l2cble_credit_based_conn_res (tL2C_CCB *p_ccb, UINT16 result)
   1320 {
   1321     if (!p_ccb)
   1322         return;
   1323 
   1324     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
   1325     {
   1326         L2CAP_TRACE_WARNING ("LE link doesn't exist");
   1327         return;
   1328     }
   1329 
   1330     l2cu_send_peer_ble_credit_based_conn_res (p_ccb, result);
   1331     return;
   1332 }
   1333 
   1334 /*******************************************************************************
   1335 **
   1336 ** Function         l2cble_send_flow_control_credit
   1337 **
   1338 ** Description      This function sends flow control credits for
   1339 **                  LE connection oriented channels.
   1340 **
   1341 ** Returns          void
   1342 **
   1343 *******************************************************************************/
   1344 void l2cble_send_flow_control_credit(tL2C_CCB *p_ccb, UINT16 credit_value)
   1345 {
   1346     if (!p_ccb)
   1347         return;
   1348 
   1349     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
   1350     {
   1351         L2CAP_TRACE_WARNING ("LE link doesn't exist");
   1352         return;
   1353     }
   1354 
   1355     l2cu_send_peer_ble_flow_control_credit(p_ccb, credit_value);
   1356     return;
   1357 
   1358 }
   1359 
   1360 /*******************************************************************************
   1361 **
   1362 ** Function         l2cble_send_peer_disc_req
   1363 **
   1364 ** Description      This function sends disconnect request
   1365 **                  to the peer LE device
   1366 **
   1367 ** Returns          void
   1368 **
   1369 *******************************************************************************/
   1370 void l2cble_send_peer_disc_req(tL2C_CCB *p_ccb)
   1371 {
   1372     L2CAP_TRACE_DEBUG ("%s",__func__);
   1373     if (!p_ccb)
   1374         return;
   1375 
   1376     if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE)
   1377     {
   1378         L2CAP_TRACE_WARNING ("LE link doesn't exist");
   1379         return;
   1380     }
   1381 
   1382     l2cu_send_peer_ble_credit_based_disconn_req(p_ccb);
   1383     return;
   1384 }
   1385 
   1386 /*******************************************************************************
   1387 **
   1388 ** Function         l2cble_sec_comp
   1389 **
   1390 ** Description      This function is called when security procedure for an LE COC
   1391 **                  link is done
   1392 **
   1393 ** Returns          void
   1394 **
   1395 *******************************************************************************/
   1396 void  l2cble_sec_comp(BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data, UINT8 status)
   1397 {
   1398     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, BT_TRANSPORT_LE);
   1399     tL2CAP_SEC_DATA *p_buf = NULL;
   1400     UINT8 sec_flag;
   1401     UINT8 sec_act;
   1402 
   1403     if (!p_lcb)
   1404     {
   1405         L2CAP_TRACE_WARNING ("%s security complete for unknown device", __func__);
   1406         return;
   1407     }
   1408 
   1409     sec_act = p_lcb->sec_act;
   1410     p_lcb->sec_act = 0;
   1411 
   1412     if (!fixed_queue_is_empty(p_lcb->le_sec_pending_q))
   1413     {
   1414         p_buf = (tL2CAP_SEC_DATA*) fixed_queue_dequeue(p_lcb->le_sec_pending_q);
   1415         if (!p_buf)
   1416         {
   1417             L2CAP_TRACE_WARNING ("%s Security complete for request not initiated from L2CAP",
   1418                     __func__);
   1419             return;
   1420         }
   1421 
   1422         if (status != BTM_SUCCESS)
   1423         {
   1424             (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
   1425         }
   1426         else
   1427         {
   1428             if (sec_act == BTM_SEC_ENCRYPT_MITM)
   1429             {
   1430                 BTM_GetSecurityFlagsByTransport(p_bda, &sec_flag, transport);
   1431                 if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
   1432                     (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
   1433                 else
   1434                 {
   1435                     L2CAP_TRACE_DEBUG ("%s MITM Protection Not present", __func__);
   1436                     (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data,
   1437                             BTM_FAILED_ON_SECURITY);
   1438                 }
   1439             }
   1440             else
   1441             {
   1442                 L2CAP_TRACE_DEBUG ("%s MITM Protection not required sec_act = %d",
   1443                         __func__, p_lcb->sec_act);
   1444 
   1445                 (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
   1446             }
   1447         }
   1448     }
   1449     else
   1450     {
   1451         L2CAP_TRACE_WARNING ("%s Security complete for request not initiated from L2CAP", __func__);
   1452         return;
   1453     }
   1454     osi_free(p_buf);
   1455 
   1456     while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q))
   1457     {
   1458         p_buf = (tL2CAP_SEC_DATA*) fixed_queue_dequeue(p_lcb->le_sec_pending_q);
   1459 
   1460         if (status != BTM_SUCCESS)
   1461             (*(p_buf->p_callback))(p_bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status);
   1462         else
   1463             l2ble_sec_access_req(p_bda, p_buf->psm, p_buf->is_originator,
   1464                     p_buf->p_callback, p_buf->p_ref_data);
   1465 
   1466        osi_free(p_buf);
   1467     }
   1468 }
   1469 
   1470 /*******************************************************************************
   1471 **
   1472 ** Function         l2ble_sec_access_req
   1473 **
   1474 ** Description      This function is called by LE COC link to meet the
   1475 **                  security requirement for the link
   1476 **
   1477 ** Returns          TRUE - security procedures are started
   1478 **                  FALSE - failure
   1479 **
   1480 *******************************************************************************/
   1481 BOOLEAN l2ble_sec_access_req(BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originator, tL2CAP_SEC_CBACK *p_callback, void *p_ref_data)
   1482 {
   1483     L2CAP_TRACE_DEBUG ("%s", __func__);
   1484     BOOLEAN status;
   1485     tL2C_LCB *p_lcb = NULL;
   1486 
   1487     if (!p_callback)
   1488     {
   1489         L2CAP_TRACE_ERROR("%s No callback function", __func__);
   1490         return FALSE;
   1491     }
   1492 
   1493     p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
   1494 
   1495     if (!p_lcb)
   1496     {
   1497         L2CAP_TRACE_ERROR ("%s Security check for unknown device", __func__);
   1498         p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_UNKNOWN_ADDR);
   1499         return FALSE;
   1500     }
   1501 
   1502     tL2CAP_SEC_DATA *p_buf = (tL2CAP_SEC_DATA*) osi_malloc((UINT16)sizeof(tL2CAP_SEC_DATA));
   1503     if (!p_buf)
   1504     {
   1505         p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_NO_RESOURCES);
   1506         return FALSE;
   1507     }
   1508 
   1509     p_buf->psm = psm;
   1510     p_buf->is_originator = is_originator;
   1511     p_buf->p_callback = p_callback;
   1512     p_buf->p_ref_data = p_ref_data;
   1513     fixed_queue_enqueue(p_lcb->le_sec_pending_q, p_buf);
   1514     status = btm_ble_start_sec_check(bd_addr, psm, is_originator, &l2cble_sec_comp, p_ref_data);
   1515 
   1516     return status;
   1517 }
   1518 #endif /* (BLE_INCLUDED == TRUE) */
   1519