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