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