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