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 (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 *******************************************************************************/
L2CA_UpdateBleConnParams(BD_ADDR rem_bda,UINT16 min_int,UINT16 max_int,UINT16 latency,UINT16 timeout)96 BOOLEAN 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 *******************************************************************************/
L2CA_EnableUpdateBleConnParams(BD_ADDR rem_bda,BOOLEAN enable)138 BOOLEAN 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 *******************************************************************************/
L2CA_GetBleConnRole(BD_ADDR bd_addr)208 UINT8 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 *******************************************************************************/
L2CA_GetDisconnectReason(BD_ADDR remote_bda)228 UINT16 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 *******************************************************************************/
l2cble_scanner_conn_comp(UINT16 handle,BD_ADDR bda,tBLE_ADDR_TYPE type,UINT16 conn_interval,UINT16 conn_latency,UINT16 conn_timeout)251 void 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 *******************************************************************************/
l2cble_advertiser_conn_comp(UINT16 handle,BD_ADDR bda,tBLE_ADDR_TYPE type,UINT16 conn_interval,UINT16 conn_latency,UINT16 conn_timeout)351 void 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 *******************************************************************************/
l2cble_conn_comp(UINT16 handle,UINT8 role,BD_ADDR bda,tBLE_ADDR_TYPE type,UINT16 conn_interval,UINT16 conn_latency,UINT16 conn_timeout)409 void 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 *******************************************************************************/
l2cble_process_sig_cmd(tL2C_LCB * p_lcb,UINT8 * p,UINT16 pkt_len)431 void 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 *******************************************************************************/
l2cble_init_direct_conn(tL2C_LCB * p_lcb)529 BOOLEAN 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 *******************************************************************************/
l2cble_create_conn(tL2C_LCB * p_lcb)588 BOOLEAN 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 *******************************************************************************/
l2c_link_processs_ble_num_bufs(UINT16 num_lm_ble_bufs)623 void 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