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 "l2cdefs.h"
     28 #include "l2c_int.h"
     29 #include "btu.h"
     30 #include "btm_int.h"
     31 #include "hcimsgs.h"
     32 
     33 #if (BLE_INCLUDED == TRUE)
     34 
     35 /*******************************************************************************
     36 **
     37 **  Function        L2CA_CancelBleConnectReq
     38 **
     39 **  Description     Cancel a pending connection attempt to a BLE device.
     40 **
     41 **  Parameters:     BD Address of remote
     42 **
     43 **  Return value:   TRUE if connection was cancelled
     44 **
     45 *******************************************************************************/
     46 BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
     47 {
     48     tL2C_LCB *p_lcb;
     49 
     50     /* There can be only one BLE connection request outstanding at a time */
     51     if (!l2cb.is_ble_connecting)
     52     {
     53         L2CAP_TRACE_WARNING0 ("L2CA_CancelBleConnectReq - no connection pending");
     54         return(FALSE);
     55     }
     56 
     57     if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN))
     58     {
     59         L2CAP_TRACE_WARNING4 ("L2CA_CancelBleConnectReq - different  BDA Connecting: %08x%04x  Cancel: %08x%04x",
     60                               (l2cb.ble_connecting_bda[0]<<24)+(l2cb.ble_connecting_bda[1]<<16)+(l2cb.ble_connecting_bda[2]<<8)+l2cb.ble_connecting_bda[3],
     61                               (l2cb.ble_connecting_bda[4]<<8)+l2cb.ble_connecting_bda[5],
     62                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
     63 
     64         return(FALSE);
     65     }
     66 
     67     if (btsnd_hcic_ble_create_conn_cancel())
     68     {
     69 
     70         if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL)
     71         {
     72             p_lcb->disc_reason = L2CAP_CONN_CANCEL;
     73             l2cu_release_lcb (p_lcb);
     74         }
     75 
     76         l2cb.is_ble_connecting = FALSE;
     77         btm_ble_update_bg_state();
     78         btm_ble_resume_bg_conn(NULL, TRUE);
     79 
     80         return(TRUE);
     81     }
     82     else
     83         return(FALSE);
     84 }
     85 
     86 
     87 /*******************************************************************************
     88 **
     89 **  Function        L2CA_UpdateBleConnParams
     90 **
     91 **  Description     Update BLE connection parameters.
     92 **
     93 **  Parameters:     BD Address of remote
     94 **
     95 **  Return value:   TRUE if update started
     96 **
     97 *******************************************************************************/
     98 BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout)
     99 {
    100     tL2C_LCB            *p_lcb;
    101 
    102     /* See if we have a link control block for the remote device */
    103     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
    104 
    105     /* If we don't have one, create one and accept the connection. */
    106     if (!p_lcb)
    107     {
    108         L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
    109                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
    110         return(FALSE);
    111     }
    112 
    113     if (!p_lcb->is_ble_link)
    114     {
    115         L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
    116                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
    117         return(FALSE);
    118     }
    119 
    120     if (p_lcb->link_role == HCI_ROLE_MASTER)
    121         btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, latency, timeout, 0, 0);
    122     else
    123         l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
    124 
    125     return(TRUE);
    126 }
    127 
    128 
    129 /*******************************************************************************
    130 **
    131 **  Function        L2CA_EnableUpdateBleConnParams
    132 **
    133 **  Description     Enable or disable update based on the request from the peer
    134 **
    135 **  Parameters:     BD Address of remote
    136 **
    137 **  Return value:   TRUE if update started
    138 **
    139 *******************************************************************************/
    140 BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
    141 {
    142     tL2C_LCB            *p_lcb;
    143 
    144     /* See if we have a link control block for the remote device */
    145     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
    146 
    147     /* If we don't have one, create one and accept the connection. */
    148     if (!p_lcb)
    149     {
    150         L2CAP_TRACE_WARNING2 ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
    151             (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
    152         return (FALSE);
    153     }
    154 
    155     L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d current upd state %d",
    156         (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->upd_disabled);
    157 
    158     if (!p_lcb->is_ble_link || (p_lcb->link_role != HCI_ROLE_MASTER))
    159     {
    160         L2CAP_TRACE_WARNING3 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x not LE or not master %d",
    161                               (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
    162         return (FALSE);
    163     }
    164 
    165     if (enable)
    166     {
    167         /* application allows to do update, if we were delaying one do it now, otherwise
    168         just mark lcb that updates are enabled */
    169         if (p_lcb->upd_disabled == UPD_PENDING)
    170         {
    171             btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
    172                                                p_lcb->latency, p_lcb->timeout, 0, 0);
    173             p_lcb->upd_disabled = UPD_UPDATED;
    174         }
    175         else
    176         {
    177             p_lcb->upd_disabled = UPD_ENABLED;
    178         }
    179     }
    180     else
    181     {
    182         /* application requests to disable parameters update.  If parameters are already updated, lets set them
    183         up to what has been requested during connection establishement */
    184         if (p_lcb->upd_disabled == UPD_UPDATED)
    185         {
    186             tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (rem_bda);
    187 
    188             btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
    189                 (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.min_conn_int : L2CAP_LE_INT_MIN),
    190                 (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.max_conn_int : L2CAP_LE_INT_MAX),
    191                 (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.slave_latency : 0),
    192                 (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.supervision_tout : L2CAP_LE_TIMEOUT_MAX),
    193                 0, 0);
    194         }
    195         p_lcb->upd_disabled = UPD_DISABLED;
    196     }
    197 
    198     return (TRUE);
    199 }
    200 
    201 /*******************************************************************************
    202 **
    203 ** Function         L2CA_GetBleConnRole
    204 **
    205 ** Description      This function returns the connection role.
    206 **
    207 ** Returns          link role.
    208 **
    209 *******************************************************************************/
    210 UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr)
    211 {
    212     UINT8       role = HCI_ROLE_UNKNOWN;
    213 
    214     tL2C_LCB *p_lcb;
    215 
    216     if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) != NULL)
    217         role = p_lcb->link_role;
    218 
    219     return role;
    220 }
    221 /*******************************************************************************
    222 **
    223 ** Function         L2CA_GetDisconnectReason
    224 **
    225 ** Description      This function returns the disconnect reason code.
    226 **
    227 ** Returns          disconnect reason
    228 **
    229 *******************************************************************************/
    230 UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda)
    231 {
    232     tL2C_LCB            *p_lcb;
    233     UINT16              reason = 0;
    234 
    235     if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda)) != NULL)
    236         reason = p_lcb->disc_reason;
    237 
    238     L2CAP_TRACE_DEBUG1 ("L2CA_GetDisconnectReason=%d ",reason);
    239 
    240     return reason;
    241 }
    242 
    243 /*******************************************************************************
    244 **
    245 ** Function         l2cble_scanner_conn_comp
    246 **
    247 ** Description      This function is called when an HCI Connection Complete
    248 **                  event is received while we are a scanner (so we are master).
    249 **
    250 ** Returns          void
    251 **
    252 *******************************************************************************/
    253 void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
    254 {
    255     tL2C_LCB            *p_lcb;
    256     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (bda);
    257 
    258     L2CAP_TRACE_DEBUG5 ("l2cble_scanner_conn_comp: HANDLE=%d addr_type=%d conn_interval=%d slave_latency=%d supervision_tout=%d",
    259                         handle,  type, conn_interval, conn_latency, conn_timeout);
    260 
    261     l2cb.is_ble_connecting = FALSE;
    262 
    263     p_dev_rec->device_type   = BT_DEVICE_TYPE_BLE;
    264     p_dev_rec->ble.ble_addr_type = type;
    265 
    266     /* See if we have a link control block for the remote device */
    267     p_lcb = l2cu_find_lcb_by_bd_addr (bda);
    268 
    269     /* If we don't have one, create one. this is auto connection complete. */
    270     if (!p_lcb)
    271     {
    272         p_lcb = l2cu_allocate_lcb (bda, FALSE);
    273         if (!p_lcb)
    274         {
    275             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    276             L2CAP_TRACE_ERROR0 ("l2cble_scanner_conn_comp - failed to allocate LCB");
    277             return;
    278         }
    279         else
    280         {
    281             if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
    282             {
    283                 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    284                 L2CAP_TRACE_WARNING0 ("l2cble_scanner_conn_comp - LCB but no CCB");
    285                 return ;
    286             }
    287         }
    288     }
    289     else if (p_lcb->link_state != LST_CONNECTING)
    290     {
    291         L2CAP_TRACE_ERROR1 ("L2CAP got BLE scanner conn_comp in bad state: %d", p_lcb->link_state);
    292         return;
    293     }
    294     btu_stop_timer(&p_lcb->timer_entry);
    295 
    296     /* Save the handle */
    297     p_lcb->handle = handle;
    298 
    299     /* Connected OK. Change state to connected, we were scanning so we are master */
    300     p_lcb->link_state = LST_CONNECTED;
    301     p_lcb->link_role  = HCI_ROLE_MASTER;
    302     p_lcb->is_ble_link = TRUE;
    303 
    304     /* If there are any preferred connection parameters, set them now */
    305     if ( (p_dev_rec->conn_params.min_conn_int     >= L2CAP_LE_INT_MIN ) &&
    306          (p_dev_rec->conn_params.min_conn_int     <= L2CAP_LE_INT_MAX ) &&
    307          (p_dev_rec->conn_params.max_conn_int     >= L2CAP_LE_INT_MIN ) &&
    308          (p_dev_rec->conn_params.max_conn_int     <= L2CAP_LE_INT_MAX ) &&
    309          (p_dev_rec->conn_params.slave_latency    <= L2CAP_LE_LATENCY_MAX ) &&
    310          (p_dev_rec->conn_params.supervision_tout >= L2CAP_LE_TIMEOUT_MIN) &&
    311          (p_dev_rec->conn_params.supervision_tout <= L2CAP_LE_TIMEOUT_MAX) &&
    312          ((conn_interval < p_dev_rec->conn_params.min_conn_int &&
    313           p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
    314           (conn_interval > p_dev_rec->conn_params.max_conn_int) ||
    315           (conn_latency > p_dev_rec->conn_params.slave_latency) ||
    316           (conn_timeout > p_dev_rec->conn_params.supervision_tout)))
    317     {
    318         L2CAP_TRACE_ERROR5 ("upd_ll_conn_params: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d",
    319                             handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int,
    320                             p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout);
    321 
    322         btsnd_hcic_ble_upd_ll_conn_params (handle,
    323                                            p_dev_rec->conn_params.min_conn_int,
    324                                            p_dev_rec->conn_params.max_conn_int,
    325                                            p_dev_rec->conn_params.slave_latency,
    326                                            p_dev_rec->conn_params.supervision_tout,
    327                                            0, 0);
    328     }
    329 
    330     /* Tell BTM Acl management about the link */
    331     btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE);
    332 
    333     if (p_lcb->p_echo_rsp_cb)
    334     {
    335         L2CAP_TRACE_ERROR0 ("l2cu_send_peer_echo_req");
    336         l2cu_send_peer_echo_req (p_lcb, NULL, 0);
    337     }
    338 
    339     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
    340 
    341     l2cu_process_fixed_chnl_resp (p_lcb);
    342 }
    343 
    344 
    345 /*******************************************************************************
    346 **
    347 ** Function         l2cble_advertiser_conn_comp
    348 **
    349 ** Description      This function is called when an HCI Connection Complete
    350 **                  event is received while we are an advertiser (so we are slave).
    351 **
    352 ** Returns          void
    353 **
    354 *******************************************************************************/
    355 void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
    356                                   UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
    357 {
    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);
    363 
    364     /* If we don't have one, create one and accept the connection. */
    365     if (!p_lcb)
    366     {
    367         p_lcb = l2cu_allocate_lcb (bda, FALSE);
    368         if (!p_lcb)
    369         {
    370             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    371             L2CAP_TRACE_ERROR0 ("l2cble_advertiser_conn_comp - failed to allocate LCB");
    372             return;
    373         }
    374         else
    375         {
    376             if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
    377             {
    378                 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
    379                 L2CAP_TRACE_WARNING0 ("l2cble_scanner_conn_comp - LCB but no CCB");
    380                 return ;
    381             }
    382         }
    383     }
    384 
    385     /* Save the handle */
    386     p_lcb->handle = handle;
    387 
    388     /* Connected OK. Change state to connected, we were advertising, so we are slave */
    389     p_lcb->link_state = LST_CONNECTED;
    390     p_lcb->link_role  = HCI_ROLE_SLAVE;
    391     p_lcb->is_ble_link = TRUE;
    392 
    393     /* Tell BTM Acl management about the link */
    394     p_dev_rec = btm_find_or_alloc_dev (bda);
    395 
    396     p_dev_rec->device_type   = BT_DEVICE_TYPE_BLE;
    397     p_dev_rec->ble.ble_addr_type = type;
    398 
    399     btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE);
    400 
    401     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
    402 
    403     l2cu_process_fixed_chnl_resp (p_lcb);
    404 }
    405 
    406 /*******************************************************************************
    407 **
    408 ** Function         l2cble_conn_comp
    409 **
    410 ** Description      This function is called when an HCI Connection Complete
    411 **                  event is received.
    412 **
    413 ** Returns          void
    414 **
    415 *******************************************************************************/
    416 void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
    417                       UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
    418 {
    419     if (role == HCI_ROLE_MASTER)
    420     {
    421         l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
    422     }
    423     else
    424     {
    425         l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
    426     }
    427 }
    428 /*******************************************************************************
    429 **
    430 ** Function         l2cble_process_sig_cmd
    431 **
    432 ** Description      This function is called when a signalling packet is received
    433 **                  on the BLE signalling CID
    434 **
    435 ** Returns          void
    436 **
    437 *******************************************************************************/
    438 void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
    439 {
    440     UINT8           *p_pkt_end;
    441     UINT8           cmd_code, id;
    442     UINT16          cmd_len, rej_reason;
    443     UINT16          result;
    444     UINT16          min_interval, max_interval, latency, timeout;
    445 
    446     p_pkt_end = p + pkt_len;
    447 
    448     STREAM_TO_UINT8  (cmd_code, p);
    449     STREAM_TO_UINT8  (id, p);
    450     STREAM_TO_UINT16 (cmd_len, p);
    451 
    452     /* Check command length does not exceed packet length */
    453     if ((p + cmd_len) > p_pkt_end)
    454     {
    455         L2CAP_TRACE_WARNING3 ("L2CAP - LE - format error, pkt_len: %d  cmd_len: %d  code: %d", pkt_len, cmd_len, cmd_code);
    456         return;
    457     }
    458 
    459     switch (cmd_code)
    460     {
    461         case L2CAP_CMD_REJECT:
    462         case L2CAP_CMD_ECHO_RSP:
    463         case L2CAP_CMD_INFO_RSP:
    464             STREAM_TO_UINT16 (rej_reason, p);
    465             break;
    466         case L2CAP_CMD_ECHO_REQ:
    467         case L2CAP_CMD_INFO_REQ:
    468             l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
    469             break;
    470 
    471         case L2CAP_CMD_BLE_UPDATE_REQ:
    472             STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */
    473             STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */
    474             STREAM_TO_UINT16 (latency, p);  /* 0x0000 - 0x03E8 */
    475             STREAM_TO_UINT16 (timeout, p);  /* 0x000A - 0x0C80 */
    476             /* If we are a master, the slave wants to update the parameters */
    477             if (p_lcb->link_role == HCI_ROLE_MASTER)
    478             {
    479                 if (min_interval < L2CAP_LE_INT_MIN || min_interval > L2CAP_LE_INT_MAX ||
    480                     max_interval < L2CAP_LE_INT_MIN || max_interval > L2CAP_LE_INT_MAX ||
    481                     latency  > L2CAP_LE_LATENCY_MAX ||
    482                     /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/
    483                     timeout < L2CAP_LE_TIMEOUT_MIN || timeout > L2CAP_LE_TIMEOUT_MAX ||
    484                     max_interval < min_interval)
    485                 {
    486                     result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
    487                 }
    488                 else
    489                 {
    490 
    491                     l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id);
    492 
    493                     p_lcb->min_interval = min_interval;
    494                     p_lcb->max_interval = max_interval;
    495                     p_lcb->latency = latency;
    496                     p_lcb->timeout = timeout;
    497 
    498                     if (p_lcb->upd_disabled == UPD_ENABLED)
    499                     {
    500                         btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
    501                                                             latency, timeout, 0, 0);
    502                         p_lcb->upd_disabled = UPD_UPDATED;
    503                     }
    504                     else
    505                     {
    506                         L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
    507                         p_lcb->upd_disabled = UPD_PENDING;
    508                     }
    509                 }
    510             }
    511             else
    512                 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
    513             break;
    514 
    515         case L2CAP_CMD_BLE_UPDATE_RSP:
    516             STREAM_TO_UINT16 (result, p);
    517             break;
    518 
    519         default:
    520             L2CAP_TRACE_WARNING1 ("L2CAP - LE - unknown cmd code: %d", cmd_code);
    521             l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
    522             return;
    523     }
    524 }
    525 
    526 
    527 /*******************************************************************************
    528 **
    529 ** Function         l2cble_create_conn
    530 **
    531 ** Description      This function initiates an acl connection via HCI
    532 **
    533 ** Returns          TRUE if successful, FALSE if connection not started.
    534 **
    535 *******************************************************************************/
    536 BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb)
    537 {
    538     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
    539     tBTM_BLE_CB     *p_cb = &btm_cb.ble_ctr_cb;
    540     UINT16          scan_int, scan_win;
    541 
    542     /* There can be only one BLE connection request outstanding at a time */
    543     if (l2cb.is_ble_connecting)
    544     {
    545         L2CAP_TRACE_WARNING0 ("L2CAP - LE - cannot start new connection, already connecting");
    546         return(FALSE);
    547     }
    548 
    549     p_lcb->link_state      = LST_CONNECTING;
    550     l2cb.is_ble_connecting = TRUE;
    551 
    552     memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
    553     btm_ble_suspend_bg_conn();
    554 
    555     scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? L2CAP_LE_INT_MIN : p_cb->scan_int;
    556     scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? L2CAP_LE_INT_MIN : p_cb->scan_win;
    557 
    558     if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int      */
    559                                         scan_win, /* UINT16 scan_win      */
    560                                         FALSE,                   /* UINT8 white_list     */
    561                                         p_lcb->ble_addr_type,    /* UINT8 addr_type_peer */
    562                                         p_lcb->remote_bd_addr,   /* BD_ADDR bda_peer     */
    563                                         BLE_ADDR_PUBLIC,         /* UINT8 addr_type_own  */
    564                                         (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.min_conn_int : L2CAP_LE_INT_MIN),  /* UINT16 conn_int_min  */
    565                                         (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.max_conn_int : L2CAP_LE_INT_MIN),  /* UINT16 conn_int_max  */
    566                                         (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.slave_latency : 0), /* UINT16 conn_latency  */
    567                                         (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.supervision_tout : L2CAP_LE_TIMEOUT_MAX), /* UINT16 conn_timeout  */
    568                                         0,                       /* UINT16 min_len       */
    569                                         0))                      /* UINT16 max_len       */
    570     {
    571         /* No buffer for connection request ? */
    572         l2cb.is_ble_connecting = FALSE;
    573         p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES;
    574         l2cu_release_lcb (p_lcb);
    575         return(FALSE);
    576     }
    577     else
    578         btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
    579 
    580     return(TRUE);
    581 }
    582 
    583 /*******************************************************************************
    584 **
    585 ** Function         l2c_link_processs_ble_num_bufs
    586 **
    587 ** Description      This function is called when a "controller buffer size"
    588 **                  event is first received from the controller. It updates
    589 **                  the L2CAP values.
    590 **
    591 ** Returns          void
    592 **
    593 *******************************************************************************/
    594 void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs)
    595 {
    596     l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs;
    597 }
    598 
    599 #endif /* (BLE_INCLUDED == TRUE) */
    600