1 /******************************************************************************
2 *
3 * Copyright 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 #define LOG_TAG "l2c_link"
27
28 #include <bluetooth/log.h>
29 #include <com_android_bluetooth_flags.h>
30
31 #include <cstdint>
32
33 #include "device/include/device_iot_config.h"
34 #include "internal_include/bt_target.h"
35 #include "osi/include/allocator.h"
36 #include "stack/btm/btm_int_types.h"
37 #include "stack/btm/btm_sco.h"
38 #include "stack/btm/btm_sec.h"
39 #include "stack/include/acl_api.h"
40 #include "stack/include/ble_hci_link_interface.h"
41 #include "stack/include/bt_hdr.h"
42 #include "stack/include/bt_types.h"
43 #include "stack/include/btm_status.h"
44 #include "stack/include/hci_error_code.h"
45 #include "stack/include/l2cap_acl_interface.h"
46 #include "stack/include/l2cap_controller_interface.h"
47 #include "stack/include/l2cap_hci_link_interface.h"
48 #include "stack/include/l2cap_security_interface.h"
49 #include "stack/l2cap/l2c_int.h"
50 #include "types/bt_transport.h"
51 #include "types/raw_address.h"
52
53 using namespace bluetooth;
54
55 extern tBTM_CB btm_cb;
56
57 static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, tL2C_TX_COMPLETE_CB_INFO* p_cbi);
58 static BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi);
59
l2c_link_hci_conn_comp(tHCI_STATUS status,uint16_t handle,const RawAddress & p_bda)60 void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, const RawAddress& p_bda) {
61 tL2C_CCB* p_ccb;
62
63 /* Save the parameters */
64 tL2C_CONN_INFO ci = {
65 .bd_addr = p_bda,
66 .hci_status = status,
67 .psm{},
68 .l2cap_result{},
69 .l2cap_status{},
70 .remote_cid{},
71 .lcids{},
72 .peer_mtu{},
73 };
74
75 /* See if we have a link control block for the remote device */
76 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(ci.bd_addr, BT_TRANSPORT_BR_EDR);
77 if (p_lcb == nullptr) {
78 /* If we don't have one, allocate one */
79 p_lcb = l2cu_allocate_lcb(ci.bd_addr, false, BT_TRANSPORT_BR_EDR);
80 if (p_lcb == nullptr) {
81 log::warn("Failed to allocate an LCB");
82 return;
83 }
84 log::debug("Allocated l2cap control block for new connection state:{}",
85 link_state_text(p_lcb->link_state));
86 p_lcb->link_state = LST_CONNECTING;
87 }
88
89 if ((p_lcb->link_state == LST_CONNECTED) && (status == HCI_ERR_CONNECTION_EXISTS)) {
90 log::warn("Connection already exists handle:0x{:04x}", handle);
91 return;
92 } else if (p_lcb->link_state != LST_CONNECTING) {
93 log::error(
94 "Link received unexpected connection complete state:{} status:{} "
95 "handle:0x{:04x}",
96 link_state_text(p_lcb->link_state), hci_error_code_text(status), p_lcb->Handle());
97 if (status != HCI_SUCCESS) {
98 log::error("Disconnecting...");
99 l2c_link_hci_disc_comp(p_lcb->Handle(), status);
100 }
101 return;
102 }
103
104 /* Save the handle */
105 l2cu_set_lcb_handle(*p_lcb, handle);
106
107 if (ci.hci_status == HCI_SUCCESS) {
108 /* Connected OK. Change state to connected */
109 p_lcb->link_state = LST_CONNECTED;
110
111 /* Get the peer information if the l2cap flow-control/rtrans is supported */
112 l2cu_send_peer_info_req(p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE);
113
114 if (p_lcb->IsBonding()) {
115 log::debug("Link is dedicated bonding handle:0x{:04x}", p_lcb->Handle());
116 if (l2cu_start_post_bond_timer(handle)) {
117 return;
118 }
119 }
120
121 alarm_cancel(p_lcb->l2c_lcb_timer);
122
123 /* For all channels, send the event through their FSMs */
124 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
125 l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM, &ci);
126 }
127
128 if (!p_lcb->ccb_queue.p_first_ccb) {
129 uint64_t timeout_ms = L2CAP_LINK_STARTUP_TOUT * 1000;
130 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, p_lcb);
131 }
132 } else if ((ci.hci_status == HCI_ERR_MAX_NUM_OF_CONNECTIONS) && l2cu_lcb_disconnecting()) {
133 /* Max number of acl connections. */
134 /* If there's an lcb disconnecting set this one to holding */
135 log::warn("Delaying connection as reached max number of links:{}",
136 HCI_ERR_MAX_NUM_OF_CONNECTIONS);
137 p_lcb->link_state = LST_CONNECT_HOLDING;
138 p_lcb->InvalidateHandle();
139 } else {
140 /* Just in case app decides to try again in the callback context */
141 p_lcb->link_state = LST_DISCONNECTING;
142
143 /* Connection failed. For all channels, send the event through */
144 /* their FSMs. The CCBs should remove themselves from the LCB */
145 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
146 tL2C_CCB* pn = p_ccb->p_next_ccb;
147
148 l2c_csm_execute(p_ccb, L2CEVT_LP_CONNECT_CFM_NEG, &ci);
149
150 p_ccb = pn;
151 }
152
153 log::info("Disconnecting link handle:0x{:04x} status:{}", p_lcb->Handle(),
154 hci_error_code_text(status));
155 p_lcb->SetDisconnectReason(status);
156 /* Release the LCB */
157 if (p_lcb->ccb_queue.p_first_ccb == NULL) {
158 l2cu_release_lcb(p_lcb);
159 } else /* there are any CCBs remaining */
160 {
161 if (ci.hci_status == HCI_ERR_CONNECTION_EXISTS) {
162 /* we are in collision situation, wait for connecttion request from
163 * controller */
164 p_lcb->link_state = LST_CONNECTING;
165 } else {
166 l2cu_create_conn_br_edr(p_lcb);
167 }
168 }
169 }
170 }
171
172 /*******************************************************************************
173 *
174 * Function l2c_link_sec_comp
175 *
176 * Description This function is called when required security procedures
177 * are completed.
178 *
179 * Returns void
180 *
181 ******************************************************************************/
l2c_link_sec_comp(RawAddress p_bda,tBT_TRANSPORT transport,void * p_ref_data,tBTM_STATUS btm_status)182 void l2c_link_sec_comp(RawAddress p_bda, tBT_TRANSPORT transport, void* p_ref_data,
183 tBTM_STATUS btm_status) {
184 tL2C_CCB* p_ccb;
185 tL2C_CCB* p_next_ccb;
186
187 log::debug("btm_status={}, BD_ADDR={}, transport={}", btm_status_text(btm_status), p_bda,
188 bt_transport_text(transport));
189
190 if (btm_status == tBTM_STATUS::BTM_SUCCESS_NO_SECURITY) {
191 btm_status = tBTM_STATUS::BTM_SUCCESS;
192 }
193
194 /* Save the parameters */
195 tL2C_CONN_INFO ci = {
196 .bd_addr = p_bda,
197 .hci_status = static_cast<tHCI_STATUS>(btm_status),
198 .psm{},
199 .l2cap_result{},
200 .l2cap_status{},
201 .remote_cid{},
202 .lcids{},
203 .peer_mtu{},
204 };
205
206 /* If we don't have one, this is an error */
207 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, transport);
208 if (!p_lcb) {
209 log::warn("L2CAP got sec_comp for unknown BD_ADDR");
210 return;
211 }
212
213 if (!p_ref_data) {
214 log::warn("Argument p_ref_data is NULL");
215 return;
216 }
217
218 /* Match p_ccb with p_ref_data returned by sec manager */
219 p_ccb = (tL2C_CCB*)p_ref_data;
220
221 if (p_lcb != p_ccb->p_lcb) {
222 log::warn("p_ref_data doesn't match with sec manager record");
223 return;
224 }
225
226 switch (btm_status) {
227 case tBTM_STATUS::BTM_SUCCESS:
228 l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP, &ci);
229 break;
230
231 case tBTM_STATUS::BTM_DELAY_CHECK:
232 /* start a timer - encryption change not received before L2CAP connect
233 * req */
234 alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
235 l2c_ccb_timer_timeout, p_ccb);
236 return;
237
238 default:
239 l2c_csm_execute(p_ccb, L2CEVT_SEC_COMP_NEG, &ci);
240 break;
241 }
242 }
243
244 /*******************************************************************************
245 **
246 ** Function l2c_link_iot_store_disc_reason
247 **
248 ** Description iot store disconnection reason to local conf file
249 **
250 ** Returns void
251 **
252 *******************************************************************************/
l2c_link_iot_store_disc_reason(RawAddress & bda,uint8_t reason)253 static void l2c_link_iot_store_disc_reason(RawAddress& bda, uint8_t reason) {
254 const char* disc_keys[] = {
255 IOT_CONF_KEY_GAP_DISC_CONNTIMEOUT_COUNT,
256 };
257 const uint8_t disc_reasons[] = {
258 HCI_ERR_CONNECTION_TOUT,
259 };
260 int i = 0;
261 int num = sizeof(disc_keys) / sizeof(disc_keys[0]);
262
263 if (reason == (uint8_t)-1) {
264 return;
265 }
266
267 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(bda, IOT_CONF_KEY_GAP_DISC_COUNT);
268 for (i = 0; i < num; i++) {
269 if (disc_reasons[i] == reason) {
270 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(bda, disc_keys[i]);
271 break;
272 }
273 }
274 }
275
276 /*******************************************************************************
277 *
278 * Function l2c_link_hci_disc_comp
279 *
280 * Description This function is called when an HCI Disconnect Complete
281 * event is received.
282 *
283 * Returns true if the link is known about, else false
284 *
285 ******************************************************************************/
l2c_link_hci_disc_comp(uint16_t handle,tHCI_REASON reason)286 bool l2c_link_hci_disc_comp(uint16_t handle, tHCI_REASON reason) {
287 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
288 if (p_lcb == nullptr) {
289 log::error("No LCB found for handle:0x{:04x}", handle);
290
291 p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING);
292 if (p_lcb != nullptr) {
293 log::info("Resuming pending ACL request {}", p_lcb->remote_bd_addr);
294 l2cu_create_conn_br_edr(p_lcb);
295 }
296 return false;
297 }
298
299 bool lcb_is_free = true;
300 l2c_link_iot_store_disc_reason(p_lcb->remote_bd_addr, reason);
301 p_lcb->SetDisconnectReason(reason);
302
303 /* Just in case app decides to try again in the callback context */
304 p_lcb->link_state = LST_DISCONNECTING;
305
306 /* Check for BLE and handle that differently */
307 if (p_lcb->transport == BT_TRANSPORT_LE) {
308 btm_ble_decrement_link_topology_mask(p_lcb->LinkRole());
309 }
310
311 /* Link is disconnected. For all channels, send the event through their FSMs. The CCBs should
312 * remove themselves from the LCB */
313 for (tL2C_CCB* p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
314 tL2C_CCB* pn = p_ccb->p_next_ccb;
315
316 /* Keep connect pending control block (if exists).
317 * Possible race condition when a reconnect occurs on the channel during a disconnect of link.
318 * This ccb will be automatically retried after link disconnect arrives */
319 if (p_ccb != p_lcb->p_pending_ccb) {
320 l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, &reason);
321 }
322 p_ccb = pn;
323 }
324
325 if (p_lcb->transport == BT_TRANSPORT_BR_EDR) {
326 /* Tell SCO management to drop any SCOs on this ACL */
327 btm_sco_acl_removed(&p_lcb->remote_bd_addr);
328 }
329
330 /* If waiting for disconnect and reconnect is pending start the reconnect now race condition where
331 * layer above issued connect request on link that was disconnecting */
332 if (p_lcb->ccb_queue.p_first_ccb != nullptr || p_lcb->p_pending_ccb) {
333 log::debug("l2c_link_hci_disc_comp: Restarting pending ACL request");
334 /* Release any held buffers */
335 while (!list_is_empty(p_lcb->link_xmit_data_q)) {
336 BT_HDR* p_buf = static_cast<BT_HDR*>(list_front(p_lcb->link_xmit_data_q));
337 list_remove(p_lcb->link_xmit_data_q, p_buf);
338 osi_free(p_buf);
339 }
340 /* for LE link, always drop and re-open to ensure to get LE remote feature
341 */
342 if (p_lcb->transport == BT_TRANSPORT_LE) {
343 btm_acl_removed(handle);
344 if (com::android::bluetooth::flags::invalidate_hci_handle_on_acl_removal()) {
345 p_lcb->InvalidateHandle();
346 }
347 } else {
348 /* If we are going to re-use the LCB without dropping it, release all
349 fixed channels
350 here */
351 int xx;
352 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
353 if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) {
354 l2cu_release_ccb(p_lcb->p_fixed_ccbs[xx]);
355 p_lcb->p_fixed_ccbs[xx] = nullptr;
356 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
357 p_lcb->remote_bd_addr, false,
358 p_lcb->DisconnectReason(), p_lcb->transport);
359 }
360 }
361 /* Cleanup connection state to avoid race conditions because
362 * l2cu_release_lcb won't be invoked to cleanup */
363 btm_acl_removed(p_lcb->Handle());
364 p_lcb->InvalidateHandle();
365 }
366 if (p_lcb->transport == BT_TRANSPORT_LE) {
367 if (l2cu_create_conn_le(p_lcb)) {
368 lcb_is_free = false; /* still using this lcb */
369 }
370 } else {
371 l2cu_create_conn_br_edr(p_lcb);
372 lcb_is_free = false; /* still using this lcb */
373 }
374 }
375 p_lcb->p_pending_ccb = nullptr;
376
377 /* Release the LCB */
378 if (lcb_is_free) {
379 l2cu_release_lcb(p_lcb);
380
381 /* Now that we have a free acl connection, see if any lcbs are pending */
382 p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING);
383 if (p_lcb != nullptr) {
384 log::info("Resuming pending ACL request {}", p_lcb->remote_bd_addr);
385 l2cu_create_conn_br_edr(p_lcb);
386 }
387 }
388
389 return true;
390 }
391
392 /*******************************************************************************
393 *
394 * Function l2c_link_timeout
395 *
396 * Description This function is called when a link timer expires
397 *
398 * Returns void
399 *
400 ******************************************************************************/
l2c_link_timeout(tL2C_LCB * p_lcb)401 void l2c_link_timeout(tL2C_LCB* p_lcb) {
402 tL2C_CCB* p_ccb;
403 tBTM_STATUS rc;
404
405 log::debug("L2CAP - l2c_link_timeout() link state:{} is_bonding:{}",
406 link_state_text(p_lcb->link_state), p_lcb->IsBonding());
407
408 /* If link was connecting or disconnecting, clear all channels and drop the
409 * LCB */
410 if ((p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH) || (p_lcb->link_state == LST_CONNECTING) ||
411 (p_lcb->link_state == LST_CONNECT_HOLDING) || (p_lcb->link_state == LST_DISCONNECTING)) {
412 p_lcb->p_pending_ccb = NULL;
413
414 /* For all channels, send a disconnect indication event through */
415 /* their FSMs. The CCBs should remove themselves from the LCB */
416 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;) {
417 tL2C_CCB* pn = p_ccb->p_next_ccb;
418
419 l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL);
420
421 p_ccb = pn;
422 }
423
424 /* Release the LCB */
425 l2cu_release_lcb(p_lcb);
426 }
427
428 /* If link is connected, check for inactivity timeout */
429 if (p_lcb->link_state == LST_CONNECTED) {
430 /* If no channels in use, drop the link. */
431 if (!p_lcb->ccb_queue.p_first_ccb) {
432 uint64_t timeout_ms;
433 bool start_timeout = true;
434
435 log::warn("TODO: Remove this callback into bcm_sec_disconnect");
436 rc = btm_sec_disconnect(p_lcb->Handle(), HCI_ERR_PEER_USER,
437 "stack::l2cap::l2c_link::l2c_link_timeout All channels closed");
438
439 if (rc == tBTM_STATUS::BTM_CMD_STORED) {
440 /* Security Manager will take care of disconnecting, state will be
441 * updated at that time */
442 start_timeout = false;
443 } else if (rc == tBTM_STATUS::BTM_CMD_STARTED) {
444 p_lcb->link_state = LST_DISCONNECTING;
445 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
446 } else if (rc == tBTM_STATUS::BTM_SUCCESS) {
447 l2cu_process_fixed_disc_cback(p_lcb);
448 /* BTM SEC will make sure that link is release (probably after pairing
449 * is done) */
450 p_lcb->link_state = LST_DISCONNECTING;
451 start_timeout = false;
452 } else if (rc == tBTM_STATUS::BTM_BUSY) {
453 /* BTM is still executing security process. Let lcb stay as connected */
454 start_timeout = false;
455 } else if (p_lcb->IsBonding()) {
456 acl_disconnect_from_handle(p_lcb->Handle(), HCI_ERR_PEER_USER,
457 "stack::l2cap::l2c_link::l2c_link_timeout "
458 "Timer expired while bonding");
459 l2cu_process_fixed_disc_cback(p_lcb);
460 p_lcb->link_state = LST_DISCONNECTING;
461 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
462 } else {
463 /* probably no buffer to send disconnect */
464 timeout_ms = BT_1SEC_TIMEOUT_MS;
465 }
466
467 if (start_timeout) {
468 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, p_lcb);
469 }
470 } else {
471 /* Check in case we were flow controlled */
472 l2c_link_check_send_pkts(p_lcb, 0, NULL);
473 }
474 }
475 }
476
477 /*******************************************************************************
478 *
479 * Function l2c_info_resp_timer_timeout
480 *
481 * Description This function is called when an info request times out
482 *
483 * Returns void
484 *
485 ******************************************************************************/
l2c_info_resp_timer_timeout(void * data)486 void l2c_info_resp_timer_timeout(void* data) {
487 tL2C_LCB* p_lcb = (tL2C_LCB*)data;
488 tL2C_CCB* p_ccb;
489
490 /* If we timed out waiting for info response, just continue using basic if
491 * allowed */
492 if (p_lcb->w4_info_rsp) {
493 /* If waiting for security complete, restart the info response timer */
494 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
495 if ((p_ccb->chnl_state == CST_ORIG_W4_SEC_COMP) ||
496 (p_ccb->chnl_state == CST_TERM_W4_SEC_COMP)) {
497 alarm_set_on_mloop(p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
498 l2c_info_resp_timer_timeout, p_lcb);
499 return;
500 }
501 }
502
503 p_lcb->w4_info_rsp = false;
504
505 /* If link is in process of being brought up */
506 if ((p_lcb->link_state != LST_DISCONNECTED) && (p_lcb->link_state != LST_DISCONNECTING)) {
507 /* Notify active channels that peer info is finished */
508 if (p_lcb->ccb_queue.p_first_ccb) {
509 tL2C_CONN_INFO ci = {
510 .bd_addr = p_lcb->remote_bd_addr,
511 .hci_status = HCI_SUCCESS,
512 .psm{},
513 .l2cap_result{},
514 .l2cap_status{},
515 .remote_cid{},
516 .lcids{},
517 .peer_mtu{},
518 };
519 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
520 l2c_csm_execute(p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
521 }
522 }
523 }
524 }
525 }
526
527 /*******************************************************************************
528 *
529 * Function l2c_link_adjust_allocation
530 *
531 * Description This function is called when a link is created or removed
532 * to calculate the amount of packets each link may send to
533 * the HCI without an ack coming back.
534 *
535 * Currently, this is a simple allocation, dividing the
536 * number of Controller Packets by the number of links. In
537 * the future, QOS configuration should be examined.
538 *
539 * Returns void
540 *
541 ******************************************************************************/
l2c_link_adjust_allocation(void)542 void l2c_link_adjust_allocation(void) {
543 uint16_t qq, yy, qq_remainder;
544 tL2C_LCB* p_lcb;
545 uint16_t hi_quota, low_quota;
546 uint16_t num_lowpri_links = 0;
547 uint16_t num_hipri_links = 0;
548 uint16_t controller_xmit_quota = l2cb.num_lm_acl_bufs;
549 uint16_t high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
550 bool is_share_buffer = (l2cb.num_lm_ble_bufs == L2C_DEF_NUM_BLE_BUF_SHARED) ? true : false;
551
552 /* If no links active, reset buffer quotas and controller buffers */
553 if (l2cb.num_used_lcbs == 0) {
554 l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
555 l2cb.round_robin_quota = l2cb.round_robin_unacked = 0;
556 return;
557 }
558
559 /* First, count the links */
560 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
561 if (p_lcb->in_use && (is_share_buffer || p_lcb->transport != BT_TRANSPORT_LE)) {
562 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
563 num_hipri_links++;
564 } else {
565 num_lowpri_links++;
566 }
567 }
568 }
569
570 /* now adjust high priority link quota */
571 low_quota = num_lowpri_links ? 1 : 0;
572 while ((num_hipri_links * high_pri_link_quota + low_quota) > controller_xmit_quota) {
573 high_pri_link_quota--;
574 }
575
576 /* Work out the xmit quota and buffer quota high and low priorities */
577 hi_quota = num_hipri_links * high_pri_link_quota;
578 low_quota = (hi_quota < controller_xmit_quota) ? controller_xmit_quota - hi_quota : 1;
579
580 /* Work out and save the HCI xmit quota for each low priority link */
581
582 /* If each low priority link cannot have at least one buffer */
583 if (num_lowpri_links > low_quota) {
584 l2cb.round_robin_quota = low_quota;
585 qq = qq_remainder = 1;
586 } else if (num_lowpri_links > 0) {
587 /* If each low priority link can have at least one buffer */
588 l2cb.round_robin_quota = 0;
589 l2cb.round_robin_unacked = 0;
590 qq = low_quota / num_lowpri_links;
591 qq_remainder = low_quota % num_lowpri_links;
592 } else {
593 /* If no low priority link */
594 l2cb.round_robin_quota = 0;
595 l2cb.round_robin_unacked = 0;
596 qq = qq_remainder = 1;
597 }
598
599 log::debug(
600 "l2c_link_adjust_allocation num_hipri: {} num_lowpri: {} low_quota: "
601 "{} round_robin_quota: {} qq: {}",
602 num_hipri_links, num_lowpri_links, low_quota, l2cb.round_robin_quota, qq);
603
604 /* Now, assign the quotas to each link */
605 for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
606 if (p_lcb->in_use && (is_share_buffer || p_lcb->transport != BT_TRANSPORT_LE)) {
607 if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
608 p_lcb->link_xmit_quota = high_pri_link_quota;
609 } else {
610 /* Safety check in case we switched to round-robin with something
611 * outstanding */
612 /* if sent_not_acked is added into round_robin_unacked then don't add it
613 * again */
614 /* l2cap keeps updating sent_not_acked for exiting from round robin */
615 if ((p_lcb->link_xmit_quota > 0) && (qq == 0)) {
616 l2cb.round_robin_unacked += p_lcb->sent_not_acked;
617 }
618
619 p_lcb->link_xmit_quota = qq;
620 if (qq_remainder > 0) {
621 p_lcb->link_xmit_quota++;
622 qq_remainder--;
623 }
624 }
625
626 log::debug("l2c_link_adjust_allocation LCB {} Priority: {} XmitQuota: {}", yy,
627 p_lcb->acl_priority, p_lcb->link_xmit_quota);
628
629 log::debug("SentNotAcked: {} RRUnacked: {}", p_lcb->sent_not_acked,
630 l2cb.round_robin_unacked);
631
632 /* There is a special case where we have readjusted the link quotas and */
633 /* this link may have sent anything but some other link sent packets so */
634 /* so we may need a timer to kick off this link's transmissions. */
635 if (p_lcb->link_xmit_data_q != nullptr) {
636 if ((p_lcb->link_state == LST_CONNECTED) &&
637 !list_is_empty(p_lcb->link_xmit_data_q) &&
638 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
639 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
640 l2c_lcb_timer_timeout, p_lcb);
641 }
642 } else {
643 log::warn("link_xmit_data_q is null");
644 }
645 }
646 }
647 }
648
649 /*******************************************************************************
650 *
651 * Function l2c_link_adjust_chnl_allocation
652 *
653 * Description This function is called to calculate the amount of packets
654 * each non-F&EC channel may have outstanding.
655 *
656 * Currently, this is a simple allocation, dividing the number
657 * of packets allocated to the link by the number of channels.
658 * In the future, QOS configuration should be examined.
659 *
660 * Returns void
661 *
662 ******************************************************************************/
l2c_link_adjust_chnl_allocation(void)663 void l2c_link_adjust_chnl_allocation(void) {
664 /* assign buffer quota to each channel based on its data rate requirement */
665 for (uint8_t xx = 0; xx < MAX_L2CAP_CHANNELS; xx++) {
666 tL2C_CCB* p_ccb = l2cb.ccb_pool + xx;
667
668 if (!p_ccb->in_use) {
669 continue;
670 }
671
672 tL2CAP_CHNL_DATA_RATE data_rate = p_ccb->tx_data_rate + p_ccb->rx_data_rate;
673 p_ccb->buff_quota = L2CAP_CBB_DEFAULT_DATA_RATE_BUFF_QUOTA * data_rate;
674 log::debug(
675 "CID:0x{:04x} FCR Mode:{} Priority:{} TxDataRate:{} RxDataRate:{} "
676 "Quota:{}",
677 p_ccb->local_cid, p_ccb->peer_cfg.fcr.mode, p_ccb->ccb_priority, p_ccb->tx_data_rate,
678 p_ccb->rx_data_rate, p_ccb->buff_quota);
679
680 /* quota may be change so check congestion */
681 l2cu_check_channel_congestion(p_ccb);
682 }
683 }
684
l2c_link_init(const uint16_t acl_buffer_count_classic)685 void l2c_link_init(const uint16_t acl_buffer_count_classic) {
686 l2cb.num_lm_acl_bufs = acl_buffer_count_classic;
687 l2cb.controller_xmit_window = acl_buffer_count_classic;
688 }
689
690 /*******************************************************************************
691 *
692 * Function l2c_link_role_changed
693 *
694 * Description This function is called whan a link's central/peripheral
695 *role change event is received. It simply updates the link control block.
696 *
697 * Returns void
698 *
699 ******************************************************************************/
l2c_link_role_changed(const RawAddress * bd_addr,tHCI_ROLE new_role,tHCI_STATUS hci_status)700 void l2c_link_role_changed(const RawAddress* bd_addr, tHCI_ROLE new_role, tHCI_STATUS hci_status) {
701 /* Make sure not called from HCI Command Status (bd_addr and new_role are
702 * invalid) */
703 if (bd_addr != nullptr) {
704 /* If here came form hci role change event */
705 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(*bd_addr, BT_TRANSPORT_BR_EDR);
706 if (p_lcb) {
707 if (new_role == HCI_ROLE_CENTRAL) {
708 p_lcb->SetLinkRoleAsCentral();
709 } else {
710 p_lcb->SetLinkRoleAsPeripheral();
711 }
712
713 /* Reset high priority link if needed */
714 if (hci_status == HCI_SUCCESS) {
715 l2cu_set_acl_priority(*bd_addr, p_lcb->acl_priority, true);
716 }
717 }
718 }
719
720 /* Check if any LCB was waiting for switch to be completed */
721 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
722 for (uint8_t xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
723 if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTING_WAIT_SWITCH)) {
724 l2cu_create_conn_after_switch(p_lcb);
725 }
726 }
727 }
728
729 /*******************************************************************************
730 *
731 * Function l2c_pin_code_request
732 *
733 * Description This function is called whan a pin-code request is received
734 * on a connection. If there are no channels active yet on the
735 * link, it extends the link first connection timer. Make sure
736 * that inactivity timer is not extended if PIN code happens
737 * to be after last ccb released.
738 *
739 * Returns void
740 *
741 ******************************************************************************/
l2c_pin_code_request(const RawAddress & bd_addr)742 void l2c_pin_code_request(const RawAddress& bd_addr) {
743 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
744
745 if ((p_lcb) && (!p_lcb->ccb_queue.p_first_ccb)) {
746 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_EXT_TIMEOUT_MS,
747 l2c_lcb_timer_timeout, p_lcb);
748 }
749 }
750
751 /*******************************************************************************
752 *
753 * Function l2c_link_check_send_pkts
754 *
755 * Description This function is called to check if it can send packets
756 * to the Host Controller. It may be passed the address of
757 * a packet to send.
758 *
759 * Returns void
760 *
761 ******************************************************************************/
l2c_link_check_send_pkts(tL2C_LCB * p_lcb,uint16_t local_cid,BT_HDR * p_buf)762 void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, uint16_t local_cid, BT_HDR* p_buf) {
763 bool single_write = false;
764
765 /* Save the channel ID for faster counting */
766 if (p_buf) {
767 p_buf->event = local_cid;
768 if (local_cid != 0) {
769 single_write = true;
770 }
771
772 p_buf->layer_specific = 0;
773 if (p_lcb->link_xmit_data_q != NULL) {
774 list_append(p_lcb->link_xmit_data_q, p_buf);
775 } else {
776 log::warn("Unable to queue packet as L2cap module transmit data queue is null");
777 }
778
779 if (p_lcb->link_xmit_quota == 0) {
780 if (p_lcb->transport == BT_TRANSPORT_LE) {
781 l2cb.ble_check_round_robin = true;
782 } else {
783 l2cb.check_round_robin = true;
784 }
785 }
786 }
787
788 /* If this is called from uncongested callback context break recursive
789 *calling.
790 ** This LCB will be served when receiving number of completed packet event.
791 */
792 if (l2cb.is_cong_cback_context) {
793 log::warn("skipping, is_cong_cback_context=true");
794 return;
795 }
796
797 /* If we are in a scenario where there are not enough buffers for each link to
798 ** have at least 1, then do a round-robin for all the LCBs
799 */
800 if ((p_lcb == NULL) || (p_lcb->link_xmit_quota == 0)) {
801 log::debug("Round robin");
802 if (p_lcb == NULL) {
803 p_lcb = l2cb.lcb_pool;
804 } else if (!single_write) {
805 p_lcb++;
806 }
807
808 /* Loop through, starting at the next */
809 for (int xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
810 /* Check for wraparound */
811 if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS]) {
812 p_lcb = &l2cb.lcb_pool[0];
813 }
814
815 /* If controller window is full, nothing to do */
816 if (((l2cb.controller_xmit_window == 0 ||
817 (l2cb.round_robin_unacked >= l2cb.round_robin_quota)) &&
818 (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
819 (p_lcb->transport == BT_TRANSPORT_LE &&
820 (l2cb.ble_round_robin_unacked >= l2cb.ble_round_robin_quota ||
821 l2cb.controller_le_xmit_window == 0))) {
822 log::debug("Skipping lcb {} due to controller window full", xx);
823 continue;
824 }
825
826 if (!p_lcb->in_use || p_lcb->link_state != LST_CONNECTED || p_lcb->link_xmit_quota != 0) {
827 log::debug("Skipping lcb {} due to quota", xx);
828 continue;
829 }
830
831 /* See if we can send anything from the Link Queue */
832 if (p_lcb->link_xmit_data_q != NULL && !list_is_empty(p_lcb->link_xmit_data_q)) {
833 log::verbose("Sending to lower layer");
834 p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q);
835 list_remove(p_lcb->link_xmit_data_q, p_buf);
836 l2c_link_send_to_lower(p_lcb, p_buf, NULL);
837 } else if (single_write) {
838 /* If only doing one write, break out */
839 log::debug("single_write is true, skipping");
840 break;
841 } else {
842 /* If nothing on the link queue, check the channel queue */
843 tL2C_TX_COMPLETE_CB_INFO cbi = {};
844 log::debug("Check next buffer");
845 p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi);
846 if (p_buf != NULL) {
847 log::debug("Sending next buffer");
848 l2c_link_send_to_lower(p_lcb, p_buf, &cbi);
849 }
850 }
851 }
852
853 /* If we finished without using up our quota, no need for a safety check */
854 if ((l2cb.controller_xmit_window > 0) && (l2cb.round_robin_unacked < l2cb.round_robin_quota) &&
855 (p_lcb->transport == BT_TRANSPORT_BR_EDR)) {
856 l2cb.check_round_robin = false;
857 }
858
859 if ((l2cb.controller_le_xmit_window > 0) &&
860 (l2cb.ble_round_robin_unacked < l2cb.ble_round_robin_quota) &&
861 (p_lcb->transport == BT_TRANSPORT_LE)) {
862 l2cb.ble_check_round_robin = false;
863 }
864 } else /* if this is not round-robin service */
865 {
866 /* link_state or power mode not ready, can't send anything else */
867 if (p_lcb->link_state != LST_CONNECTED) {
868 log::warn("Can't send, link state: {} not LST_CONNECTED or power mode BTM_PM_STS_PENDING",
869 p_lcb->link_state);
870 return;
871 }
872 log::verbose(
873 "Direct send, transport={}, xmit_window={}, le_xmit_window={}, "
874 "sent_not_acked={}, link_xmit_quota={}",
875 p_lcb->transport, l2cb.controller_xmit_window, l2cb.controller_le_xmit_window,
876 p_lcb->sent_not_acked, p_lcb->link_xmit_quota);
877
878 /* See if we can send anything from the link queue */
879 while (((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
880 (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE))) &&
881 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
882 if ((p_lcb->link_xmit_data_q == NULL) || list_is_empty(p_lcb->link_xmit_data_q)) {
883 log::verbose("No transmit data, skipping");
884 break;
885 }
886 log::verbose("Sending to lower layer");
887 p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q);
888 list_remove(p_lcb->link_xmit_data_q, p_buf);
889 l2c_link_send_to_lower(p_lcb, p_buf, NULL);
890 }
891
892 if (!single_write) {
893 /* See if we can send anything for any channel */
894 log::verbose("Trying to send other data when single_write is false");
895 while (((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
896 (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE))) &&
897 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
898 tL2C_TX_COMPLETE_CB_INFO cbi = {};
899 p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi);
900 if (p_buf == NULL) {
901 log::verbose("No next buffer, skipping");
902 break;
903 }
904 log::verbose("Sending to lower layer");
905 l2c_link_send_to_lower(p_lcb, p_buf, &cbi);
906 }
907 }
908
909 /* There is a special case where we have readjusted the link quotas and */
910 /* this link may have sent anything but some other link sent packets so */
911 /* so we may need a timer to kick off this link's transmissions. */
912 if ((p_lcb->link_xmit_data_q != NULL) && (!list_is_empty(p_lcb->link_xmit_data_q)) &&
913 (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
914 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
915 l2c_lcb_timer_timeout, p_lcb);
916 }
917 }
918 }
919
l2c_OnHciModeChangeSendPendingPackets(RawAddress remote)920 void l2c_OnHciModeChangeSendPendingPackets(RawAddress remote) {
921 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(remote, BT_TRANSPORT_BR_EDR);
922 if (p_lcb != NULL) {
923 /* There might be any pending packets due to SNIFF or PENDING state */
924 /* Trigger L2C to start transmission of the pending packets. */
925 log::verbose("btm mode change to active; check l2c_link for outgoing packets");
926 l2c_link_check_send_pkts(p_lcb, 0, NULL);
927 }
928 }
929
930 /*******************************************************************************
931 *
932 * Function l2c_link_send_to_lower
933 *
934 * Description This function queues the buffer for HCI transmission
935 *
936 ******************************************************************************/
l2c_link_send_to_lower_br_edr(tL2C_LCB * p_lcb,BT_HDR * p_buf)937 static void l2c_link_send_to_lower_br_edr(tL2C_LCB* p_lcb, BT_HDR* p_buf) {
938 const uint16_t link_xmit_quota = p_lcb->link_xmit_quota;
939
940 if (link_xmit_quota == 0) {
941 l2cb.round_robin_unacked++;
942 }
943 p_lcb->sent_not_acked++;
944 p_buf->layer_specific = 0;
945 l2cb.controller_xmit_window--;
946
947 acl_send_data_packet_br_edr(p_lcb->remote_bd_addr, p_buf);
948 log::verbose("TotalWin={},Hndl=0x{:x},Quota={},Unack={},RRQuota={},RRUnack={}",
949 l2cb.controller_xmit_window, p_lcb->Handle(), p_lcb->link_xmit_quota,
950 p_lcb->sent_not_acked, l2cb.round_robin_quota, l2cb.round_robin_unacked);
951 }
952
l2c_link_send_to_lower_ble(tL2C_LCB * p_lcb,BT_HDR * p_buf)953 static void l2c_link_send_to_lower_ble(tL2C_LCB* p_lcb, BT_HDR* p_buf) {
954 const uint16_t link_xmit_quota = p_lcb->link_xmit_quota;
955
956 if (link_xmit_quota == 0) {
957 l2cb.ble_round_robin_unacked++;
958 }
959 p_lcb->sent_not_acked++;
960 p_buf->layer_specific = 0;
961 l2cb.controller_le_xmit_window--;
962
963 acl_send_data_packet_ble(p_lcb->remote_bd_addr, p_buf);
964 log::debug("TotalWin={},Hndl=0x{:x},Quota={},Unack={},RRQuota={},RRUnack={}",
965 l2cb.controller_le_xmit_window, p_lcb->Handle(), p_lcb->link_xmit_quota,
966 p_lcb->sent_not_acked, l2cb.ble_round_robin_quota, l2cb.ble_round_robin_unacked);
967 }
968
l2c_link_send_to_lower(tL2C_LCB * p_lcb,BT_HDR * p_buf,tL2C_TX_COMPLETE_CB_INFO * p_cbi)969 static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
970 tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
971 if (p_lcb->transport == BT_TRANSPORT_BR_EDR) {
972 l2c_link_send_to_lower_br_edr(p_lcb, p_buf);
973 } else {
974 l2c_link_send_to_lower_ble(p_lcb, p_buf);
975 }
976 if (p_cbi) {
977 l2cu_tx_complete(p_cbi);
978 }
979
980 if (p_lcb->suspended.empty()) {
981 return;
982 }
983
984 auto it = p_lcb->suspended.begin();
985 while (it != p_lcb->suspended.end()) {
986 bool erase = false;
987 uint16_t fixed_cid = *it;
988
989 if (fixed_cid < L2CAP_FIRST_FIXED_CHNL || fixed_cid > L2CAP_LAST_FIXED_CHNL) {
990 log::warn("Unknown channel was marked for removal, CID: 0x{:04x} BDA: {}", fixed_cid,
991 p_lcb->remote_bd_addr);
992 erase = true;
993 } else {
994 auto p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
995 if (p_ccb == nullptr || !p_ccb->in_use) {
996 log::warn(
997 "Fixed channel control block not active but was marked for removal, CID: 0x{:04x} "
998 "BDA: {}",
999 fixed_cid, p_lcb->remote_bd_addr);
1000 erase = true;
1001 } else if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1002 if (L2CA_RemoveFixedChnl(fixed_cid, p_lcb->remote_bd_addr)) {
1003 log::info("Finally removed CID: 0x{:04x} BDA: {}", fixed_cid, p_lcb->remote_bd_addr);
1004 } else {
1005 log::error("Failed to remove CID: 0x{:04x} BDA: {}", fixed_cid, p_lcb->remote_bd_addr);
1006 }
1007 erase = true;
1008 }
1009 }
1010
1011 if (erase) {
1012 it = p_lcb->suspended.erase(it);
1013 } else {
1014 it++;
1015 }
1016 }
1017 }
1018
l2c_packets_completed(uint16_t handle,uint16_t num_sent)1019 void l2c_packets_completed(uint16_t handle, uint16_t num_sent) {
1020 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1021 if (p_lcb == nullptr) {
1022 return;
1023 }
1024 p_lcb->update_outstanding_packets(num_sent);
1025
1026 switch (p_lcb->transport) {
1027 case BT_TRANSPORT_BR_EDR:
1028 l2cb.controller_xmit_window += num_sent;
1029 if (p_lcb->is_round_robin_scheduling()) {
1030 l2cb.update_outstanding_classic_packets(num_sent);
1031 }
1032 break;
1033 case BT_TRANSPORT_LE:
1034 l2cb.controller_le_xmit_window += num_sent;
1035 if (p_lcb->is_round_robin_scheduling()) {
1036 l2cb.update_outstanding_le_packets(num_sent);
1037 }
1038 break;
1039 default:
1040 log::error("Unknown transport received:{}", p_lcb->transport);
1041 return;
1042 }
1043
1044 l2c_link_check_send_pkts(p_lcb, 0, NULL);
1045
1046 if (p_lcb->is_high_priority()) {
1047 switch (p_lcb->transport) {
1048 case BT_TRANSPORT_LE:
1049 if (l2cb.ble_check_round_robin && l2cb.is_ble_round_robin_quota_available()) {
1050 l2c_link_check_send_pkts(NULL, 0, NULL);
1051 }
1052 break;
1053 case BT_TRANSPORT_BR_EDR:
1054 if (l2cb.check_round_robin && l2cb.is_classic_round_robin_quota_available()) {
1055 l2c_link_check_send_pkts(NULL, 0, NULL);
1056 }
1057 break;
1058 default:
1059 break;
1060 }
1061 }
1062 }
1063
l2cu_ConnectAclForSecurity(const RawAddress & bd_addr)1064 tBTM_STATUS l2cu_ConnectAclForSecurity(const RawAddress& bd_addr) {
1065 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
1066 if (p_lcb && (p_lcb->link_state == LST_CONNECTED || p_lcb->link_state == LST_CONNECTING)) {
1067 log::warn("Connection already exists");
1068 return tBTM_STATUS::BTM_CMD_STARTED;
1069 }
1070
1071 /* Make sure an L2cap link control block is available */
1072 if (!p_lcb && (p_lcb = l2cu_allocate_lcb(bd_addr, true, BT_TRANSPORT_BR_EDR)) == NULL) {
1073 log::warn("failed allocate LCB for {}", bd_addr);
1074 return tBTM_STATUS::BTM_NO_RESOURCES;
1075 }
1076
1077 l2cu_create_conn_br_edr(p_lcb);
1078 return tBTM_STATUS::BTM_SUCCESS;
1079 }
1080
l2cble_update_sec_act(const RawAddress & bd_addr,uint16_t sec_act)1081 void l2cble_update_sec_act(const RawAddress& bd_addr, uint16_t sec_act) {
1082 tL2C_LCB* lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
1083 lcb->sec_act = sec_act;
1084 }
1085
1086 /******************************************************************************
1087 *
1088 * Function l2cu_get_next_channel_in_rr
1089 *
1090 * Description get the next channel to send on a link. It also adjusts the
1091 * CCB queue to do a basic priority and round-robin scheduling.
1092 *
1093 * Returns pointer to CCB or NULL
1094 *
1095 ******************************************************************************/
l2cu_get_next_channel_in_rr(tL2C_LCB * p_lcb)1096 static tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) {
1097 tL2C_CCB* p_serve_ccb = NULL;
1098 tL2C_CCB* p_ccb;
1099
1100 int i, j;
1101
1102 /* scan all of priority until finding a channel to serve */
1103 for (i = 0; (i < L2CAP_NUM_CHNL_PRIORITY) && (!p_serve_ccb); i++) {
1104 /* scan all channel within serving priority group until finding a channel to
1105 * serve */
1106 for (j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb) && (!p_serve_ccb); j++) {
1107 /* scaning from next serving channel */
1108 p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
1109
1110 if (!p_ccb) {
1111 log::error("p_serve_ccb is NULL, rr_pri={}", p_lcb->rr_pri);
1112 return NULL;
1113 }
1114
1115 /* store the next serving channel */
1116 /* this channel is the last channel of its priority group */
1117 if ((p_ccb->p_next_ccb == NULL) || (p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority)) {
1118 /* next serving channel is set to the first channel in the group */
1119 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb;
1120 } else {
1121 /* next serving channel is set to the next channel in the group */
1122 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
1123 }
1124
1125 if (p_ccb->chnl_state != CST_OPEN) {
1126 continue;
1127 }
1128
1129 if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
1130 log::debug("Connection oriented channel");
1131 if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1132 continue;
1133 }
1134
1135 } else {
1136 /* eL2CAP option in use */
1137 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
1138 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) {
1139 continue;
1140 }
1141
1142 if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
1143 if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1144 continue;
1145 }
1146
1147 /* If in eRTM mode, check for window closure */
1148 if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
1149 (l2c_fcr_is_flow_controlled(p_ccb))) {
1150 continue;
1151 }
1152 }
1153 } else {
1154 if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1155 continue;
1156 }
1157 }
1158 }
1159
1160 /* found a channel to serve */
1161 p_serve_ccb = p_ccb;
1162 /* decrease quota of its priority group */
1163 p_lcb->rr_serv[p_lcb->rr_pri].quota--;
1164 }
1165
1166 /* if there is no more quota of the priority group or no channel to have
1167 * data to send */
1168 if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0) || (!p_serve_ccb)) {
1169 /* serve next priority group */
1170 p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
1171 /* initialize its quota */
1172 p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
1173 }
1174 }
1175
1176 if (p_serve_ccb) {
1177 log::verbose("RR service pri={}, quota={}, lcid=0x{:04x}", p_serve_ccb->ccb_priority,
1178 p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota, p_serve_ccb->local_cid);
1179 }
1180
1181 return p_serve_ccb;
1182 }
1183
1184 /******************************************************************************
1185 *
1186 * Function l2cu_get_next_buffer_to_send
1187 *
1188 * Description get the next buffer to send on a link. It also adjusts the
1189 * CCB queue to do a basic priority and round-robin scheduling.
1190 *
1191 * Returns pointer to buffer or NULL
1192 *
1193 ******************************************************************************/
l2cu_get_next_buffer_to_send(tL2C_LCB * p_lcb,tL2C_TX_COMPLETE_CB_INFO * p_cbi)1194 static BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
1195 tL2C_CCB* p_ccb;
1196 BT_HDR* p_buf;
1197
1198 /* Highest priority are fixed channels */
1199 int xx;
1200
1201 p_cbi->cb = NULL;
1202
1203 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
1204 p_ccb = p_lcb->p_fixed_ccbs[xx];
1205 if (p_ccb == NULL) {
1206 continue;
1207 }
1208
1209 /* eL2CAP option in use */
1210 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
1211 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) {
1212 continue;
1213 }
1214
1215 /* No more checks needed if sending from the reatransmit queue */
1216 if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
1217 if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1218 continue;
1219 }
1220
1221 /* If in eRTM mode, check for window closure */
1222 if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
1223 (l2c_fcr_is_flow_controlled(p_ccb))) {
1224 continue;
1225 }
1226 }
1227
1228 p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0);
1229 if (p_buf != NULL) {
1230 l2cu_check_channel_congestion(p_ccb);
1231 l2cu_set_acl_hci_header(p_buf, p_ccb);
1232 return p_buf;
1233 }
1234 } else {
1235 if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
1236 p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
1237 if (NULL == p_buf) {
1238 log::error("No data to be sent");
1239 return NULL;
1240 }
1241
1242 /* Prepare callback info for TX completion */
1243 p_cbi->cb = l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb;
1244 p_cbi->local_cid = p_ccb->local_cid;
1245 p_cbi->num_sdu = 1;
1246
1247 l2cu_check_channel_congestion(p_ccb);
1248 l2cu_set_acl_hci_header(p_buf, p_ccb);
1249 return p_buf;
1250 }
1251 }
1252 }
1253
1254 /* get next serving channel in round-robin */
1255 p_ccb = l2cu_get_next_channel_in_rr(p_lcb);
1256
1257 /* Return if no buffer */
1258 if (p_ccb == NULL) {
1259 return NULL;
1260 }
1261
1262 if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
1263 /* Check credits */
1264 if (p_ccb->peer_conn_cfg.credits == 0) {
1265 log::debug("No credits to send packets");
1266 return NULL;
1267 }
1268
1269 bool last_piece_of_sdu = false;
1270 p_buf = l2c_lcc_get_next_xmit_sdu_seg(p_ccb, &last_piece_of_sdu);
1271 p_ccb->peer_conn_cfg.credits--;
1272
1273 if (last_piece_of_sdu) {
1274 // TODO: send callback up the stack. Investigate setting p_cbi->cb to
1275 // notify after controller ack send.
1276 }
1277
1278 } else {
1279 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
1280 p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0);
1281 if (p_buf == NULL) {
1282 return NULL;
1283 }
1284 } else {
1285 p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
1286 if (NULL == p_buf) {
1287 log::error("#2: No data to be sent");
1288 return NULL;
1289 }
1290 }
1291 }
1292
1293 if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_TxComplete_Cb &&
1294 (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE)) {
1295 (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
1296 }
1297
1298 l2cu_check_channel_congestion(p_ccb);
1299
1300 l2cu_set_acl_hci_header(p_buf, p_ccb);
1301
1302 return p_buf;
1303 }
1304