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