blob: 2d7d9e0fe759800bbaaa25e1a28959e9f2a8fd15 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080027#include "bt_utils.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080028#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)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -070035#define L2CA_GET_UPD_ST(x) ((x) & UPD_ST_MASK)
36#define L2CA_SET_UPD_ST(x, y) x = (((x) & ~UPD_ST_MASK) | (y))
37
The Android Open Source Project5738f832012-12-12 16:00:35 -080038
Wei Wanged534e32014-05-20 06:30:13 +000039#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE)
40#include "vendor_ble.h"
41#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -080042/*******************************************************************************
43**
44** Function L2CA_CancelBleConnectReq
45**
46** Description Cancel a pending connection attempt to a BLE device.
47**
48** Parameters: BD Address of remote
49**
50** Return value: TRUE if connection was cancelled
51**
52*******************************************************************************/
53BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
54{
55 tL2C_LCB *p_lcb;
56
57 /* There can be only one BLE connection request outstanding at a time */
Andre Eisenbach6975b4d2013-08-05 16:55:38 -070058 if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
The Android Open Source Project5738f832012-12-12 16:00:35 -080059 {
60 L2CAP_TRACE_WARNING0 ("L2CA_CancelBleConnectReq - no connection pending");
61 return(FALSE);
62 }
63
64 if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN))
65 {
66 L2CAP_TRACE_WARNING4 ("L2CA_CancelBleConnectReq - different BDA Connecting: %08x%04x Cancel: %08x%04x",
67 (l2cb.ble_connecting_bda[0]<<24)+(l2cb.ble_connecting_bda[1]<<16)+(l2cb.ble_connecting_bda[2]<<8)+l2cb.ble_connecting_bda[3],
68 (l2cb.ble_connecting_bda[4]<<8)+l2cb.ble_connecting_bda[5],
69 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
70
71 return(FALSE);
72 }
73
74 if (btsnd_hcic_ble_create_conn_cancel())
75 {
76
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -070077 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE)) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -080078 {
79 p_lcb->disc_reason = L2CAP_CONN_CANCEL;
80 l2cu_release_lcb (p_lcb);
81 }
Andre Eisenbach6975b4d2013-08-05 16:55:38 -070082 /* update state to be cancel, wait for connection cancel complete */
83 btm_ble_set_conn_st (BLE_CONN_CANCEL);
The Android Open Source Project5738f832012-12-12 16:00:35 -080084
85 return(TRUE);
86 }
87 else
88 return(FALSE);
89}
90
Zhihai Xu15d0a0c2013-12-17 20:33:09 -080091/*******************************************************************************
92**
The Android Open Source Project5738f832012-12-12 16:00:35 -080093** Function L2CA_UpdateBleConnParams
94**
95** Description Update BLE connection parameters.
96**
97** Parameters: BD Address of remote
98**
99** Return value: TRUE if update started
100**
101*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700102BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int,
103 UINT16 latency, UINT16 timeout)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800104{
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700105 tL2C_LCB *p_lcb;
106 tACL_CONN *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800107
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700108 /* See if we have a link control block for the remote device */
109 p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800110
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700111 /* If we don't have one, create one and accept the connection. */
112 if (!p_lcb || !p_acl_cb)
113 {
114 L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
115 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
116 (rem_bda[4]<<8)+rem_bda[5]);
117 return(FALSE);
118 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800119
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700120 if (p_lcb->transport != BT_TRANSPORT_LE)
121 {
122 L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
123 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
124 (rem_bda[4]<<8)+rem_bda[5]);
125 return(FALSE);
126 }
127#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
128 /* if both 4.1 compliant */
129 if ((HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) &&
130 HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)))
131 {
132 /* TODO: CE length selection ?? */
133 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
134 latency, timeout, 0, 0);
135 }
136 else
137 /* if either side does not support Connection Parameters Request
138 Link Layer Control Procedure,
139 use Link Layer Connection Update procedure */
140#endif
141 {
142 if (p_lcb->link_role == HCI_ROLE_MASTER)
143 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
144 latency, timeout, 0, 0);
145 else
146 l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
147 }
148 return(TRUE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800149
The Android Open Source Project5738f832012-12-12 16:00:35 -0800150}
151
152
153/*******************************************************************************
154**
155** Function L2CA_EnableUpdateBleConnParams
156**
157** Description Enable or disable update based on the request from the peer
158**
159** Parameters: BD Address of remote
160**
161** Return value: TRUE if update started
162**
163*******************************************************************************/
164BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
165{
166 tL2C_LCB *p_lcb;
167
168 /* See if we have a link control block for the remote device */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700169 p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800170
The Android Open Source Project5738f832012-12-12 16:00:35 -0800171 if (!p_lcb)
172 {
173 L2CAP_TRACE_WARNING2 ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700174 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
175 (rem_bda[4]<<8)+rem_bda[5]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800176 return (FALSE);
177 }
178
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700179 L2CAP_TRACE_API5 ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__,
180 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
181 (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800182
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700183 if (p_lcb->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800184 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700185 L2CAP_TRACE_WARNING4 ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__,
186 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
187 (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800188 return (FALSE);
189 }
190
191 if (enable)
192 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700193 if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) == UPD_DISABLED)
194 {
195 p_lcb->conn_param_enb.param = (TIMER_PARAM_TYPE)p_lcb;
196 btu_start_timer (&p_lcb->conn_param_enb, BTU_TTYPE_L2CAP_END_CONN_UPD,
197 L2CAP_BLE_ENB_CONN_PARAM_TOUT);
198 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENB_TOUT);
199 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800200 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700201 else if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) != UPD_DISABLED)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800202 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700203 btu_stop_timer(&p_lcb->conn_param_enb);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800204
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700205 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
206 {
207
208 /*
209 application requests to disable parameters update.If parameters are already updated,
210 lets set them up to what has been requested during connection establishement
211 */
212 if ((p_lcb->conn_update_mask & UPD_REQUEST) != 0)
213 {
214 /* revert back to default */
215 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
216 BTM_BLE_CONN_INT_MIN_DEF,
217 BTM_BLE_CONN_INT_MAX_DEF,
218 BTM_BLE_CONN_SLAVE_LATENCY_DEF,
219 BTM_BLE_CONN_TIMEOUT_DEF,
220 0, 0);
221 }
222 }
223 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_DISABLED);
224
225 }
Zhihai Xu15d0a0c2013-12-17 20:33:09 -0800226
The Android Open Source Project5738f832012-12-12 16:00:35 -0800227 return (TRUE);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700228
The Android Open Source Project5738f832012-12-12 16:00:35 -0800229}
230
Zhihai Xu15d0a0c2013-12-17 20:33:09 -0800231
232/*******************************************************************************
233**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800234** Function L2CA_GetBleConnRole
235**
236** Description This function returns the connection role.
237**
238** Returns link role.
239**
240*******************************************************************************/
241UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr)
242{
243 UINT8 role = HCI_ROLE_UNKNOWN;
244
245 tL2C_LCB *p_lcb;
246
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700247 if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800248 role = p_lcb->link_role;
249
250 return role;
251}
252/*******************************************************************************
253**
254** Function L2CA_GetDisconnectReason
255**
256** Description This function returns the disconnect reason code.
257**
258** Returns disconnect reason
259**
260*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700261UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800262{
263 tL2C_LCB *p_lcb;
264 UINT16 reason = 0;
265
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700266 if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800267 reason = p_lcb->disc_reason;
268
269 L2CAP_TRACE_DEBUG1 ("L2CA_GetDisconnectReason=%d ",reason);
270
271 return reason;
272}
273
274/*******************************************************************************
275**
276** Function l2cble_scanner_conn_comp
277**
278** Description This function is called when an HCI Connection Complete
279** event is received while we are a scanner (so we are master).
280**
281** Returns void
282**
283*******************************************************************************/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800284void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
285 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800286{
287 tL2C_LCB *p_lcb;
288 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda);
289
290 L2CAP_TRACE_DEBUG5 ("l2cble_scanner_conn_comp: HANDLE=%d addr_type=%d conn_interval=%d slave_latency=%d supervision_tout=%d",
291 handle, type, conn_interval, conn_latency, conn_timeout);
292
293 l2cb.is_ble_connecting = FALSE;
294
The Android Open Source Project5738f832012-12-12 16:00:35 -0800295 /* See if we have a link control block for the remote device */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700296 p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800297
298 /* If we don't have one, create one. this is auto connection complete. */
299 if (!p_lcb)
300 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700301 p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800302 if (!p_lcb)
303 {
304 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
305 L2CAP_TRACE_ERROR0 ("l2cble_scanner_conn_comp - failed to allocate LCB");
306 return;
307 }
308 else
309 {
310 if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
311 {
312 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
313 L2CAP_TRACE_WARNING0 ("l2cble_scanner_conn_comp - LCB but no CCB");
314 return ;
315 }
316 }
317 }
318 else if (p_lcb->link_state != LST_CONNECTING)
319 {
320 L2CAP_TRACE_ERROR1 ("L2CAP got BLE scanner conn_comp in bad state: %d", p_lcb->link_state);
321 return;
322 }
323 btu_stop_timer(&p_lcb->timer_entry);
324
325 /* Save the handle */
326 p_lcb->handle = handle;
327
328 /* Connected OK. Change state to connected, we were scanning so we are master */
329 p_lcb->link_state = LST_CONNECTED;
330 p_lcb->link_role = HCI_ROLE_MASTER;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700331 p_lcb->transport = BT_TRANSPORT_LE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800332
333 /* If there are any preferred connection parameters, set them now */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800334 if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
335 (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
336 (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
337 (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
338 (p_dev_rec->conn_params.slave_latency <= BTM_BLE_CONN_LATENCY_MAX ) &&
339 (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
340 (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
The Android Open Source Project5738f832012-12-12 16:00:35 -0800341 ((conn_interval < p_dev_rec->conn_params.min_conn_int &&
342 p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
343 (conn_interval > p_dev_rec->conn_params.max_conn_int) ||
344 (conn_latency > p_dev_rec->conn_params.slave_latency) ||
345 (conn_timeout > p_dev_rec->conn_params.supervision_tout)))
346 {
347 L2CAP_TRACE_ERROR5 ("upd_ll_conn_params: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d",
348 handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int,
349 p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout);
350
351 btsnd_hcic_ble_upd_ll_conn_params (handle,
352 p_dev_rec->conn_params.min_conn_int,
353 p_dev_rec->conn_params.max_conn_int,
354 p_dev_rec->conn_params.slave_latency,
355 p_dev_rec->conn_params.supervision_tout,
356 0, 0);
357 }
358
359 /* Tell BTM Acl management about the link */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700360 btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800361
362 p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
363
364 l2cu_process_fixed_chnl_resp (p_lcb);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700365
366 btm_ble_set_conn_st(BLE_CONN_IDLE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800367}
368
369
370/*******************************************************************************
371**
372** Function l2cble_advertiser_conn_comp
373**
374** Description This function is called when an HCI Connection Complete
375** event is received while we are an advertiser (so we are slave).
376**
377** Returns void
378**
379*******************************************************************************/
380void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
381 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
382{
383 tL2C_LCB *p_lcb;
384 tBTM_SEC_DEV_REC *p_dev_rec;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800385 UNUSED(type);
386 UNUSED(conn_interval);
387 UNUSED(conn_latency);
388 UNUSED(conn_timeout);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800389
390 /* See if we have a link control block for the remote device */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700391 p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800392
393 /* If we don't have one, create one and accept the connection. */
394 if (!p_lcb)
395 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700396 p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800397 if (!p_lcb)
398 {
399 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
400 L2CAP_TRACE_ERROR0 ("l2cble_advertiser_conn_comp - failed to allocate LCB");
401 return;
402 }
403 else
404 {
405 if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
406 {
407 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
408 L2CAP_TRACE_WARNING0 ("l2cble_scanner_conn_comp - LCB but no CCB");
409 return ;
410 }
411 }
412 }
413
414 /* Save the handle */
415 p_lcb->handle = handle;
416
417 /* Connected OK. Change state to connected, we were advertising, so we are slave */
418 p_lcb->link_state = LST_CONNECTED;
419 p_lcb->link_role = HCI_ROLE_SLAVE;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700420 p_lcb->transport = BT_TRANSPORT_LE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800421
422 /* Tell BTM Acl management about the link */
423 p_dev_rec = btm_find_or_alloc_dev (bda);
424
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700425 btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800426
427 p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
428
429 l2cu_process_fixed_chnl_resp (p_lcb);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700430
431 /* when adv and initiating are both active, cancel the direct connection */
432 if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0)
433 {
434 L2CA_CancelBleConnectReq(bda);
435 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800436}
437
438/*******************************************************************************
439**
440** Function l2cble_conn_comp
441**
442** Description This function is called when an HCI Connection Complete
443** event is received.
444**
445** Returns void
446**
447*******************************************************************************/
448void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
449 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
450{
451 if (role == HCI_ROLE_MASTER)
452 {
453 l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
454 }
455 else
456 {
457 l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
458 }
459}
460/*******************************************************************************
461**
462** Function l2cble_process_sig_cmd
463**
464** Description This function is called when a signalling packet is received
465** on the BLE signalling CID
466**
467** Returns void
468**
469*******************************************************************************/
470void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
471{
472 UINT8 *p_pkt_end;
473 UINT8 cmd_code, id;
474 UINT16 cmd_len, rej_reason;
475 UINT16 result;
476 UINT16 min_interval, max_interval, latency, timeout;
477
478 p_pkt_end = p + pkt_len;
479
480 STREAM_TO_UINT8 (cmd_code, p);
481 STREAM_TO_UINT8 (id, p);
482 STREAM_TO_UINT16 (cmd_len, p);
483
484 /* Check command length does not exceed packet length */
485 if ((p + cmd_len) > p_pkt_end)
486 {
487 L2CAP_TRACE_WARNING3 ("L2CAP - LE - format error, pkt_len: %d cmd_len: %d code: %d", pkt_len, cmd_len, cmd_code);
488 return;
489 }
490
491 switch (cmd_code)
492 {
493 case L2CAP_CMD_REJECT:
494 case L2CAP_CMD_ECHO_RSP:
495 case L2CAP_CMD_INFO_RSP:
496 STREAM_TO_UINT16 (rej_reason, p);
497 break;
498 case L2CAP_CMD_ECHO_REQ:
499 case L2CAP_CMD_INFO_REQ:
500 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
501 break;
502
503 case L2CAP_CMD_BLE_UPDATE_REQ:
504 STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */
505 STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */
506 STREAM_TO_UINT16 (latency, p); /* 0x0000 - 0x03E8 */
507 STREAM_TO_UINT16 (timeout, p); /* 0x000A - 0x0C80 */
508 /* If we are a master, the slave wants to update the parameters */
509 if (p_lcb->link_role == HCI_ROLE_MASTER)
510 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800511 if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX ||
512 max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX ||
513 latency > BTM_BLE_CONN_LATENCY_MAX ||
The Android Open Source Project5738f832012-12-12 16:00:35 -0800514 /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800515 timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX ||
The Android Open Source Project5738f832012-12-12 16:00:35 -0800516 max_interval < min_interval)
517 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800518 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800519 }
520 else
521 {
522
523 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id);
524
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700525 p_lcb->min_interval = min_interval;
526 p_lcb->max_interval = max_interval;
527 p_lcb->latency = latency;
528 p_lcb->timeout = timeout;
529 p_lcb->conn_update_mask |= UPD_REQUEST;
530
531 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
532 {
533 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
534 latency, timeout, 0, 0);
535 }
536 else
537 {
538 L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
539 }
540
The Android Open Source Project5738f832012-12-12 16:00:35 -0800541 }
542 }
543 else
544 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
545 break;
546
547 case L2CAP_CMD_BLE_UPDATE_RSP:
548 STREAM_TO_UINT16 (result, p);
549 break;
550
551 default:
552 L2CAP_TRACE_WARNING1 ("L2CAP - LE - unknown cmd code: %d", cmd_code);
553 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
554 return;
555 }
556}
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700557/*******************************************************************************
558**
559** Function l2c_enable_conn_param_timeout
560**
561** Description This function process the connection parameter enabling timeout
562**
563** Returns None.
564**
565*******************************************************************************/
566void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb)
567{
568 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800569
570
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700571 /* application allows to do update, if we were delaying one do it now, otherwise
572 just mark lcb that updates are enabled */
573 if (p_lcb->conn_update_mask & UPD_REQUEST)
574 {
575 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
576 p_lcb->latency, p_lcb->timeout, 0, 0);
577 }
578 else
579 {
580 /* if preferred number has been set, set to preferred conn parameter */
581 if (p_dev_rec && p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
582 {
583 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
584 (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
585 p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
586 (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
587 p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
588 (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
589 p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
590 (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
591 p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
592 0, 0);
593 }
594 }
595 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENABLED);
596
597}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800598/*******************************************************************************
599**
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800600** Function l2cble_init_direct_conn
601**
602** Description This function is to initate a direct connection
603**
604** Returns TRUE connection initiated, FALSE otherwise.
605**
606*******************************************************************************/
607BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
608{
609 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
610 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
611 UINT16 scan_int, scan_win;
612 BD_ADDR init_addr;
613 UINT8 init_addr_type = BLE_ADDR_PUBLIC,
614 own_addr_type = BLE_ADDR_PUBLIC;
615
616 /* There can be only one BLE connection request outstanding at a time */
617 if (p_dev_rec == NULL)
618 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700619 L2CAP_TRACE_WARNING0 ("unknown device, can not initate connection");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800620 return(FALSE);
621 }
622
623 scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
624 scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
625
626 init_addr_type = p_lcb->ble_addr_type;
627 memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
628
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700629#if BLE_PRIVACY_SPT == TRUE
Zhihai Xu8b35b3f2014-03-11 15:01:45 -0700630 if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
631 {
632 init_addr_type = BLE_ADDR_RANDOM;
Nitin Arora66988a02014-05-28 18:50:09 -0700633 //memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
Zhihai Xu8b35b3f2014-03-11 15:01:45 -0700634 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700635 /* if privacy is on and current do not consider using reconnection address */
636 if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */
637 own_addr_type = BLE_ADDR_RANDOM;
Zhihai Xu8b35b3f2014-03-11 15:01:45 -0700638#endif
639
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700640 if (!btm_ble_topology_check(BTM_BLE_STATE_INIT))
641 {
642 l2cu_release_lcb (p_lcb);
643 L2CAP_TRACE_ERROR0("initate direct connection fail, topology limitation");
644 return FALSE;
645 }
Wei Wanged534e32014-05-20 06:30:13 +0000646#if BLE_PRIVACY_SPT == TRUE
Adam Hampson845c2602014-05-27 13:14:30 -0700647#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE)
Wei Wanged534e32014-05-20 06:30:13 +0000648 extern tBTM_STATUS BTM_BleEnableIRKFeature(BOOLEAN enable);
649 if (btm_ble_vendor_irk_list_load_dev(p_dev_rec))
650 BTM_BleEnableIRKFeature(TRUE);
651
652 btm_random_pseudo_to_public(init_addr, &init_addr_type);
653#endif
654#endif
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800655 if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */
656 scan_win, /* UINT16 scan_win */
657 FALSE, /* UINT8 white_list */
Andre Eisenbach6975b4d2013-08-05 16:55:38 -0700658 init_addr_type, /* UINT8 addr_type_peer */
659 init_addr, /* BD_ADDR bda_peer */
660 own_addr_type, /* UINT8 addr_type_own */
Zhihai Xu3dc59452013-10-25 16:47:49 -0700661 (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
662 p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* conn_int_min */
663 (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
664 p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* conn_int_max */
665 (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
666 p_dev_rec->conn_params.slave_latency : 0), /* UINT16 conn_latency */
667 (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
668 p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_SUP_TOUT_DEF), /* conn_timeout */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800669 0, /* UINT16 min_len */
670 0)) /* UINT16 max_len */
671 {
672 l2cu_release_lcb (p_lcb);
673 L2CAP_TRACE_ERROR0("initate direct connection fail, no resources");
674 return (FALSE);
675 }
676 else
677 {
678 p_lcb->link_state = LST_CONNECTING;
Andre Eisenbach6975b4d2013-08-05 16:55:38 -0700679 l2cb.is_ble_connecting = TRUE;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800680 memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
681 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
682 btm_ble_set_conn_st (BLE_DIR_CONN);
683
684 return (TRUE);
685 }
686}
687
688/*******************************************************************************
689**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800690** Function l2cble_create_conn
691**
692** Description This function initiates an acl connection via HCI
693**
694** Returns TRUE if successful, FALSE if connection not started.
695**
696*******************************************************************************/
697BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb)
698{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800699 tBTM_BLE_CONN_ST conn_st = btm_ble_get_conn_st();
700 BOOLEAN rt = FALSE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800701
702 /* There can be only one BLE connection request outstanding at a time */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800703 if (conn_st == BLE_CONN_IDLE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800704 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800705 rt = l2cble_init_direct_conn(p_lcb);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800706 }
707 else
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800708 {
709 L2CAP_TRACE_WARNING1 ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800710
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800711 btm_ble_enqueue_direct_conn_req(p_lcb);
712
713 if (conn_st == BLE_BG_CONN)
714 btm_ble_suspend_bg_conn();
715
716 rt = TRUE;
717 }
718 return rt;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800719}
720
721/*******************************************************************************
722**
723** Function l2c_link_processs_ble_num_bufs
724**
725** Description This function is called when a "controller buffer size"
726** event is first received from the controller. It updates
727** the L2CAP values.
728**
729** Returns void
730**
731*******************************************************************************/
732void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs)
733{
Andre Eisenbach0082e022013-04-03 13:56:05 -0700734 if (num_lm_ble_bufs == 0)
Andre Eisenbach12c3f492013-04-24 16:02:04 -0700735 {
736 num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;
737 l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED;
738 }
739
The Android Open Source Project5738f832012-12-12 16:00:35 -0800740 l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs;
741}
742
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700743#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
744/*******************************************************************************
745**
746** Function l2cble_process_rc_param_request_evt
747**
748** Description process LE Remote Connection Parameter Request Event.
749**
750** Returns void
751**
752*******************************************************************************/
753void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
754 UINT16 latency, UINT16 timeout)
755{
756 tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle (handle);
757
758 if (p_lcb != NULL)
759 {
760 p_lcb->min_interval = int_min;
761 p_lcb->max_interval = int_max;
762 p_lcb->latency = latency;
763 p_lcb->timeout = timeout;
764 p_lcb->conn_update_mask |= UPD_REQUEST;
765
766 /* TODO: revisit: if update is enabled, always accept connection parameter update */
767 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
768 {
769 btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
770 }
771 else
772 {
773 L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
774 btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL);
775 }
776
777 }
778 else
779 {
780 L2CAP_TRACE_WARNING0("No link to update connection parameter")
781 }
782}
783#endif
784
785
The Android Open Source Project5738f832012-12-12 16:00:35 -0800786#endif /* (BLE_INCLUDED == TRUE) */