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