• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *******************************************************************************/
L2CA_CancelBleConnectReq(BD_ADDR rem_bda)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 *******************************************************************************/
L2CA_UpdateBleConnParams(BD_ADDR rem_bda,UINT16 min_int,UINT16 max_int,UINT16 latency,UINT16 timeout)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 *******************************************************************************/
L2CA_EnableUpdateBleConnParams(BD_ADDR rem_bda,BOOLEAN enable)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 *******************************************************************************/
L2CA_GetBleConnRole(BD_ADDR bd_addr)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 *******************************************************************************/
L2CA_GetDisconnectReason(BD_ADDR remote_bda)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 *******************************************************************************/
l2cble_scanner_conn_comp(UINT16 handle,BD_ADDR bda,tBLE_ADDR_TYPE type,UINT16 conn_interval,UINT16 conn_latency,UINT16 conn_timeout)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 *******************************************************************************/
l2cble_advertiser_conn_comp(UINT16 handle,BD_ADDR bda,tBLE_ADDR_TYPE type,UINT16 conn_interval,UINT16 conn_latency,UINT16 conn_timeout)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 *******************************************************************************/
l2cble_conn_comp(UINT16 handle,UINT8 role,BD_ADDR bda,tBLE_ADDR_TYPE type,UINT16 conn_interval,UINT16 conn_latency,UINT16 conn_timeout)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 *******************************************************************************/
l2cble_process_sig_cmd(tL2C_LCB * p_lcb,UINT8 * p,UINT16 pkt_len)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 *******************************************************************************/
l2cble_create_conn(tL2C_LCB * p_lcb)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 *******************************************************************************/
l2c_link_processs_ble_num_bufs(UINT16 num_lm_ble_bufs)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