blob: 2b933e8e102a3b89d844c655914d549960cbcaec [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
Wei Wanged534e32014-05-20 06:30:13 +000038#include "vendor_ble.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080039/*******************************************************************************
40**
41** Function L2CA_CancelBleConnectReq
42**
43** Description Cancel a pending connection attempt to a BLE device.
44**
45** Parameters: BD Address of remote
46**
47** Return value: TRUE if connection was cancelled
48**
49*******************************************************************************/
50BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
51{
52 tL2C_LCB *p_lcb;
53
54 /* There can be only one BLE connection request outstanding at a time */
Andre Eisenbach6975b4d2013-08-05 16:55:38 -070055 if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
The Android Open Source Project5738f832012-12-12 16:00:35 -080056 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -070057 L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - no connection pending");
The Android Open Source Project5738f832012-12-12 16:00:35 -080058 return(FALSE);
59 }
60
61 if (memcmp (rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN))
62 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -070063 L2CAP_TRACE_WARNING ("L2CA_CancelBleConnectReq - different BDA Connecting: %08x%04x Cancel: %08x%04x",
The Android Open Source Project5738f832012-12-12 16:00:35 -080064 (l2cb.ble_connecting_bda[0]<<24)+(l2cb.ble_connecting_bda[1]<<16)+(l2cb.ble_connecting_bda[2]<<8)+l2cb.ble_connecting_bda[3],
65 (l2cb.ble_connecting_bda[4]<<8)+l2cb.ble_connecting_bda[5],
66 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
67
68 return(FALSE);
69 }
70
71 if (btsnd_hcic_ble_create_conn_cancel())
72 {
73
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -070074 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 -080075 {
76 p_lcb->disc_reason = L2CAP_CONN_CANCEL;
77 l2cu_release_lcb (p_lcb);
78 }
Andre Eisenbach6975b4d2013-08-05 16:55:38 -070079 /* update state to be cancel, wait for connection cancel complete */
80 btm_ble_set_conn_st (BLE_CONN_CANCEL);
The Android Open Source Project5738f832012-12-12 16:00:35 -080081
82 return(TRUE);
83 }
84 else
85 return(FALSE);
86}
87
Zhihai Xu15d0a0c2013-12-17 20:33:09 -080088/*******************************************************************************
89**
The Android Open Source Project5738f832012-12-12 16:00:35 -080090** Function L2CA_UpdateBleConnParams
91**
92** Description Update BLE connection parameters.
93**
94** Parameters: BD Address of remote
95**
96** Return value: TRUE if update started
97**
98*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -070099BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int,
100 UINT16 latency, UINT16 timeout)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800101{
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700102 tL2C_LCB *p_lcb;
103 tACL_CONN *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800104
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700105 /* See if we have a link control block for the remote device */
106 p_lcb = l2cu_find_lcb_by_bd_addr (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 /* If we don't have one, create one and accept the connection. */
109 if (!p_lcb || !p_acl_cb)
110 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700111 L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700112 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
113 (rem_bda[4]<<8)+rem_bda[5]);
114 return(FALSE);
115 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800116
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700117 if (p_lcb->transport != BT_TRANSPORT_LE)
118 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700119 L2CAP_TRACE_WARNING ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700120 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
121 (rem_bda[4]<<8)+rem_bda[5]);
122 return(FALSE);
123 }
124#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
125 /* if both 4.1 compliant */
126 if ((HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) &&
127 HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)))
128 {
129 /* TODO: CE length selection ?? */
130 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
131 latency, timeout, 0, 0);
132 }
133 else
134 /* if either side does not support Connection Parameters Request
135 Link Layer Control Procedure,
136 use Link Layer Connection Update procedure */
137#endif
138 {
139 if (p_lcb->link_role == HCI_ROLE_MASTER)
140 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
141 latency, timeout, 0, 0);
142 else
143 l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
144 }
145 return(TRUE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800146
The Android Open Source Project5738f832012-12-12 16:00:35 -0800147}
148
149
150/*******************************************************************************
151**
152** Function L2CA_EnableUpdateBleConnParams
153**
154** Description Enable or disable update based on the request from the peer
155**
156** Parameters: BD Address of remote
157**
158** Return value: TRUE if update started
159**
160*******************************************************************************/
161BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
162{
163 tL2C_LCB *p_lcb;
164
165 /* See if we have a link control block for the remote device */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700166 p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800167
The Android Open Source Project5738f832012-12-12 16:00:35 -0800168 if (!p_lcb)
169 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700170 L2CAP_TRACE_WARNING ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700171 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
172 (rem_bda[4]<<8)+rem_bda[5]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800173 return (FALSE);
174 }
175
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700176 L2CAP_TRACE_API ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__,
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700177 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
178 (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800179
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700180 if (p_lcb->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800181 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700182 L2CAP_TRACE_WARNING ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__,
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700183 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
184 (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800185 return (FALSE);
186 }
187
188 if (enable)
189 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700190 if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) == UPD_DISABLED)
191 {
192 p_lcb->conn_param_enb.param = (TIMER_PARAM_TYPE)p_lcb;
193 btu_start_timer (&p_lcb->conn_param_enb, BTU_TTYPE_L2CAP_END_CONN_UPD,
194 L2CAP_BLE_ENB_CONN_PARAM_TOUT);
195 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENB_TOUT);
196 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800197 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700198 else if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) != UPD_DISABLED)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800199 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700200 btu_stop_timer(&p_lcb->conn_param_enb);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800201
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700202 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
203 {
204
205 /*
206 application requests to disable parameters update.If parameters are already updated,
207 lets set them up to what has been requested during connection establishement
208 */
209 if ((p_lcb->conn_update_mask & UPD_REQUEST) != 0)
210 {
211 /* revert back to default */
212 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
213 BTM_BLE_CONN_INT_MIN_DEF,
214 BTM_BLE_CONN_INT_MAX_DEF,
215 BTM_BLE_CONN_SLAVE_LATENCY_DEF,
216 BTM_BLE_CONN_TIMEOUT_DEF,
217 0, 0);
218 }
219 }
220 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_DISABLED);
221
222 }
Zhihai Xu15d0a0c2013-12-17 20:33:09 -0800223
The Android Open Source Project5738f832012-12-12 16:00:35 -0800224 return (TRUE);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700225
The Android Open Source Project5738f832012-12-12 16:00:35 -0800226}
227
Zhihai Xu15d0a0c2013-12-17 20:33:09 -0800228
229/*******************************************************************************
230**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800231** Function L2CA_GetBleConnRole
232**
233** Description This function returns the connection role.
234**
235** Returns link role.
236**
237*******************************************************************************/
238UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr)
239{
240 UINT8 role = HCI_ROLE_UNKNOWN;
241
242 tL2C_LCB *p_lcb;
243
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700244 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 -0800245 role = p_lcb->link_role;
246
247 return role;
248}
249/*******************************************************************************
250**
251** Function L2CA_GetDisconnectReason
252**
253** Description This function returns the disconnect reason code.
254**
255** Returns disconnect reason
256**
257*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700258UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800259{
260 tL2C_LCB *p_lcb;
261 UINT16 reason = 0;
262
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700263 if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800264 reason = p_lcb->disc_reason;
265
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700266 L2CAP_TRACE_DEBUG ("L2CA_GetDisconnectReason=%d ",reason);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800267
268 return reason;
269}
270
271/*******************************************************************************
272**
Priti Aghera9c29d082014-09-02 15:41:56 -0700273** Function l2cble_notify_le_connection
274**
275** Description This function notifiy the l2cap connection to the app layer
276**
277** Returns none
278**
279*******************************************************************************/
280void l2cble_notify_le_connection (BD_ADDR bda)
281{
282 tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
Prerepa Viswanadham7ae25152014-09-10 17:08:11 -0700283 tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ;
Priti Aghera9c29d082014-09-02 15:41:56 -0700284
Prerepa Viswanadham7ae25152014-09-10 17:08:11 -0700285 if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED)
286 {
287 /* update link status */
288 btm_establish_continue(p_acl);
289 /* update l2cap link status and send callback */
290 p_lcb->link_state = LST_CONNECTED;
Priti Aghera9c29d082014-09-02 15:41:56 -0700291 l2cu_process_fixed_chnl_resp (p_lcb);
Prerepa Viswanadham7ae25152014-09-10 17:08:11 -0700292 }
Priti Aghera9c29d082014-09-02 15:41:56 -0700293}
294
295/*******************************************************************************
296**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800297** Function l2cble_scanner_conn_comp
298**
299** Description This function is called when an HCI Connection Complete
300** event is received while we are a scanner (so we are master).
301**
302** Returns void
303**
304*******************************************************************************/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800305void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
306 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800307{
308 tL2C_LCB *p_lcb;
309 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda);
310
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700311 L2CAP_TRACE_DEBUG ("l2cble_scanner_conn_comp: HANDLE=%d addr_type=%d conn_interval=%d slave_latency=%d supervision_tout=%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800312 handle, type, conn_interval, conn_latency, conn_timeout);
313
314 l2cb.is_ble_connecting = FALSE;
315
The Android Open Source Project5738f832012-12-12 16:00:35 -0800316 /* See if we have a link control block for the remote device */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700317 p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800318
319 /* If we don't have one, create one. this is auto connection complete. */
320 if (!p_lcb)
321 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700322 p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800323 if (!p_lcb)
324 {
325 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700326 L2CAP_TRACE_ERROR ("l2cble_scanner_conn_comp - failed to allocate LCB");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800327 return;
328 }
329 else
330 {
331 if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
332 {
333 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700334 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800335 return ;
336 }
337 }
338 }
339 else if (p_lcb->link_state != LST_CONNECTING)
340 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700341 L2CAP_TRACE_ERROR ("L2CAP got BLE scanner conn_comp in bad state: %d", p_lcb->link_state);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800342 return;
343 }
344 btu_stop_timer(&p_lcb->timer_entry);
345
346 /* Save the handle */
347 p_lcb->handle = handle;
348
349 /* Connected OK. Change state to connected, we were scanning so we are master */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800350 p_lcb->link_role = HCI_ROLE_MASTER;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700351 p_lcb->transport = BT_TRANSPORT_LE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800352
353 /* If there are any preferred connection parameters, set them now */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800354 if ( (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
355 (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
356 (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN ) &&
357 (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX ) &&
358 (p_dev_rec->conn_params.slave_latency <= BTM_BLE_CONN_LATENCY_MAX ) &&
359 (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) &&
360 (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) &&
The Android Open Source Project5738f832012-12-12 16:00:35 -0800361 ((conn_interval < p_dev_rec->conn_params.min_conn_int &&
362 p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ||
363 (conn_interval > p_dev_rec->conn_params.max_conn_int) ||
364 (conn_latency > p_dev_rec->conn_params.slave_latency) ||
365 (conn_timeout > p_dev_rec->conn_params.supervision_tout)))
366 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700367 L2CAP_TRACE_ERROR ("upd_ll_conn_params: HANDLE=%d min_conn_int=%d max_conn_int=%d slave_latency=%d supervision_tout=%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800368 handle, p_dev_rec->conn_params.min_conn_int, p_dev_rec->conn_params.max_conn_int,
369 p_dev_rec->conn_params.slave_latency, p_dev_rec->conn_params.supervision_tout);
370
371 btsnd_hcic_ble_upd_ll_conn_params (handle,
372 p_dev_rec->conn_params.min_conn_int,
373 p_dev_rec->conn_params.max_conn_int,
374 p_dev_rec->conn_params.slave_latency,
375 p_dev_rec->conn_params.supervision_tout,
376 0, 0);
377 }
378
379 /* Tell BTM Acl management about the link */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700380 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 -0800381
382 p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
383
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700384 btm_ble_set_conn_st(BLE_CONN_IDLE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800385}
386
387
388/*******************************************************************************
389**
390** Function l2cble_advertiser_conn_comp
391**
392** Description This function is called when an HCI Connection Complete
393** event is received while we are an advertiser (so we are slave).
394**
395** Returns void
396**
397*******************************************************************************/
398void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
399 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
400{
401 tL2C_LCB *p_lcb;
402 tBTM_SEC_DEV_REC *p_dev_rec;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800403 UNUSED(type);
404 UNUSED(conn_interval);
405 UNUSED(conn_latency);
406 UNUSED(conn_timeout);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800407
408 /* See if we have a link control block for the remote device */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700409 p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800410
411 /* If we don't have one, create one and accept the connection. */
412 if (!p_lcb)
413 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700414 p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800415 if (!p_lcb)
416 {
417 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700418 L2CAP_TRACE_ERROR ("l2cble_advertiser_conn_comp - failed to allocate LCB");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800419 return;
420 }
421 else
422 {
423 if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
424 {
425 btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700426 L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800427 return ;
428 }
429 }
430 }
431
432 /* Save the handle */
433 p_lcb->handle = handle;
434
435 /* Connected OK. Change state to connected, we were advertising, so we are slave */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800436 p_lcb->link_role = HCI_ROLE_SLAVE;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700437 p_lcb->transport = BT_TRANSPORT_LE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800438
439 /* Tell BTM Acl management about the link */
440 p_dev_rec = btm_find_or_alloc_dev (bda);
441
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700442 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 -0800443
444 p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
445
Priti Aghera9c29d082014-09-02 15:41:56 -0700446 if (!HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(btm_cb.devcb.local_le_features))
447 {
Prerepa Viswanadham7ae25152014-09-10 17:08:11 -0700448 p_lcb->link_state = LST_CONNECTED;
Priti Aghera9c29d082014-09-02 15:41:56 -0700449 l2cu_process_fixed_chnl_resp (p_lcb);
450 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700451
452 /* when adv and initiating are both active, cancel the direct connection */
453 if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0)
454 {
455 L2CA_CancelBleConnectReq(bda);
456 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800457}
458
459/*******************************************************************************
460**
461** Function l2cble_conn_comp
462**
463** Description This function is called when an HCI Connection Complete
464** event is received.
465**
466** Returns void
467**
468*******************************************************************************/
469void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
470 UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
471{
472 if (role == HCI_ROLE_MASTER)
473 {
474 l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
475 }
476 else
477 {
478 l2cble_advertiser_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
479 }
480}
481/*******************************************************************************
482**
483** Function l2cble_process_sig_cmd
484**
485** Description This function is called when a signalling packet is received
486** on the BLE signalling CID
487**
488** Returns void
489**
490*******************************************************************************/
491void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
492{
493 UINT8 *p_pkt_end;
494 UINT8 cmd_code, id;
495 UINT16 cmd_len, rej_reason;
496 UINT16 result;
497 UINT16 min_interval, max_interval, latency, timeout;
498
499 p_pkt_end = p + pkt_len;
500
501 STREAM_TO_UINT8 (cmd_code, p);
502 STREAM_TO_UINT8 (id, p);
503 STREAM_TO_UINT16 (cmd_len, p);
504
505 /* Check command length does not exceed packet length */
506 if ((p + cmd_len) > p_pkt_end)
507 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700508 L2CAP_TRACE_WARNING ("L2CAP - LE - format error, pkt_len: %d cmd_len: %d code: %d", pkt_len, cmd_len, cmd_code);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800509 return;
510 }
511
512 switch (cmd_code)
513 {
514 case L2CAP_CMD_REJECT:
515 case L2CAP_CMD_ECHO_RSP:
516 case L2CAP_CMD_INFO_RSP:
517 STREAM_TO_UINT16 (rej_reason, p);
518 break;
519 case L2CAP_CMD_ECHO_REQ:
520 case L2CAP_CMD_INFO_REQ:
521 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
522 break;
523
524 case L2CAP_CMD_BLE_UPDATE_REQ:
525 STREAM_TO_UINT16 (min_interval, p); /* 0x0006 - 0x0C80 */
526 STREAM_TO_UINT16 (max_interval, p); /* 0x0006 - 0x0C80 */
527 STREAM_TO_UINT16 (latency, p); /* 0x0000 - 0x03E8 */
528 STREAM_TO_UINT16 (timeout, p); /* 0x000A - 0x0C80 */
529 /* If we are a master, the slave wants to update the parameters */
530 if (p_lcb->link_role == HCI_ROLE_MASTER)
531 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800532 if (min_interval < BTM_BLE_CONN_INT_MIN || min_interval > BTM_BLE_CONN_INT_MAX ||
533 max_interval < BTM_BLE_CONN_INT_MIN || max_interval > BTM_BLE_CONN_INT_MAX ||
534 latency > BTM_BLE_CONN_LATENCY_MAX ||
The Android Open Source Project5738f832012-12-12 16:00:35 -0800535 /*(timeout >= max_interval && latency > (timeout * 10/(max_interval * 1.25) - 1)) ||*/
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800536 timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX ||
The Android Open Source Project5738f832012-12-12 16:00:35 -0800537 max_interval < min_interval)
538 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800539 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_UNACCEPTABLE_PARAMS, id);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800540 }
541 else
542 {
543
544 l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id);
545
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700546 p_lcb->min_interval = min_interval;
547 p_lcb->max_interval = max_interval;
548 p_lcb->latency = latency;
549 p_lcb->timeout = timeout;
550 p_lcb->conn_update_mask |= UPD_REQUEST;
551
552 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
553 {
554 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
555 latency, timeout, 0, 0);
556 }
557 else
558 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700559 L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled");
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700560 }
561
The Android Open Source Project5738f832012-12-12 16:00:35 -0800562 }
563 }
564 else
565 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
566 break;
567
568 case L2CAP_CMD_BLE_UPDATE_RSP:
569 STREAM_TO_UINT16 (result, p);
570 break;
571
572 default:
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700573 L2CAP_TRACE_WARNING ("L2CAP - LE - unknown cmd code: %d", cmd_code);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800574 l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
575 return;
576 }
577}
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700578/*******************************************************************************
579**
580** Function l2c_enable_conn_param_timeout
581**
582** Description This function process the connection parameter enabling timeout
583**
584** Returns None.
585**
586*******************************************************************************/
587void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb)
588{
589 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 -0800590
591
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700592 /* application allows to do update, if we were delaying one do it now, otherwise
593 just mark lcb that updates are enabled */
594 if (p_lcb->conn_update_mask & UPD_REQUEST)
595 {
596 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
597 p_lcb->latency, p_lcb->timeout, 0, 0);
598 }
599 else
600 {
601 /* if preferred number has been set, set to preferred conn parameter */
602 if (p_dev_rec && p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
603 {
604 btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
605 (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
606 p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
607 (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
608 p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
609 (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
610 p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
611 (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
612 p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
613 0, 0);
614 }
615 }
616 L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENABLED);
617
618}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800619/*******************************************************************************
620**
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800621** Function l2cble_init_direct_conn
622**
623** Description This function is to initate a direct connection
624**
625** Returns TRUE connection initiated, FALSE otherwise.
626**
627*******************************************************************************/
628BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
629{
630 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
631 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
632 UINT16 scan_int, scan_win;
633 BD_ADDR init_addr;
634 UINT8 init_addr_type = BLE_ADDR_PUBLIC,
635 own_addr_type = BLE_ADDR_PUBLIC;
636
637 /* There can be only one BLE connection request outstanding at a time */
638 if (p_dev_rec == NULL)
639 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700640 L2CAP_TRACE_WARNING ("unknown device, can not initate connection");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800641 return(FALSE);
642 }
643
644 scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
645 scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
646
647 init_addr_type = p_lcb->ble_addr_type;
648 memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
649
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700650#if BLE_PRIVACY_SPT == TRUE
Zhihai Xu8b35b3f2014-03-11 15:01:45 -0700651 if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
652 {
653 init_addr_type = BLE_ADDR_RANDOM;
Zhihai Xu8b35b3f2014-03-11 15:01:45 -0700654 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700655 /* if privacy is on and current do not consider using reconnection address */
656 if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */
657 own_addr_type = BLE_ADDR_RANDOM;
Zhihai Xu8b35b3f2014-03-11 15:01:45 -0700658#endif
659
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700660 if (!btm_ble_topology_check(BTM_BLE_STATE_INIT))
661 {
662 l2cu_release_lcb (p_lcb);
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700663 L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation");
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700664 return FALSE;
665 }
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700666 if (btm_ble_vendor_irk_list_load_dev(p_dev_rec) &&
667 (btm_cb.cmn_ble_vsc_cb.rpa_offloading == TRUE ))
668 {
669 btm_ble_vendor_enable_irk_feature(TRUE);
670 btm_random_pseudo_to_public(init_addr, &init_addr_type);
671 }
Wei Wanged534e32014-05-20 06:30:13 +0000672
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800673 if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */
674 scan_win, /* UINT16 scan_win */
675 FALSE, /* UINT8 white_list */
Andre Eisenbach6975b4d2013-08-05 16:55:38 -0700676 init_addr_type, /* UINT8 addr_type_peer */
677 init_addr, /* BD_ADDR bda_peer */
678 own_addr_type, /* UINT8 addr_type_own */
Zhihai Xu3dc59452013-10-25 16:47:49 -0700679 (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
680 p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* conn_int_min */
681 (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
682 p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF), /* conn_int_max */
683 (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
Steve Paik9c07b332014-06-19 15:50:46 -0700684 p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF), /* UINT16 conn_latency */
Zhihai Xu3dc59452013-10-25 16:47:49 -0700685 (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
Steve Paik9c07b332014-06-19 15:50:46 -0700686 p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800687 0, /* UINT16 min_len */
688 0)) /* UINT16 max_len */
689 {
690 l2cu_release_lcb (p_lcb);
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700691 L2CAP_TRACE_ERROR("initate direct connection fail, no resources");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800692 return (FALSE);
693 }
694 else
695 {
696 p_lcb->link_state = LST_CONNECTING;
Andre Eisenbach6975b4d2013-08-05 16:55:38 -0700697 l2cb.is_ble_connecting = TRUE;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800698 memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
699 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
700 btm_ble_set_conn_st (BLE_DIR_CONN);
701
702 return (TRUE);
703 }
704}
705
706/*******************************************************************************
707**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800708** Function l2cble_create_conn
709**
710** Description This function initiates an acl connection via HCI
711**
712** Returns TRUE if successful, FALSE if connection not started.
713**
714*******************************************************************************/
715BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb)
716{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800717 tBTM_BLE_CONN_ST conn_st = btm_ble_get_conn_st();
718 BOOLEAN rt = FALSE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800719
720 /* There can be only one BLE connection request outstanding at a time */
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800721 if (conn_st == BLE_CONN_IDLE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800722 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800723 rt = l2cble_init_direct_conn(p_lcb);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800724 }
725 else
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800726 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700727 L2CAP_TRACE_WARNING ("L2CAP - LE - cannot start new connection at conn st: %d", conn_st);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800728
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800729 btm_ble_enqueue_direct_conn_req(p_lcb);
730
731 if (conn_st == BLE_BG_CONN)
732 btm_ble_suspend_bg_conn();
733
734 rt = TRUE;
735 }
736 return rt;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800737}
738
739/*******************************************************************************
740**
741** Function l2c_link_processs_ble_num_bufs
742**
743** Description This function is called when a "controller buffer size"
744** event is first received from the controller. It updates
745** the L2CAP values.
746**
747** Returns void
748**
749*******************************************************************************/
750void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs)
751{
Andre Eisenbach0082e022013-04-03 13:56:05 -0700752 if (num_lm_ble_bufs == 0)
Andre Eisenbach12c3f492013-04-24 16:02:04 -0700753 {
754 num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;
755 l2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED;
756 }
757
The Android Open Source Project5738f832012-12-12 16:00:35 -0800758 l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs;
759}
760
Mudumba Ananth92ac2d82014-07-11 00:05:54 -0700761/*******************************************************************************
762**
763** Function l2c_ble_link_adjust_allocation
764**
765** Description This function is called when a link is created or removed
766** to calculate the amount of packets each link may send to
767** the HCI without an ack coming back.
768**
769** Currently, this is a simple allocation, dividing the
770** number of Controller Packets by the number of links. In
771** the future, QOS configuration should be examined.
772**
773** Returns void
774**
775*******************************************************************************/
776void l2c_ble_link_adjust_allocation (void)
777{
778 UINT16 qq, yy, qq_remainder;
779 tL2C_LCB *p_lcb;
780 UINT16 hi_quota, low_quota;
781 UINT16 num_lowpri_links = 0;
782 UINT16 num_hipri_links = 0;
783 UINT16 controller_xmit_quota = l2cb.num_lm_ble_bufs;
784 UINT16 high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
785
786 /* If no links active, reset buffer quotas and controller buffers */
787 if (l2cb.num_ble_links_active == 0)
788 {
789 l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
790 l2cb.ble_round_robin_quota = l2cb.ble_round_robin_unacked = 0;
791 return;
792 }
793
794 /* First, count the links */
795 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++)
796 {
797 if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE)
798 {
799 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
800 num_hipri_links++;
801 else
802 num_lowpri_links++;
803 }
804 }
805
806 /* now adjust high priority link quota */
807 low_quota = num_lowpri_links ? 1 : 0;
808 while ( (num_hipri_links * high_pri_link_quota + low_quota) > controller_xmit_quota )
809 high_pri_link_quota--;
810
811
812 /* Work out the xmit quota and buffer quota high and low priorities */
813 hi_quota = num_hipri_links * high_pri_link_quota;
814 low_quota = (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
815
816 /* Work out and save the HCI xmit quota for each low priority link */
817
818 /* If each low priority link cannot have at least one buffer */
819 if (num_lowpri_links > low_quota)
820 {
821 l2cb.ble_round_robin_quota = low_quota;
822 qq = qq_remainder = 0;
823 }
824 /* If each low priority link can have at least one buffer */
825 else if (num_lowpri_links > 0)
826 {
827 l2cb.ble_round_robin_quota = 0;
828 l2cb.ble_round_robin_unacked = 0;
829 qq = low_quota / num_lowpri_links;
830 qq_remainder = low_quota % num_lowpri_links;
831 }
832 /* If no low priority link */
833 else
834 {
835 l2cb.ble_round_robin_quota = 0;
836 l2cb.ble_round_robin_unacked = 0;
837 qq = qq_remainder = 0;
838 }
839 L2CAP_TRACE_EVENT ("l2c_ble_link_adjust_allocation num_hipri: %u num_lowpri: %u low_quota: %u round_robin_quota: %u qq: %u",
840 num_hipri_links, num_lowpri_links, low_quota,
841 l2cb.ble_round_robin_quota, qq);
842
843 /* Now, assign the quotas to each link */
844 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++)
845 {
846 if (p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE)
847 {
848 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
849 {
850 p_lcb->link_xmit_quota = high_pri_link_quota;
851 }
852 else
853 {
854 /* Safety check in case we switched to round-robin with something outstanding */
855 /* if sent_not_acked is added into round_robin_unacked then don't add it again */
856 /* l2cap keeps updating sent_not_acked for exiting from round robin */
857 if (( p_lcb->link_xmit_quota > 0 )&&( qq == 0 ))
858 l2cb.ble_round_robin_unacked += p_lcb->sent_not_acked;
859
860 p_lcb->link_xmit_quota = qq;
861 if (qq_remainder > 0)
862 {
863 p_lcb->link_xmit_quota++;
864 qq_remainder--;
865 }
866 }
867
868 L2CAP_TRACE_EVENT("l2c_ble_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d",
869 yy, p_lcb->acl_priority, p_lcb->link_xmit_quota);
870
871 L2CAP_TRACE_EVENT(" SentNotAcked: %d RRUnacked: %d",
872 p_lcb->sent_not_acked, l2cb.round_robin_unacked);
873
874 /* There is a special case where we have readjusted the link quotas and */
875 /* this link may have sent anything but some other link sent packets so */
876 /* so we may need a timer to kick off this link's transmissions. */
877 if ( (p_lcb->link_state == LST_CONNECTED)
878 && (p_lcb->link_xmit_data_q.count)
879 && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota) )
880 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_FLOW_CONTROL_TOUT);
881 }
882 }
883}
884
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700885#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
886/*******************************************************************************
887**
888** Function l2cble_process_rc_param_request_evt
889**
890** Description process LE Remote Connection Parameter Request Event.
891**
892** Returns void
893**
894*******************************************************************************/
895void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
896 UINT16 latency, UINT16 timeout)
897{
898 tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle (handle);
899
900 if (p_lcb != NULL)
901 {
902 p_lcb->min_interval = int_min;
903 p_lcb->max_interval = int_max;
904 p_lcb->latency = latency;
905 p_lcb->timeout = timeout;
906 p_lcb->conn_update_mask |= UPD_REQUEST;
907
908 /* TODO: revisit: if update is enabled, always accept connection parameter update */
909 if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
910 {
911 btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
912 }
913 else
914 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700915 L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled");
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700916 btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL);
917 }
918
919 }
920 else
921 {
Sharvil Nanavatia51c9d92014-05-04 01:08:21 -0700922 L2CAP_TRACE_WARNING("No link to update connection parameter")
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700923 }
924}
925#endif
926
927
The Android Open Source Project5738f832012-12-12 16:00:35 -0800928#endif /* (BLE_INCLUDED == TRUE) */