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