blob: c51967c5237bd9093a1de90c0fedbf4619689eb4 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
2 *
3 * Copyright (C) 1999-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 the functions relating to link management. A "link"
22 * is a connection between this device and another device. Only ACL links
23 * are managed.
24 *
25 ******************************************************************************/
26
Jack Hef2af1c42016-12-13 01:59:12 -080027#include <base/logging.h>
Myles Watson911d1ae2016-11-28 16:44:40 -080028#include <stdio.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080029#include <stdlib.h>
30#include <string.h>
The Android Open Source Project5738f832012-12-12 16:00:35 -080031
Pavlin Radoslavov258c2532015-09-27 20:59:05 -070032#include "bt_common.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080033#include "bt_types.h"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080034#include "bt_utils.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080035#include "btm_api.h"
36#include "btm_int.h"
Myles Watson911d1ae2016-11-28 16:44:40 -080037#include "btu.h"
38#include "device/include/controller.h"
39#include "hcimsgs.h"
40#include "l2c_api.h"
41#include "l2c_int.h"
42#include "l2cdefs.h"
Myles Watsond7ffd642016-10-27 10:27:36 -070043#include "osi/include/osi.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080044
Myles Watson911d1ae2016-11-28 16:44:40 -080045extern fixed_queue_t* btu_general_alarm_queue;
Pavlin Radoslavov78bcff72015-12-04 17:36:34 -080046
Yamei Du35e95c92015-11-18 17:28:07 +080047static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
48 tL2C_TX_COMPLETE_CB_INFO* p_cbi);
The Android Open Source Project5738f832012-12-12 16:00:35 -080049
The Android Open Source Project5738f832012-12-12 16:00:35 -080050/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -080051 *
52 * Function l2c_link_hci_conn_req
53 *
54 * Description This function is called when an HCI Connection Request
55 * event is received.
56 *
57 * Returns true, if accept conn
58 *
59 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -070060bool l2c_link_hci_conn_req(const RawAddress& bd_addr) {
Myles Watson911d1ae2016-11-28 16:44:40 -080061 tL2C_LCB* p_lcb;
62 tL2C_LCB* p_lcb_cur;
63 int xx;
64 bool no_links;
The Android Open Source Project5738f832012-12-12 16:00:35 -080065
Myles Watson911d1ae2016-11-28 16:44:40 -080066 /* See if we have a link control block for the remote device */
67 p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -080068
Myles Watson911d1ae2016-11-28 16:44:40 -080069 /* If we don't have one, create one and accept the connection. */
70 if (!p_lcb) {
71 p_lcb = l2cu_allocate_lcb(bd_addr, false, BT_TRANSPORT_BR_EDR);
72 if (!p_lcb) {
73 btsnd_hcic_reject_conn(bd_addr, HCI_ERR_HOST_REJECT_RESOURCES);
74 L2CAP_TRACE_ERROR("L2CAP failed to allocate LCB");
75 return false;
The Android Open Source Project5738f832012-12-12 16:00:35 -080076 }
77
Myles Watson911d1ae2016-11-28 16:44:40 -080078 no_links = true;
The Android Open Source Project5738f832012-12-12 16:00:35 -080079
Myles Watson911d1ae2016-11-28 16:44:40 -080080 /* If we already have connection, accept as a master */
81 for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS;
82 xx++, p_lcb_cur++) {
83 if (p_lcb_cur == p_lcb) continue;
The Android Open Source Project5738f832012-12-12 16:00:35 -080084
Myles Watson911d1ae2016-11-28 16:44:40 -080085 if (p_lcb_cur->in_use) {
86 no_links = false;
87 p_lcb->link_role = HCI_ROLE_MASTER;
88 break;
89 }
The Android Open Source Project5738f832012-12-12 16:00:35 -080090 }
Myles Watson911d1ae2016-11-28 16:44:40 -080091
92 if (no_links) {
93 if (!btm_dev_support_switch(bd_addr))
94 p_lcb->link_role = HCI_ROLE_SLAVE;
95 else
96 p_lcb->link_role = l2cu_get_conn_role(p_lcb);
The Android Open Source Project5738f832012-12-12 16:00:35 -080097 }
Myles Watson911d1ae2016-11-28 16:44:40 -080098
99 /* Tell the other side we accept the connection */
Jakub Pawlowskib8a477e2017-06-16 15:16:15 -0700100 btsnd_hcic_accept_conn(bd_addr, p_lcb->link_role);
Myles Watson911d1ae2016-11-28 16:44:40 -0800101
102 p_lcb->link_state = LST_CONNECTING;
103
104 /* Start a timer waiting for connect complete */
105 alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS,
106 l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
107 return (true);
108 }
109
110 /* We already had a link control block to the guy. Check what state it is in
111 */
112 if ((p_lcb->link_state == LST_CONNECTING) ||
113 (p_lcb->link_state == LST_CONNECT_HOLDING)) {
114 /* Connection collision. Accept the connection anyways. */
115
116 if (!btm_dev_support_switch(bd_addr))
117 p_lcb->link_role = HCI_ROLE_SLAVE;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800118 else
Myles Watson911d1ae2016-11-28 16:44:40 -0800119 p_lcb->link_role = l2cu_get_conn_role(p_lcb);
120
Jakub Pawlowskib8a477e2017-06-16 15:16:15 -0700121 btsnd_hcic_accept_conn(bd_addr, p_lcb->link_role);
Myles Watson911d1ae2016-11-28 16:44:40 -0800122
123 p_lcb->link_state = LST_CONNECTING;
124 return (true);
125 } else if (p_lcb->link_state == LST_DISCONNECTING) {
126 /* In disconnecting state, reject the connection. */
127 btsnd_hcic_reject_conn(bd_addr, HCI_ERR_HOST_REJECT_DEVICE);
128 } else {
129 L2CAP_TRACE_ERROR(
130 "L2CAP got conn_req while connected (state:%d). Reject it",
131 p_lcb->link_state);
132 /* Reject the connection with ACL Connection Already exist reason */
133 btsnd_hcic_reject_conn(bd_addr, HCI_ERR_CONNECTION_EXISTS);
134 }
135 return (false);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800136}
137
138/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800139 *
140 * Function l2c_link_hci_conn_comp
141 *
142 * Description This function is called when an HCI Connection Complete
143 * event is received.
144 *
145 * Returns void
146 *
147 ******************************************************************************/
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700148bool l2c_link_hci_conn_comp(uint8_t status, uint16_t handle,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700149 const RawAddress& p_bda) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800150 tL2C_CONN_INFO ci;
151 tL2C_LCB* p_lcb;
152 tL2C_CCB* p_ccb;
153 tBTM_SEC_DEV_REC* p_dev_info = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800154
Myles Watson911d1ae2016-11-28 16:44:40 -0800155 btm_acl_update_busy_level(BTM_BLI_PAGE_DONE_EVT);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800156
Myles Watson911d1ae2016-11-28 16:44:40 -0800157 /* Save the parameters */
158 ci.status = status;
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700159 ci.bd_addr = p_bda;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800160
Myles Watson911d1ae2016-11-28 16:44:40 -0800161 /* See if we have a link control block for the remote device */
162 p_lcb = l2cu_find_lcb_by_bd_addr(ci.bd_addr, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800163
Myles Watson911d1ae2016-11-28 16:44:40 -0800164 /* If we don't have one, this is an error */
165 if (!p_lcb) {
166 L2CAP_TRACE_WARNING("L2CAP got conn_comp for unknown BD_ADDR");
167 return (false);
168 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800169
Myles Watson911d1ae2016-11-28 16:44:40 -0800170 if (p_lcb->link_state != LST_CONNECTING) {
171 L2CAP_TRACE_ERROR("L2CAP got conn_comp in bad state: %d status: 0x%d",
172 p_lcb->link_state, status);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800173
Myles Watson911d1ae2016-11-28 16:44:40 -0800174 if (status != HCI_SUCCESS) l2c_link_hci_disc_comp(p_lcb->handle, status);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800175
Myles Watson911d1ae2016-11-28 16:44:40 -0800176 return (false);
177 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800178
Myles Watson911d1ae2016-11-28 16:44:40 -0800179 /* Save the handle */
180 p_lcb->handle = handle;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800181
Myles Watson911d1ae2016-11-28 16:44:40 -0800182 if (ci.status == HCI_SUCCESS) {
183 /* Connected OK. Change state to connected */
184 p_lcb->link_state = LST_CONNECTED;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800185
Myles Watson911d1ae2016-11-28 16:44:40 -0800186 /* Get the peer information if the l2cap flow-control/rtrans is supported */
187 l2cu_send_peer_info_req(p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800188
Myles Watson911d1ae2016-11-28 16:44:40 -0800189 /* Tell BTM Acl management about the link */
190 p_dev_info = btm_find_dev(p_bda);
191 if (p_dev_info != NULL)
192 btm_acl_created(ci.bd_addr, p_dev_info->dev_class,
193 p_dev_info->sec_bd_name, handle, p_lcb->link_role,
194 BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800195 else
Myles Watson911d1ae2016-11-28 16:44:40 -0800196 btm_acl_created(ci.bd_addr, NULL, NULL, handle, p_lcb->link_role,
197 BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800198
Myles Watson911d1ae2016-11-28 16:44:40 -0800199 BTM_SetLinkSuperTout(ci.bd_addr, btm_cb.btm_def_link_super_tout);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800200
Myles Watson911d1ae2016-11-28 16:44:40 -0800201 /* If dedicated bonding do not process any further */
202 if (p_lcb->is_bonding) {
203 if (l2cu_start_post_bond_timer(handle)) return (true);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800204 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800205
Myles Watson911d1ae2016-11-28 16:44:40 -0800206 /* Update the timeouts in the hold queue */
207 l2c_process_held_packets(false);
208
209 alarm_cancel(p_lcb->l2c_lcb_timer);
210
211 /* For all channels, send the event through their FSMs */
212 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
213 p_ccb = p_ccb->p_next_ccb) {
214 l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM, &ci);
215 }
216
217 if (p_lcb->p_echo_rsp_cb) {
218 l2cu_send_peer_echo_req(p_lcb, NULL, 0);
219 alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_ECHO_RSP_TIMEOUT_MS,
220 l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
221 } else if (!p_lcb->ccb_queue.p_first_ccb) {
222 period_ms_t timeout_ms = L2CAP_LINK_STARTUP_TOUT * 1000;
223 alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms,
224 l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
225 }
226 }
227 /* Max number of acl connections. */
228 /* If there's an lcb disconnecting set this one to holding */
229 else if ((ci.status == HCI_ERR_MAX_NUM_OF_CONNECTIONS) &&
230 l2cu_lcb_disconnecting()) {
231 p_lcb->link_state = LST_CONNECT_HOLDING;
232 p_lcb->handle = HCI_INVALID_HANDLE;
233 } else {
234 /* Just in case app decides to try again in the callback context */
235 p_lcb->link_state = LST_DISCONNECTING;
236
237 /* Connection failed. For all channels, send the event through */
238 /* their FSMs. The CCBs should remove themselves from the LCB */
239 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
240 tL2C_CCB* pn = p_ccb->p_next_ccb;
241
242 l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM_NEG, &ci);
243
244 p_ccb = pn;
245 }
246
247 p_lcb->disc_reason = status;
248 /* Release the LCB */
249 if (p_lcb->ccb_queue.p_first_ccb == NULL)
250 l2cu_release_lcb(p_lcb);
251 else /* there are any CCBs remaining */
252 {
253 if (ci.status == HCI_ERR_CONNECTION_EXISTS) {
254 /* we are in collision situation, wait for connecttion request from
255 * controller */
256 p_lcb->link_state = LST_CONNECTING;
257 } else {
258 l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR);
259 }
260 }
261 }
262 return (true);
263}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800264
265/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800266 *
267 * Function l2c_link_sec_comp
268 *
269 * Description This function is called when required security procedures
270 * are completed.
271 *
272 * Returns void
273 *
274 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700275void l2c_link_sec_comp(const RawAddress* p_bda,
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700276 UNUSED_ATTR tBT_TRANSPORT transport, void* p_ref_data,
277 uint8_t status) {
278 l2c_link_sec_comp2(*p_bda, transport, p_ref_data, status);
279}
280
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700281void l2c_link_sec_comp2(const RawAddress& p_bda,
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700282 UNUSED_ATTR tBT_TRANSPORT transport, void* p_ref_data,
283 uint8_t status) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800284 tL2C_CONN_INFO ci;
285 tL2C_LCB* p_lcb;
286 tL2C_CCB* p_ccb;
287 tL2C_CCB* p_next_ccb;
288 uint8_t event;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800289
Myles Watson911d1ae2016-11-28 16:44:40 -0800290 L2CAP_TRACE_DEBUG("l2c_link_sec_comp: %d, 0x%x", status, p_ref_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800291
Myles Watson911d1ae2016-11-28 16:44:40 -0800292 if (status == BTM_SUCCESS_NO_SECURITY) status = BTM_SUCCESS;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800293
Myles Watson911d1ae2016-11-28 16:44:40 -0800294 /* Save the parameters */
295 ci.status = status;
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700296 ci.bd_addr = p_bda;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800297
Myles Watson911d1ae2016-11-28 16:44:40 -0800298 p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, transport);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800299
Myles Watson911d1ae2016-11-28 16:44:40 -0800300 /* If we don't have one, this is an error */
301 if (!p_lcb) {
302 L2CAP_TRACE_WARNING("L2CAP got sec_comp for unknown BD_ADDR");
303 return;
304 }
305
306 /* Match p_ccb with p_ref_data returned by sec manager */
307 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
308 p_next_ccb = p_ccb->p_next_ccb;
309
310 if (p_ccb == p_ref_data) {
311 switch (status) {
312 case BTM_SUCCESS:
313 event = L2CEVT_SEC_COMP;
314 break;
315
316 case BTM_DELAY_CHECK:
317 /* start a timer - encryption change not received before L2CAP connect
318 * req */
319 alarm_set_on_queue(
320 p_ccb->l2c_ccb_timer, L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
321 l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
322 return;
323
324 default:
325 event = L2CEVT_SEC_COMP_NEG;
326 }
327 l2c_csm_execute(p_ccb, event, &ci);
328 break;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800329 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800330 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800331}
332
The Android Open Source Project5738f832012-12-12 16:00:35 -0800333/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800334 *
335 * Function l2c_link_hci_disc_comp
336 *
337 * Description This function is called when an HCI Disconnect Complete
338 * event is received.
339 *
340 * Returns true if the link is known about, else false
341 *
342 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800343bool l2c_link_hci_disc_comp(uint16_t handle, uint8_t reason) {
344 tL2C_LCB* p_lcb;
345 tL2C_CCB* p_ccb;
346 bool status = true;
347 bool lcb_is_free = true;
348 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800349
Myles Watson911d1ae2016-11-28 16:44:40 -0800350 /* See if we have a link control block for the connection */
351 p_lcb = l2cu_find_lcb_by_handle(handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800352
Myles Watson911d1ae2016-11-28 16:44:40 -0800353 /* If we don't have one, maybe an SCO link. Send to MM */
354 if (!p_lcb) {
355 status = false;
356 } else {
357 /* There can be a case when we rejected PIN code authentication */
358 /* otherwise save a new reason */
359 if (btm_cb.acl_disc_reason != HCI_ERR_HOST_REJECT_SECURITY)
360 btm_cb.acl_disc_reason = reason;
361
362 p_lcb->disc_reason = btm_cb.acl_disc_reason;
363
364 /* Just in case app decides to try again in the callback context */
365 p_lcb->link_state = LST_DISCONNECTING;
366
367 /* Check for BLE and handle that differently */
368 if (p_lcb->transport == BT_TRANSPORT_LE)
369 btm_ble_update_link_topology_mask(p_lcb->link_role, false);
370 /* Link is disconnected. For all channels, send the event through */
371 /* their FSMs. The CCBs should remove themselves from the LCB */
372 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
373 tL2C_CCB* pn = p_ccb->p_next_ccb;
374
375 /* Keep connect pending control block (if exists)
376 * Possible Race condition when a reconnect occurs
377 * on the channel during a disconnect of link. This
378 * ccb will be automatically retried after link disconnect
379 * arrives
380 */
381 if (p_ccb != p_lcb->p_pending_ccb) {
382 l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, &reason);
383 }
384 p_ccb = pn;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800385 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800386
Ganesh Ganapathi Batta8fe58872014-04-16 16:50:09 -0700387#if (BTM_SCO_INCLUDED == TRUE)
Myles Watson911d1ae2016-11-28 16:44:40 -0800388 if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
389 /* Tell SCO management to drop any SCOs on this ACL */
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700390 btm_sco_acl_removed(&p_lcb->remote_bd_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800391#endif
392
Myles Watson911d1ae2016-11-28 16:44:40 -0800393 /* If waiting for disconnect and reconnect is pending start the reconnect
394 now
395 race condition where layer above issued connect request on link that was
396 disconnecting
397 */
398 if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb) {
399 L2CAP_TRACE_DEBUG(
400 "l2c_link_hci_disc_comp: Restarting pending ACL request");
401 transport = p_lcb->transport;
402 /* for LE link, always drop and re-open to ensure to get LE remote feature
403 */
404 if (p_lcb->transport == BT_TRANSPORT_LE) {
405 l2cb.is_ble_connecting = false;
406 btm_acl_removed(p_lcb->remote_bd_addr, p_lcb->transport);
407 /* Release any held buffers */
408 BT_HDR* p_buf;
409 while (!list_is_empty(p_lcb->link_xmit_data_q)) {
410 p_buf = static_cast<BT_HDR*>(list_front(p_lcb->link_xmit_data_q));
411 list_remove(p_lcb->link_xmit_data_q, p_buf);
412 osi_free(p_buf);
413 }
414 } else {
Pavlin Radoslavove34b0eb2016-05-16 17:14:03 -0700415#if (L2CAP_NUM_FIXED_CHNLS > 0)
Myles Watson911d1ae2016-11-28 16:44:40 -0800416 /* If we are going to re-use the LCB without dropping it, release all
417 fixed channels
418 here */
419 int xx;
420 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
421 if (p_lcb->p_fixed_ccbs[xx] &&
422 p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) {
423 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
424 xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false,
425 p_lcb->disc_reason, p_lcb->transport);
426 if (p_lcb->p_fixed_ccbs[xx] == NULL) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800427 L2CAP_TRACE_ERROR(
428 "%s: unexpected p_fixed_ccbs[%d] is NULL remote_bd_addr = %s "
429 "p_lcb = %p in_use = %d link_state = %d handle = %d "
430 "link_role = %d is_bonding = %d disc_reason = %d transport = "
431 "%d",
Jakub Pawlowskib707f442017-07-03 15:39:36 -0700432 __func__, xx, p_lcb->remote_bd_addr.ToString().c_str(), p_lcb,
433 p_lcb->in_use, p_lcb->link_state, p_lcb->handle,
Myles Watson911d1ae2016-11-28 16:44:40 -0800434 p_lcb->link_role, p_lcb->is_bonding, p_lcb->disc_reason,
435 p_lcb->transport);
436 }
Jack Hef2af1c42016-12-13 01:59:12 -0800437 CHECK(p_lcb->p_fixed_ccbs[xx] != NULL);
Myles Watson911d1ae2016-11-28 16:44:40 -0800438 l2cu_release_ccb(p_lcb->p_fixed_ccbs[xx]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800439
Myles Watson911d1ae2016-11-28 16:44:40 -0800440 p_lcb->p_fixed_ccbs[xx] = NULL;
Prerepa Viswanadham7ae25152014-09-10 17:08:11 -0700441 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800442 }
Ganesh Ganapathi Batta8fe58872014-04-16 16:50:09 -0700443#endif
Myles Watson911d1ae2016-11-28 16:44:40 -0800444 }
445 if (l2cu_create_conn(p_lcb, transport))
446 lcb_is_free = false; /* still using this lcb */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800447 }
448
Myles Watson911d1ae2016-11-28 16:44:40 -0800449 p_lcb->p_pending_ccb = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800450
Myles Watson911d1ae2016-11-28 16:44:40 -0800451 /* Release the LCB */
452 if (lcb_is_free) l2cu_release_lcb(p_lcb);
453 }
454
455 /* Now that we have a free acl connection, see if any lcbs are pending */
456 if (lcb_is_free &&
457 ((p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING)) != NULL)) {
458 /* we found one-- create a connection */
459 l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR);
460 }
461
462 return status;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800463}
464
The Android Open Source Project5738f832012-12-12 16:00:35 -0800465/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800466 *
467 * Function l2c_link_hci_qos_violation
468 *
469 * Description This function is called when an HCI QOS Violation
470 * event is received.
471 *
472 * Returns true if the link is known about, else false
473 *
474 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800475bool l2c_link_hci_qos_violation(uint16_t handle) {
476 tL2C_LCB* p_lcb;
477 tL2C_CCB* p_ccb;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800478
Myles Watson911d1ae2016-11-28 16:44:40 -0800479 /* See if we have a link control block for the connection */
480 p_lcb = l2cu_find_lcb_by_handle(handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800481
Myles Watson911d1ae2016-11-28 16:44:40 -0800482 /* If we don't have one, maybe an SCO link. */
483 if (!p_lcb) return (false);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800484
Myles Watson911d1ae2016-11-28 16:44:40 -0800485 /* For all channels, tell the upper layer about it */
486 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
487 if (p_ccb->p_rcb->api.pL2CA_QoSViolationInd_Cb)
488 l2c_csm_execute(p_ccb, L2CEVT_LP_QOS_VIOLATION_IND, NULL);
489 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800490
Myles Watson911d1ae2016-11-28 16:44:40 -0800491 return (true);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800492}
493
The Android Open Source Project5738f832012-12-12 16:00:35 -0800494/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800495 *
496 * Function l2c_link_timeout
497 *
498 * Description This function is called when a link timer expires
499 *
500 * Returns void
501 *
502 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800503void l2c_link_timeout(tL2C_LCB* p_lcb) {
504 tL2C_CCB* p_ccb;
505 tBTM_STATUS rc;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800506
Myles Watson911d1ae2016-11-28 16:44:40 -0800507 L2CAP_TRACE_EVENT(
508 "L2CAP - l2c_link_timeout() link state %d first CCB %p is_bonding:%d",
509 p_lcb->link_state, p_lcb->ccb_queue.p_first_ccb, p_lcb->is_bonding);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800510
Myles Watson911d1ae2016-11-28 16:44:40 -0800511 /* If link was connecting or disconnecting, clear all channels and drop the
512 * LCB */
513 if ((p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH) ||
514 (p_lcb->link_state == LST_CONNECTING) ||
515 (p_lcb->link_state == LST_CONNECT_HOLDING) ||
516 (p_lcb->link_state == LST_DISCONNECTING)) {
517 p_lcb->p_pending_ccb = NULL;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800518
Myles Watson911d1ae2016-11-28 16:44:40 -0800519 /* For all channels, send a disconnect indication event through */
520 /* their FSMs. The CCBs should remove themselves from the LCB */
521 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
522 tL2C_CCB* pn = p_ccb->p_next_ccb;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800523
Myles Watson911d1ae2016-11-28 16:44:40 -0800524 l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800525
Myles Watson911d1ae2016-11-28 16:44:40 -0800526 p_ccb = pn;
527 }
528 if (p_lcb->link_state == LST_CONNECTING && l2cb.is_ble_connecting == true) {
529 L2CA_CancelBleConnectReq(l2cb.ble_connecting_bda);
530 }
531 /* Release the LCB */
532 l2cu_release_lcb(p_lcb);
533 }
534
535 /* If link is connected, check for inactivity timeout */
536 if (p_lcb->link_state == LST_CONNECTED) {
537 /* Check for ping outstanding */
538 if (p_lcb->p_echo_rsp_cb) {
539 tL2CA_ECHO_RSP_CB* p_cb = p_lcb->p_echo_rsp_cb;
540
541 /* Zero out the callback in case app immediately calls us again */
542 p_lcb->p_echo_rsp_cb = NULL;
543
544 (*p_cb)(L2CAP_PING_RESULT_NO_RESP);
545
546 L2CAP_TRACE_WARNING("L2CAP - ping timeout");
547
548 /* For all channels, send a disconnect indication event through */
549 /* their FSMs. The CCBs should remove themselves from the LCB */
550 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
551 tL2C_CCB* pn = p_ccb->p_next_ccb;
552
553 l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL);
554
555 p_ccb = pn;
556 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800557 }
558
Myles Watson911d1ae2016-11-28 16:44:40 -0800559 /* If no channels in use, drop the link. */
560 if (!p_lcb->ccb_queue.p_first_ccb) {
561 period_ms_t timeout_ms;
562 bool start_timeout = true;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800563
Myles Watson911d1ae2016-11-28 16:44:40 -0800564 rc = btm_sec_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800565
Myles Watson911d1ae2016-11-28 16:44:40 -0800566 if (rc == BTM_CMD_STORED) {
567 /* Security Manager will take care of disconnecting, state will be
568 * updated at that time */
569 start_timeout = false;
570 } else if (rc == BTM_CMD_STARTED) {
571 p_lcb->link_state = LST_DISCONNECTING;
572 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
573 } else if (rc == BTM_SUCCESS) {
574 l2cu_process_fixed_disc_cback(p_lcb);
575 /* BTM SEC will make sure that link is release (probably after pairing
576 * is done) */
577 p_lcb->link_state = LST_DISCONNECTING;
578 start_timeout = false;
579 } else if (rc == BTM_BUSY) {
580 /* BTM is still executing security process. Let lcb stay as connected */
581 start_timeout = false;
582 } else if (p_lcb->is_bonding) {
583 btsnd_hcic_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
584 l2cu_process_fixed_disc_cback(p_lcb);
585 p_lcb->link_state = LST_DISCONNECTING;
586 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
587 } else {
588 /* probably no buffer to send disconnect */
589 timeout_ms = BT_1SEC_TIMEOUT_MS;
590 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800591
Myles Watson911d1ae2016-11-28 16:44:40 -0800592 if (start_timeout) {
593 alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms,
594 l2c_lcb_timer_timeout, p_lcb,
595 btu_general_alarm_queue);
596 }
597 } else {
598 /* Check in case we were flow controlled */
599 l2c_link_check_send_pkts(p_lcb, NULL, NULL);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800600 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800601 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800602}
603
604/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800605 *
606 * Function l2c_info_resp_timer_timeout
607 *
608 * Description This function is called when an info request times out
609 *
610 * Returns void
611 *
612 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800613void l2c_info_resp_timer_timeout(void* data) {
614 tL2C_LCB* p_lcb = (tL2C_LCB*)data;
615 tL2C_CCB* p_ccb;
616 tL2C_CONN_INFO ci;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800617
Myles Watson911d1ae2016-11-28 16:44:40 -0800618 /* If we timed out waiting for info response, just continue using basic if
619 * allowed */
620 if (p_lcb->w4_info_rsp) {
621 /* If waiting for security complete, restart the info response timer */
622 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
623 p_ccb = p_ccb->p_next_ccb) {
624 if ((p_ccb->chnl_state == CST_ORIG_W4_SEC_COMP) ||
625 (p_ccb->chnl_state == CST_TERM_W4_SEC_COMP)) {
626 alarm_set_on_queue(
627 p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
628 l2c_info_resp_timer_timeout, p_lcb, btu_general_alarm_queue);
629 return;
630 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800631 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800632
633 p_lcb->w4_info_rsp = false;
634
635 /* If link is in process of being brought up */
636 if ((p_lcb->link_state != LST_DISCONNECTED) &&
637 (p_lcb->link_state != LST_DISCONNECTING)) {
638 /* Notify active channels that peer info is finished */
639 if (p_lcb->ccb_queue.p_first_ccb) {
640 ci.status = HCI_SUCCESS;
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700641 ci.bd_addr = p_lcb->remote_bd_addr;
Myles Watson911d1ae2016-11-28 16:44:40 -0800642
643 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
644 p_ccb = p_ccb->p_next_ccb) {
645 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
646 }
647 }
648 }
649 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800650}
651
652/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800653 *
654 * Function l2c_link_adjust_allocation
655 *
656 * Description This function is called when a link is created or removed
657 * to calculate the amount of packets each link may send to
658 * the HCI without an ack coming back.
659 *
660 * Currently, this is a simple allocation, dividing the
661 * number of Controller Packets by the number of links. In
662 * the future, QOS configuration should be examined.
663 *
664 * Returns void
665 *
666 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800667void l2c_link_adjust_allocation(void) {
668 uint16_t qq, yy, qq_remainder;
669 tL2C_LCB* p_lcb;
670 uint16_t hi_quota, low_quota;
671 uint16_t num_lowpri_links = 0;
672 uint16_t num_hipri_links = 0;
673 uint16_t controller_xmit_quota = l2cb.num_lm_acl_bufs;
674 uint16_t high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800675
Myles Watson911d1ae2016-11-28 16:44:40 -0800676 /* If no links active, reset buffer quotas and controller buffers */
677 if (l2cb.num_links_active == 0) {
678 l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
679 l2cb.round_robin_quota = l2cb.round_robin_unacked = 0;
680 return;
681 }
682
683 /* First, count the links */
684 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
685 if (p_lcb->in_use) {
686 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
687 num_hipri_links++;
688 else
689 num_lowpri_links++;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800690 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800691 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800692
Myles Watson911d1ae2016-11-28 16:44:40 -0800693 /* now adjust high priority link quota */
694 low_quota = num_lowpri_links ? 1 : 0;
695 while ((num_hipri_links * high_pri_link_quota + low_quota) >
696 controller_xmit_quota)
697 high_pri_link_quota--;
698
699 /* Work out the xmit quota and buffer quota high and low priorities */
700 hi_quota = num_hipri_links * high_pri_link_quota;
701 low_quota =
702 (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
703
704 /* Work out and save the HCI xmit quota for each low priority link */
705
706 /* If each low priority link cannot have at least one buffer */
707 if (num_lowpri_links > low_quota) {
708 l2cb.round_robin_quota = low_quota;
709 qq = qq_remainder = 1;
710 }
711 /* If each low priority link can have at least one buffer */
712 else if (num_lowpri_links > 0) {
713 l2cb.round_robin_quota = 0;
714 l2cb.round_robin_unacked = 0;
715 qq = low_quota / num_lowpri_links;
716 qq_remainder = low_quota % num_lowpri_links;
717 }
718 /* If no low priority link */
719 else {
720 l2cb.round_robin_quota = 0;
721 l2cb.round_robin_unacked = 0;
722 qq = qq_remainder = 1;
723 }
724
725 L2CAP_TRACE_EVENT(
726 "l2c_link_adjust_allocation num_hipri: %u num_lowpri: %u low_quota: "
727 "%u round_robin_quota: %u qq: %u",
728 num_hipri_links, num_lowpri_links, low_quota, l2cb.round_robin_quota, qq);
729
730 /* Now, assign the quotas to each link */
731 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
732 if (p_lcb->in_use) {
733 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
734 p_lcb->link_xmit_quota = high_pri_link_quota;
735 } else {
736 /* Safety check in case we switched to round-robin with something
737 * outstanding */
738 /* if sent_not_acked is added into round_robin_unacked then don't add it
739 * again */
740 /* l2cap keeps updating sent_not_acked for exiting from round robin */
741 if ((p_lcb->link_xmit_quota > 0) && (qq == 0))
742 l2cb.round_robin_unacked += p_lcb->sent_not_acked;
743
744 p_lcb->link_xmit_quota = qq;
745 if (qq_remainder > 0) {
746 p_lcb->link_xmit_quota++;
747 qq_remainder--;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800748 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800749 }
750
751 L2CAP_TRACE_EVENT(
752 "l2c_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d", yy,
753 p_lcb->acl_priority, p_lcb->link_xmit_quota);
754
755 L2CAP_TRACE_EVENT(" SentNotAcked: %d RRUnacked: %d",
756 p_lcb->sent_not_acked, l2cb.round_robin_unacked);
757
758 /* There is a special case where we have readjusted the link quotas and */
759 /* this link may have sent anything but some other link sent packets so */
760 /* so we may need a timer to kick off this link's transmissions. */
761 if ((p_lcb->link_state == LST_CONNECTED) &&
762 (!list_is_empty(p_lcb->link_xmit_data_q)) &&
763 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
764 alarm_set_on_queue(
765 p_lcb->l2c_lcb_timer, L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
766 l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
767 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800768 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800769 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800770}
771
772/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800773 *
774 * Function l2c_link_adjust_chnl_allocation
775 *
Myles Watson9ca07092016-11-28 16:41:53 -0800776 * Description This function is called to calculate the amount of packets
777 * each non-F&EC channel may have outstanding.
Myles Watsonee96a3c2016-11-23 14:49:54 -0800778 *
779 * Currently, this is a simple allocation, dividing the number
Myles Watson9ca07092016-11-28 16:41:53 -0800780 * of packets allocated to the link by the number of channels.
781 * In the future, QOS configuration should be examined.
Myles Watsonee96a3c2016-11-23 14:49:54 -0800782 *
783 * Returns void
784 *
785 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800786void l2c_link_adjust_chnl_allocation(void) {
787 uint8_t xx;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800788
Myles Watson911d1ae2016-11-28 16:44:40 -0800789 L2CAP_TRACE_DEBUG("%s", __func__);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800790
Myles Watson911d1ae2016-11-28 16:44:40 -0800791 /* assign buffer quota to each channel based on its data rate requirement */
792 for (xx = 0; xx < MAX_L2CAP_CHANNELS; xx++) {
793 tL2C_CCB* p_ccb = l2cb.ccb_pool + xx;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800794
Myles Watson911d1ae2016-11-28 16:44:40 -0800795 if (!p_ccb->in_use) continue;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800796
Myles Watson911d1ae2016-11-28 16:44:40 -0800797 tL2CAP_CHNL_DATA_RATE data_rate = p_ccb->tx_data_rate + p_ccb->rx_data_rate;
798 p_ccb->buff_quota = L2CAP_CBB_DEFAULT_DATA_RATE_BUFF_QUOTA * data_rate;
799 L2CAP_TRACE_EVENT(
800 "CID:0x%04x FCR Mode:%u Priority:%u TxDataRate:%u RxDataRate:%u "
801 "Quota:%u",
802 p_ccb->local_cid, p_ccb->peer_cfg.fcr.mode, p_ccb->ccb_priority,
803 p_ccb->tx_data_rate, p_ccb->rx_data_rate, p_ccb->buff_quota);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800804
Myles Watson911d1ae2016-11-28 16:44:40 -0800805 /* quota may be change so check congestion */
806 l2cu_check_channel_congestion(p_ccb);
807 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800808}
809
810/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800811 *
812 * Function l2c_link_processs_num_bufs
813 *
814 * Description This function is called when a "controller buffer size"
815 * event is first received from the controller. It updates
816 * the L2CAP values.
817 *
818 * Returns void
819 *
820 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800821void l2c_link_processs_num_bufs(uint16_t num_lm_acl_bufs) {
822 l2cb.num_lm_acl_bufs = l2cb.controller_xmit_window = num_lm_acl_bufs;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800823}
824
825/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800826 *
827 * Function l2c_link_pkts_rcvd
828 *
Myles Watson9ca07092016-11-28 16:41:53 -0800829 * Description This function is called from the HCI transport when it is
830 * time to send a "Host ready for packets" command. This is
831 * only when host to controller flow control is used. It fills
832 * in the arrays of numbers of packets and handles.
Myles Watsonee96a3c2016-11-23 14:49:54 -0800833 *
834 * Returns count of number of entries filled in
835 *
836 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800837uint8_t l2c_link_pkts_rcvd(UNUSED_ATTR uint16_t* num_pkts,
838 UNUSED_ATTR uint16_t* handles) {
839 uint8_t num_found = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800840
Myles Watson911d1ae2016-11-28 16:44:40 -0800841 return (num_found);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800842}
843
844/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800845 *
846 * Function l2c_link_role_changed
847 *
Myles Watson9ca07092016-11-28 16:41:53 -0800848 * Description This function is called whan a link's master/slave role
849 * change event is received. It simply updates the link control
850 * block.
Myles Watsonee96a3c2016-11-23 14:49:54 -0800851 *
852 * Returns void
853 *
854 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700855void l2c_link_role_changed(const RawAddress* bd_addr, uint8_t new_role,
Myles Watson911d1ae2016-11-28 16:44:40 -0800856 uint8_t hci_status) {
857 tL2C_LCB* p_lcb;
858 int xx;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800859
Myles Watson911d1ae2016-11-28 16:44:40 -0800860 /* Make sure not called from HCI Command Status (bd_addr and new_role are
861 * invalid) */
862 if (bd_addr) {
863 /* If here came form hci role change event */
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700864 p_lcb = l2cu_find_lcb_by_bd_addr(*bd_addr, BT_TRANSPORT_BR_EDR);
Myles Watson911d1ae2016-11-28 16:44:40 -0800865 if (p_lcb) {
866 p_lcb->link_role = new_role;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800867
Myles Watson911d1ae2016-11-28 16:44:40 -0800868 /* Reset high priority link if needed */
869 if (hci_status == HCI_SUCCESS)
Jakub Pawlowskic2276b02017-06-09 16:00:25 -0700870 l2cu_set_acl_priority(*bd_addr, p_lcb->acl_priority, true);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800871 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800872 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800873
Myles Watson911d1ae2016-11-28 16:44:40 -0800874 /* Check if any LCB was waiting for switch to be completed */
875 for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
876 if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH)) {
877 l2cu_create_conn_after_switch(p_lcb);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800878 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800879 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800880}
881
882/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800883 *
884 * Function l2c_pin_code_request
885 *
886 * Description This function is called whan a pin-code request is received
887 * on a connection. If there are no channels active yet on the
888 * link, it extends the link first connection timer. Make sure
889 * that inactivity timer is not extended if PIN code happens
890 * to be after last ccb released.
891 *
892 * Returns void
893 *
894 ******************************************************************************/
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700895void l2c_pin_code_request(const RawAddress& bd_addr) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800896 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800897
Myles Watson911d1ae2016-11-28 16:44:40 -0800898 if ((p_lcb) && (!p_lcb->ccb_queue.p_first_ccb)) {
899 alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_EXT_TIMEOUT_MS,
900 l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
901 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800902}
903
Marie Janssend19e0782016-07-15 12:48:27 -0700904#if (L2CAP_WAKE_PARKED_LINK == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800905/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800906 *
907 * Function l2c_link_check_power_mode
908 *
909 * Description This function is called to check power mode.
910 *
911 * Returns true if link is going to be active from park
912 * false if nothing to send or not in park mode
913 *
914 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800915bool l2c_link_check_power_mode(tL2C_LCB* p_lcb) {
916 tBTM_PM_MODE mode;
917 tL2C_CCB* p_ccb;
918 bool need_to_active = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800919
Myles Watson911d1ae2016-11-28 16:44:40 -0800920 /*
921 * We only switch park to active only if we have unsent packets
922 */
923 if (list_is_empty(p_lcb->link_xmit_data_q)) {
924 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
925 p_ccb = p_ccb->p_next_ccb) {
926 if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
Marie Janssend19e0782016-07-15 12:48:27 -0700927 need_to_active = true;
Myles Watson911d1ae2016-11-28 16:44:40 -0800928 break;
929 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800930 }
Myles Watson911d1ae2016-11-28 16:44:40 -0800931 } else
932 need_to_active = true;
933
934 /* if we have packets to send */
935 if (need_to_active) {
936 /* check power mode */
937 if (BTM_ReadPowerMode(p_lcb->remote_bd_addr, &mode) == BTM_SUCCESS) {
938 if (mode == BTM_PM_STS_PENDING) {
939 L2CAP_TRACE_DEBUG("LCB(0x%x) is in PM pending state", p_lcb->handle);
940
941 return true;
942 }
943 }
944 }
945 return false;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800946}
Chris Mantone7ef4652014-10-15 16:31:49 -0700947#endif /* L2CAP_WAKE_PARKED_LINK == TRUE) */
The Android Open Source Project5738f832012-12-12 16:00:35 -0800948
949/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -0800950 *
951 * Function l2c_link_check_send_pkts
952 *
953 * Description This function is called to check if it can send packets
954 * to the Host Controller. It may be passed the address of
955 * a packet to send.
956 *
957 * Returns void
958 *
959 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -0800960void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) {
961 int xx;
962 bool single_write = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800963
Myles Watson911d1ae2016-11-28 16:44:40 -0800964 /* Save the channel ID for faster counting */
965 if (p_buf) {
966 if (p_ccb != NULL) {
967 p_buf->event = p_ccb->local_cid;
968 single_write = true;
969 } else
970 p_buf->event = 0;
971
972 p_buf->layer_specific = 0;
973 list_append(p_lcb->link_xmit_data_q, p_buf);
974
975 if (p_lcb->link_xmit_quota == 0) {
976 if (p_lcb->transport == BT_TRANSPORT_LE)
977 l2cb.ble_check_round_robin = true;
978 else
979 l2cb.check_round_robin = true;
980 }
981 }
982
983 /* If this is called from uncongested callback context break recursive
984 *calling.
985 ** This LCB will be served when receiving number of completed packet event.
986 */
987 if (l2cb.is_cong_cback_context) return;
988
989 /* If we are in a scenario where there are not enough buffers for each link to
990 ** have at least 1, then do a round-robin for all the LCBs
991 */
992 if ((p_lcb == NULL) || (p_lcb->link_xmit_quota == 0)) {
993 if (p_lcb == NULL)
994 p_lcb = l2cb.lcb_pool;
995 else if (!single_write)
996 p_lcb++;
997
998 /* Loop through, starting at the next */
999 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
Yamei Du35e95c92015-11-18 17:28:07 +08001000 /* Check for wraparound */
1001 if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) p_lcb = &l2cb.lcb_pool[0];
1002
Myles Watson911d1ae2016-11-28 16:44:40 -08001003 /* If controller window is full, nothing to do */
1004 if (((l2cb.controller_xmit_window == 0 ||
1005 (l2cb.round_robin_unacked >= l2cb.round_robin_quota)) &&
1006 (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
1007 (p_lcb->transport == BT_TRANSPORT_LE &&
1008 (l2cb.ble_round_robin_unacked >= l2cb.ble_round_robin_quota ||
1009 l2cb.controller_le_xmit_window == 0)))
Ruina Liubd6b1222015-09-24 10:04:16 +08001010 continue;
Myles Watson911d1ae2016-11-28 16:44:40 -08001011
Myles Watson911d1ae2016-11-28 16:44:40 -08001012 if ((!p_lcb->in_use) || (p_lcb->partial_segment_being_sent) ||
1013 (p_lcb->link_state != LST_CONNECTED) ||
1014 (p_lcb->link_xmit_quota != 0) || (L2C_LINK_CHECK_POWER_MODE(p_lcb)))
1015 continue;
1016
1017 /* See if we can send anything from the Link Queue */
1018 if (!list_is_empty(p_lcb->link_xmit_data_q)) {
1019 p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q);
1020 list_remove(p_lcb->link_xmit_data_q, p_buf);
Yamei Du35e95c92015-11-18 17:28:07 +08001021 l2c_link_send_to_lower(p_lcb, p_buf, NULL);
Myles Watson911d1ae2016-11-28 16:44:40 -08001022 } else if (single_write) {
1023 /* If only doing one write, break out */
1024 break;
1025 }
1026 /* If nothing on the link queue, check the channel queue */
1027 else {
Yamei Du35e95c92015-11-18 17:28:07 +08001028 tL2C_TX_COMPLETE_CB_INFO cbi;
1029 p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi);
Myles Watson911d1ae2016-11-28 16:44:40 -08001030 if (p_buf != NULL) {
Yamei Du35e95c92015-11-18 17:28:07 +08001031 l2c_link_send_to_lower(p_lcb, p_buf, &cbi);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001032 }
Myles Watson911d1ae2016-11-28 16:44:40 -08001033 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001034 }
1035
Myles Watson911d1ae2016-11-28 16:44:40 -08001036 /* If we finished without using up our quota, no need for a safety check */
1037 if ((l2cb.controller_xmit_window > 0) &&
1038 (l2cb.round_robin_unacked < l2cb.round_robin_quota) &&
1039 (p_lcb->transport == BT_TRANSPORT_BR_EDR))
1040 l2cb.check_round_robin = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001041
Myles Watson911d1ae2016-11-28 16:44:40 -08001042 if ((l2cb.controller_le_xmit_window > 0) &&
1043 (l2cb.ble_round_robin_unacked < l2cb.ble_round_robin_quota) &&
1044 (p_lcb->transport == BT_TRANSPORT_LE))
1045 l2cb.ble_check_round_robin = false;
1046 } else /* if this is not round-robin service */
1047 {
1048 /* If a partial segment is being sent, can't send anything else */
1049 if ((p_lcb->partial_segment_being_sent) ||
1050 (p_lcb->link_state != LST_CONNECTED) ||
1051 (L2C_LINK_CHECK_POWER_MODE(p_lcb)))
1052 return;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001053
Myles Watson911d1ae2016-11-28 16:44:40 -08001054 /* See if we can send anything from the link queue */
1055 while (((l2cb.controller_xmit_window != 0 &&
1056 (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
1057 (l2cb.controller_le_xmit_window != 0 &&
1058 (p_lcb->transport == BT_TRANSPORT_LE))) &&
1059 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
1060 if (list_is_empty(p_lcb->link_xmit_data_q)) break;
Satya Calloji444a8da2015-03-06 10:38:22 -08001061
Myles Watson911d1ae2016-11-28 16:44:40 -08001062 p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q);
1063 list_remove(p_lcb->link_xmit_data_q, p_buf);
Yamei Du35e95c92015-11-18 17:28:07 +08001064 if (!l2c_link_send_to_lower(p_lcb, p_buf, NULL)) break;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001065 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001066
Myles Watson911d1ae2016-11-28 16:44:40 -08001067 if (!single_write) {
1068 /* See if we can send anything for any channel */
1069 while (((l2cb.controller_xmit_window != 0 &&
1070 (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
1071 (l2cb.controller_le_xmit_window != 0 &&
1072 (p_lcb->transport == BT_TRANSPORT_LE))) &&
1073 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
Yamei Du35e95c92015-11-18 17:28:07 +08001074 tL2C_TX_COMPLETE_CB_INFO cbi;
1075 p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi);
Myles Watson911d1ae2016-11-28 16:44:40 -08001076 if (p_buf == NULL) break;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001077
Yamei Du35e95c92015-11-18 17:28:07 +08001078 if (!l2c_link_send_to_lower(p_lcb, p_buf, &cbi)) break;
Myles Watson911d1ae2016-11-28 16:44:40 -08001079 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001080 }
Myles Watson911d1ae2016-11-28 16:44:40 -08001081
1082 /* There is a special case where we have readjusted the link quotas and */
1083 /* this link may have sent anything but some other link sent packets so */
1084 /* so we may need a timer to kick off this link's transmissions. */
1085 if ((!list_is_empty(p_lcb->link_xmit_data_q)) &&
1086 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
1087 alarm_set_on_queue(p_lcb->l2c_lcb_timer,
1088 L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
1089 l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
1090 }
1091 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001092}
1093
1094/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -08001095 *
1096 * Function l2c_link_send_to_lower
1097 *
1098 * Description This function queues the buffer for HCI transmission
1099 *
1100 * Returns true for success, false for fail
1101 *
1102 ******************************************************************************/
Jakub Pawlowskic2276b02017-06-09 16:00:25 -07001103static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
1104 tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
Myles Watson911d1ae2016-11-28 16:44:40 -08001105 uint16_t num_segs;
1106 uint16_t xmit_window, acl_data_size;
1107 const controller_t* controller = controller_get_interface();
The Android Open Source Project5738f832012-12-12 16:00:35 -08001108
Myles Watson911d1ae2016-11-28 16:44:40 -08001109 if ((p_buf->len <= controller->get_acl_packet_size_classic() &&
1110 (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
1111 ((p_lcb->transport == BT_TRANSPORT_LE) &&
1112 (p_buf->len <= controller->get_acl_packet_size_ble()))) {
1113 if (p_lcb->link_xmit_quota == 0) {
1114 if (p_lcb->transport == BT_TRANSPORT_LE)
1115 l2cb.ble_round_robin_unacked++;
1116 else
1117 l2cb.round_robin_unacked++;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001118 }
Myles Watson911d1ae2016-11-28 16:44:40 -08001119 p_lcb->sent_not_acked++;
1120 p_buf->layer_specific = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001121
Myles Watson911d1ae2016-11-28 16:44:40 -08001122 if (p_lcb->transport == BT_TRANSPORT_LE) {
1123 l2cb.controller_le_xmit_window--;
1124 bte_main_hci_send(
1125 p_buf, (uint16_t)(BT_EVT_TO_LM_HCI_ACL | LOCAL_BLE_CONTROLLER_ID));
1126 } else {
1127 l2cb.controller_xmit_window--;
1128 bte_main_hci_send(p_buf, BT_EVT_TO_LM_HCI_ACL);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001129 }
Myles Watson911d1ae2016-11-28 16:44:40 -08001130 } else {
1131 if (p_lcb->transport == BT_TRANSPORT_LE) {
1132 acl_data_size = controller->get_acl_data_size_ble();
1133 xmit_window = l2cb.controller_le_xmit_window;
1134
1135 } else {
1136 acl_data_size = controller->get_acl_data_size_classic();
1137 xmit_window = l2cb.controller_xmit_window;
1138 }
1139 num_segs = (p_buf->len - HCI_DATA_PREAMBLE_SIZE + acl_data_size - 1) /
1140 acl_data_size;
1141
1142 /* If doing round-robin, then only 1 segment each time */
1143 if (p_lcb->link_xmit_quota == 0) {
1144 num_segs = 1;
1145 p_lcb->partial_segment_being_sent = true;
1146 } else {
1147 /* Multi-segment packet. Make sure it can fit */
1148 if (num_segs > xmit_window) {
1149 num_segs = xmit_window;
1150 p_lcb->partial_segment_being_sent = true;
1151 }
1152
1153 if (num_segs > (p_lcb->link_xmit_quota - p_lcb->sent_not_acked)) {
1154 num_segs = (p_lcb->link_xmit_quota - p_lcb->sent_not_acked);
1155 p_lcb->partial_segment_being_sent = true;
1156 }
1157 }
1158
1159 p_buf->layer_specific = num_segs;
1160 if (p_lcb->transport == BT_TRANSPORT_LE) {
1161 l2cb.controller_le_xmit_window -= num_segs;
1162 if (p_lcb->link_xmit_quota == 0) l2cb.ble_round_robin_unacked += num_segs;
1163 } else {
1164 l2cb.controller_xmit_window -= num_segs;
1165
1166 if (p_lcb->link_xmit_quota == 0) l2cb.round_robin_unacked += num_segs;
1167 }
1168
1169 p_lcb->sent_not_acked += num_segs;
1170 if (p_lcb->transport == BT_TRANSPORT_LE) {
1171 bte_main_hci_send(
1172 p_buf, (uint16_t)(BT_EVT_TO_LM_HCI_ACL | LOCAL_BLE_CONTROLLER_ID));
1173 } else {
1174 bte_main_hci_send(p_buf, BT_EVT_TO_LM_HCI_ACL);
1175 }
1176 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001177
1178#if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE)
Myles Watson911d1ae2016-11-28 16:44:40 -08001179 if (p_lcb->transport == BT_TRANSPORT_LE) {
1180 L2CAP_TRACE_DEBUG(
1181 "TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
1182 l2cb.controller_le_xmit_window, p_lcb->handle, p_lcb->link_xmit_quota,
1183 p_lcb->sent_not_acked, l2cb.ble_round_robin_quota,
1184 l2cb.ble_round_robin_unacked);
1185 } else {
1186 L2CAP_TRACE_DEBUG(
1187 "TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
1188 l2cb.controller_xmit_window, p_lcb->handle, p_lcb->link_xmit_quota,
1189 p_lcb->sent_not_acked, l2cb.round_robin_quota,
1190 l2cb.round_robin_unacked);
1191 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001192#endif
1193
Jakub Pawlowskic2276b02017-06-09 16:00:25 -07001194 if (p_cbi) l2cu_tx_complete(p_cbi);
Yamei Du35e95c92015-11-18 17:28:07 +08001195
Myles Watson911d1ae2016-11-28 16:44:40 -08001196 return true;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001197}
1198
1199/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -08001200 *
1201 * Function l2c_link_process_num_completed_pkts
1202 *
1203 * Description This function is called when a "number-of-completed-packets"
1204 * event is received from the controller. It updates all the
1205 * LCB transmit counts.
1206 *
1207 * Returns void
1208 *
1209 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -08001210void l2c_link_process_num_completed_pkts(uint8_t* p) {
1211 uint8_t num_handles, xx;
1212 uint16_t handle;
1213 uint16_t num_sent;
1214 tL2C_LCB* p_lcb;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001215
Myles Watson911d1ae2016-11-28 16:44:40 -08001216 STREAM_TO_UINT8(num_handles, p);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001217
Myles Watson911d1ae2016-11-28 16:44:40 -08001218 for (xx = 0; xx < num_handles; xx++) {
1219 STREAM_TO_UINT16(handle, p);
1220 STREAM_TO_UINT16(num_sent, p);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001221
Myles Watson911d1ae2016-11-28 16:44:40 -08001222 p_lcb = l2cu_find_lcb_by_handle(handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001223
Myles Watson911d1ae2016-11-28 16:44:40 -08001224 /* Callback for number of completed packet event */
1225 /* Originally designed for [3DSG] */
1226 if ((p_lcb != NULL) && (p_lcb->p_nocp_cb)) {
1227 L2CAP_TRACE_DEBUG("L2CAP - calling NoCP callback");
1228 (*p_lcb->p_nocp_cb)(p_lcb->remote_bd_addr);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001229 }
1230
Myles Watson911d1ae2016-11-28 16:44:40 -08001231 if (p_lcb) {
1232 if (p_lcb && (p_lcb->transport == BT_TRANSPORT_LE))
1233 l2cb.controller_le_xmit_window += num_sent;
1234 else {
1235 /* Maintain the total window to the controller */
1236 l2cb.controller_xmit_window += num_sent;
1237 }
1238 /* If doing round-robin, adjust communal counts */
1239 if (p_lcb->link_xmit_quota == 0) {
1240 if (p_lcb->transport == BT_TRANSPORT_LE) {
1241 /* Don't go negative */
1242 if (l2cb.ble_round_robin_unacked > num_sent)
1243 l2cb.ble_round_robin_unacked -= num_sent;
1244 else
1245 l2cb.ble_round_robin_unacked = 0;
1246 } else {
1247 /* Don't go negative */
1248 if (l2cb.round_robin_unacked > num_sent)
1249 l2cb.round_robin_unacked -= num_sent;
1250 else
1251 l2cb.round_robin_unacked = 0;
1252 }
1253 }
1254
1255 /* Don't go negative */
1256 if (p_lcb->sent_not_acked > num_sent)
1257 p_lcb->sent_not_acked -= num_sent;
1258 else
1259 p_lcb->sent_not_acked = 0;
1260
1261 l2c_link_check_send_pkts(p_lcb, NULL, NULL);
1262
1263 /* If we were doing round-robin for low priority links, check 'em */
1264 if ((p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) &&
1265 (l2cb.check_round_robin) &&
1266 (l2cb.round_robin_unacked < l2cb.round_robin_quota)) {
1267 l2c_link_check_send_pkts(NULL, NULL, NULL);
1268 }
1269 if ((p_lcb->transport == BT_TRANSPORT_LE) &&
1270 (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) &&
1271 ((l2cb.ble_check_round_robin) &&
1272 (l2cb.ble_round_robin_unacked < l2cb.ble_round_robin_quota))) {
1273 l2c_link_check_send_pkts(NULL, NULL, NULL);
1274 }
1275 }
1276
1277#if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE)
1278 if (p_lcb) {
1279 if (p_lcb->transport == BT_TRANSPORT_LE) {
1280 L2CAP_TRACE_DEBUG(
1281 "TotalWin=%d,LinkUnack(0x%x)=%d,RRCheck=%d,RRUnack=%d",
1282 l2cb.controller_le_xmit_window, p_lcb->handle,
1283 p_lcb->sent_not_acked, l2cb.ble_check_round_robin,
1284 l2cb.ble_round_robin_unacked);
1285 } else {
1286 L2CAP_TRACE_DEBUG(
1287 "TotalWin=%d,LinkUnack(0x%x)=%d,RRCheck=%d,RRUnack=%d",
1288 l2cb.controller_xmit_window, p_lcb->handle, p_lcb->sent_not_acked,
1289 l2cb.check_round_robin, l2cb.round_robin_unacked);
1290 }
1291 } else {
1292 L2CAP_TRACE_DEBUG(
1293 "TotalWin=%d LE_Win: %d, Handle=0x%x, RRCheck=%d, RRUnack=%d",
1294 l2cb.controller_xmit_window, l2cb.controller_le_xmit_window, handle,
1295 l2cb.ble_check_round_robin, l2cb.ble_round_robin_unacked);
1296 }
1297#endif
1298 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001299}
1300
1301/*******************************************************************************
Myles Watsonee96a3c2016-11-23 14:49:54 -08001302 *
1303 * Function l2c_link_segments_xmitted
1304 *
1305 * Description This function is called from the HCI Interface when an ACL
1306 * data packet segment is transmitted.
1307 *
1308 * Returns void
1309 *
1310 ******************************************************************************/
Myles Watson911d1ae2016-11-28 16:44:40 -08001311void l2c_link_segments_xmitted(BT_HDR* p_msg) {
1312 uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
1313 uint16_t handle;
1314 tL2C_LCB* p_lcb;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001315
Myles Watson911d1ae2016-11-28 16:44:40 -08001316 /* Extract the handle */
1317 STREAM_TO_UINT16(handle, p);
1318 handle = HCID_GET_HANDLE(handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001319
Myles Watson911d1ae2016-11-28 16:44:40 -08001320 /* Find the LCB based on the handle */
1321 p_lcb = l2cu_find_lcb_by_handle(handle);
1322 if (p_lcb == NULL) {
1323 L2CAP_TRACE_WARNING("L2CAP - rcvd segment complete, unknown handle: %d",
1324 handle);
1325 osi_free(p_msg);
1326 return;
1327 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001328
Myles Watson911d1ae2016-11-28 16:44:40 -08001329 if (p_lcb->link_state == LST_CONNECTED) {
1330 /* Enqueue the buffer to the head of the transmit queue, and see */
1331 /* if we can transmit anything more. */
1332 list_prepend(p_lcb->link_xmit_data_q, p_msg);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001333
Myles Watson911d1ae2016-11-28 16:44:40 -08001334 p_lcb->partial_segment_being_sent = false;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001335
Myles Watson911d1ae2016-11-28 16:44:40 -08001336 l2c_link_check_send_pkts(p_lcb, NULL, NULL);
1337 } else
1338 osi_free(p_msg);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001339}