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