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 L2CAP utility functions
22 *
23 ******************************************************************************/
24 #define LOG_TAG "l2c_utils"
25
26 #include <bluetooth/log.h>
27 #include <com_android_bluetooth_flags.h>
28 #include <string.h>
29
30 #include <algorithm>
31
32 #include "hal/snoop_logger.h"
33 #include "hci/controller_interface.h"
34 #include "internal_include/bt_target.h"
35 #include "main/shim/acl_api.h"
36 #include "main/shim/entry.h"
37 #include "osi/include/allocator.h"
38 #include "stack/btm/btm_sec.h"
39 #include "stack/include/acl_api.h"
40 #include "stack/include/bt_hdr.h"
41 #include "stack/include/bt_types.h"
42 #include "stack/include/btm_client_interface.h"
43 #include "stack/include/btm_status.h"
44 #include "stack/include/hci_error_code.h"
45 #include "stack/include/hcidefs.h"
46 #include "stack/include/l2cap_acl_interface.h"
47 #include "stack/include/l2cap_controller_interface.h"
48 #include "stack/include/l2cap_hci_link_interface.h"
49 #include "stack/include/l2cap_interface.h"
50 #include "stack/include/l2cap_security_interface.h"
51 #include "stack/include/l2cdefs.h"
52 #include "stack/l2cap/l2c_int.h"
53 #include "types/raw_address.h"
54
55 using namespace bluetooth;
56
57 /* The offset in a buffer that L2CAP will use when building commands.
58 */
59 #define L2CAP_SEND_CMD_OFFSET 0
60
61 /*******************************************************************************
62 *
63 * Function l2cu_allocate_lcb
64 *
65 * Description Look for an unused LCB
66 *
67 * Returns LCB address or NULL if none found
68 *
69 ******************************************************************************/
l2cu_allocate_lcb(const RawAddress & p_bd_addr,bool is_bonding,tBT_TRANSPORT transport)70 tL2C_LCB* l2cu_allocate_lcb(const RawAddress& p_bd_addr, bool is_bonding, tBT_TRANSPORT transport) {
71 int xx;
72 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
73
74 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
75 if (!p_lcb->in_use) {
76 alarm_free(p_lcb->l2c_lcb_timer);
77 alarm_free(p_lcb->info_resp_timer);
78 *p_lcb = {};
79
80 p_lcb->remote_bd_addr = p_bd_addr;
81
82 p_lcb->in_use = true;
83 p_lcb->with_active_local_clients = false;
84 p_lcb->link_state = LST_DISCONNECTED;
85 p_lcb->InvalidateHandle();
86 p_lcb->l2c_lcb_timer = alarm_new("l2c_lcb.l2c_lcb_timer");
87 p_lcb->info_resp_timer = alarm_new("l2c_lcb.info_resp_timer");
88 p_lcb->idle_timeout = l2cb.idle_timeout;
89 p_lcb->signal_id = 1; /* spec does not allow '0' */
90 if (is_bonding) {
91 p_lcb->SetBonding();
92 } else {
93 p_lcb->ResetBonding();
94 }
95 p_lcb->transport = transport;
96 p_lcb->tx_data_len = bluetooth::shim::GetController()->GetLeSuggestedDefaultDataLength();
97 p_lcb->le_sec_pending_q = fixed_queue_new(SIZE_MAX);
98
99 if (transport == BT_TRANSPORT_LE) {
100 l2cb.num_ble_links_active++;
101 l2c_ble_link_adjust_allocation();
102 } else {
103 l2cb.num_used_lcbs++;
104 l2c_link_adjust_allocation();
105 }
106 p_lcb->link_xmit_data_q = list_new(NULL);
107 return p_lcb;
108 }
109 }
110
111 /* If here, no free LCB found */
112 return NULL;
113 }
114
l2cu_set_lcb_handle(tL2C_LCB & p_lcb,uint16_t handle)115 void l2cu_set_lcb_handle(tL2C_LCB& p_lcb, uint16_t handle) {
116 if (p_lcb.Handle() != HCI_INVALID_HANDLE) {
117 log::warn("Should not replace active handle:{} with new handle:{}", p_lcb.Handle(), handle);
118 }
119 p_lcb.SetHandle(handle);
120 }
121
122 /*******************************************************************************
123 *
124 * Function l2cu_update_lcb_4_bonding
125 *
126 * Description Mark the lcb for bonding. Used when bonding takes place on
127 * an existing ACL connection. (Pre-Lisbon devices)
128 *
129 * Returns Nothing
130 *
131 ******************************************************************************/
l2cu_update_lcb_4_bonding(const RawAddress & p_bd_addr,bool is_bonding)132 void l2cu_update_lcb_4_bonding(const RawAddress& p_bd_addr, bool is_bonding) {
133 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
134
135 if (p_lcb) {
136 log::verbose("BDA: {} is_bonding: {}", p_bd_addr, is_bonding);
137 if (is_bonding) {
138 p_lcb->SetBonding();
139 } else {
140 p_lcb->ResetBonding();
141 }
142 }
143 }
144
145 /*******************************************************************************
146 *
147 * Function l2cu_release_lcb
148 *
149 * Description Release an LCB. All timers will be stopped and freed,
150 * channels dropped, buffers returned etc.
151 *
152 * Returns void
153 *
154 ******************************************************************************/
l2cu_release_lcb(tL2C_LCB * p_lcb)155 void l2cu_release_lcb(tL2C_LCB* p_lcb) {
156 tL2C_CCB* p_ccb;
157
158 p_lcb->in_use = false;
159 p_lcb->ResetBonding();
160
161 /* Stop and free timers */
162 alarm_free(p_lcb->l2c_lcb_timer);
163 p_lcb->l2c_lcb_timer = NULL;
164 alarm_free(p_lcb->info_resp_timer);
165 p_lcb->info_resp_timer = NULL;
166
167 if (p_lcb->transport == BT_TRANSPORT_BR_EDR) { /* Release all SCO links */
168 get_btm_client_interface().sco.BTM_RemoveScoByBdaddr(p_lcb->remote_bd_addr);
169 }
170
171 if (p_lcb->sent_not_acked > 0) {
172 if (p_lcb->transport == BT_TRANSPORT_LE) {
173 l2cb.controller_le_xmit_window += p_lcb->sent_not_acked;
174 if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs) {
175 l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
176 }
177 } else {
178 l2cb.controller_xmit_window += p_lcb->sent_not_acked;
179 if (l2cb.controller_xmit_window > l2cb.num_lm_acl_bufs) {
180 l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
181 }
182 }
183 }
184
185 l2cu_process_fixed_disc_cback(p_lcb);
186
187 /* Ensure no CCBs left on this LCB */
188 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_lcb->ccb_queue.p_first_ccb) {
189 l2cu_release_ccb(p_ccb);
190 }
191
192 /* Tell BTM Acl management the link was removed */
193 if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING)) {
194 btm_acl_removed(p_lcb->Handle());
195 }
196
197 /* Release any held buffers */
198 if (p_lcb->link_xmit_data_q) {
199 while (!list_is_empty(p_lcb->link_xmit_data_q)) {
200 BT_HDR* p_buf = static_cast<BT_HDR*>(list_front(p_lcb->link_xmit_data_q));
201 list_remove(p_lcb->link_xmit_data_q, p_buf);
202 osi_free(p_buf);
203 }
204 list_free(p_lcb->link_xmit_data_q);
205 p_lcb->link_xmit_data_q = NULL;
206 }
207
208 /* Re-adjust flow control windows make sure it does not go negative */
209 if (p_lcb->transport == BT_TRANSPORT_LE) {
210 if (l2cb.num_ble_links_active >= 1) {
211 l2cb.num_ble_links_active--;
212 }
213
214 l2c_ble_link_adjust_allocation();
215 } else {
216 if (l2cb.num_used_lcbs >= 1) {
217 l2cb.num_used_lcbs--;
218 }
219
220 l2c_link_adjust_allocation();
221 }
222
223 p_lcb->suspended.clear();
224
225 /* Check and release all the LE COC connections waiting for security */
226 if (p_lcb->le_sec_pending_q) {
227 while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) {
228 tL2CAP_SEC_DATA* p_buf = (tL2CAP_SEC_DATA*)fixed_queue_try_dequeue(p_lcb->le_sec_pending_q);
229 if (p_buf->p_callback) {
230 p_buf->p_callback(p_lcb->remote_bd_addr, p_lcb->transport, p_buf->p_ref_data,
231 tBTM_STATUS::BTM_DEV_RESET);
232 }
233 osi_free(p_buf);
234 }
235 fixed_queue_free(p_lcb->le_sec_pending_q, NULL);
236 p_lcb->le_sec_pending_q = NULL;
237 }
238 }
239
240 /*******************************************************************************
241 *
242 * Function l2cu_find_lcb_by_bd_addr
243 *
244 * Description Look through all active LCBs for a match based on the
245 * remote BD address.
246 *
247 * Returns pointer to matched LCB, or NULL if no match
248 *
249 ******************************************************************************/
l2cu_find_lcb_by_bd_addr(const RawAddress & p_bd_addr,tBT_TRANSPORT transport)250 tL2C_LCB* l2cu_find_lcb_by_bd_addr(const RawAddress& p_bd_addr, tBT_TRANSPORT transport) {
251 int xx;
252 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
253
254 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
255 if ((p_lcb->in_use) && p_lcb->transport == transport && (p_lcb->remote_bd_addr == p_bd_addr)) {
256 return p_lcb;
257 }
258 }
259
260 /* If here, no match found */
261 return NULL;
262 }
263
264 /*******************************************************************************
265 *
266 * Function l2c_is_cmd_rejected
267 *
268 * Description Checks if cmd_code is command or response
269 * If a command it will be rejected per spec.
270 * This function is used when a illegal packet length is
271 * detected.
272 *
273 * Returns bool - true if cmd_code is a command and it is rejected,
274 * false if response code. (command not rejected)
275 *
276 ******************************************************************************/
l2c_is_cmd_rejected(uint8_t cmd_code,uint8_t signal_id,tL2C_LCB * p_lcb)277 bool l2c_is_cmd_rejected(uint8_t cmd_code, uint8_t signal_id, tL2C_LCB* p_lcb) {
278 switch (cmd_code) {
279 case L2CAP_CMD_CONN_REQ:
280 case L2CAP_CMD_CONFIG_REQ:
281 case L2CAP_CMD_DISC_REQ:
282 case L2CAP_CMD_ECHO_REQ:
283 case L2CAP_CMD_INFO_REQ:
284 case L2CAP_CMD_AMP_CONN_REQ:
285 case L2CAP_CMD_AMP_MOVE_REQ:
286 case L2CAP_CMD_BLE_UPDATE_REQ:
287 l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, signal_id, L2CAP_DEFAULT_MTU, 0);
288 log::warn("Dumping first Command ({})", cmd_code);
289 return true;
290
291 default: /* Otherwise a response */
292 return false;
293 }
294 }
295
296 /*******************************************************************************
297 *
298 * Function l2cu_build_header
299 *
300 * Description Builds the L2CAP command packet header
301 *
302 * Returns Pointer to allocated packet or NULL if no resources
303 *
304 ******************************************************************************/
l2cu_build_header(tL2C_LCB * p_lcb,uint16_t len,uint8_t cmd,uint8_t signal_id)305 static BT_HDR* l2cu_build_header(tL2C_LCB* p_lcb, uint16_t len, uint8_t cmd, uint8_t signal_id) {
306 BT_HDR* p_buf = (BT_HDR*)osi_malloc(L2CAP_CMD_BUF_SIZE);
307 uint8_t* p;
308
309 p_buf->offset = L2CAP_SEND_CMD_OFFSET;
310 p_buf->len = len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
311 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
312
313 /* Put in HCI header - handle + pkt boundary */
314 if (p_lcb->transport == BT_TRANSPORT_LE) {
315 UINT16_TO_STREAM(p,
316 (p_lcb->Handle() | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
317 } else {
318 UINT16_TO_STREAM(p, p_lcb->Handle() | l2cb.non_flushable_pbf);
319 }
320
321 UINT16_TO_STREAM(p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD);
322 UINT16_TO_STREAM(p, len + L2CAP_CMD_OVERHEAD);
323
324 if (p_lcb->transport == BT_TRANSPORT_LE) {
325 UINT16_TO_STREAM(p, L2CAP_BLE_SIGNALLING_CID);
326 } else {
327 UINT16_TO_STREAM(p, L2CAP_SIGNALLING_CID);
328 }
329
330 /* Put in L2CAP command header */
331 UINT8_TO_STREAM(p, cmd);
332 UINT8_TO_STREAM(p, signal_id);
333 UINT16_TO_STREAM(p, len);
334
335 return p_buf;
336 }
337
338 /*******************************************************************************
339 *
340 * Function l2cu_adj_id
341 *
342 * Description Checks for valid ID based on specified mask
343 * and adjusts the id if invalid.
344 *
345 * Returns void
346 *
347 ******************************************************************************/
l2cu_adj_id(tL2C_LCB * p_lcb)348 static void l2cu_adj_id(tL2C_LCB* p_lcb) {
349 if (p_lcb->signal_id == 0) {
350 p_lcb->signal_id++;
351 }
352 }
353
354 /*******************************************************************************
355 *
356 * Function l2cu_send_peer_cmd_reject
357 *
358 * Description Build and send an L2CAP "command reject" message
359 * to the peer.
360 *
361 * Returns void
362 *
363 ******************************************************************************/
l2cu_send_peer_cmd_reject(tL2C_LCB * p_lcb,uint16_t reason,uint8_t rem_id,uint16_t p1,uint16_t p2)364 void l2cu_send_peer_cmd_reject(tL2C_LCB* p_lcb, uint16_t reason, uint8_t rem_id, uint16_t p1,
365 uint16_t p2) {
366 uint16_t param_len;
367 BT_HDR* p_buf;
368 uint8_t* p;
369
370 /* Put in L2CAP packet header */
371 if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED) {
372 param_len = 2;
373 } else if (reason == L2CAP_CMD_REJ_INVALID_CID) {
374 param_len = 4;
375 } else {
376 param_len = 0;
377 }
378
379 p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_CMD_REJECT_LEN + param_len), L2CAP_CMD_REJECT,
380 rem_id);
381 if (p_buf == NULL) {
382 log::warn("L2CAP - no buffer cmd_rej");
383 return;
384 }
385
386 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
387 L2CAP_CMD_OVERHEAD;
388
389 UINT16_TO_STREAM(p, reason);
390
391 if (param_len >= 2) {
392 UINT16_TO_STREAM(p, p1);
393 }
394
395 if (param_len >= 4) {
396 UINT16_TO_STREAM(p, p2);
397 }
398
399 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
400 }
401
402 /*******************************************************************************
403 *
404 * Function l2cu_send_peer_connect_req
405 *
406 * Description Build and send an L2CAP "connection request" message
407 * to the peer.
408 *
409 * Returns void
410 *
411 ******************************************************************************/
l2cu_send_peer_connect_req(tL2C_CCB * p_ccb)412 void l2cu_send_peer_connect_req(tL2C_CCB* p_ccb) {
413 BT_HDR* p_buf;
414 uint8_t* p;
415
416 /* Create an identifier for this packet */
417 p_ccb->p_lcb->signal_id++;
418 l2cu_adj_id(p_ccb->p_lcb);
419
420 p_ccb->local_id = p_ccb->p_lcb->signal_id;
421
422 p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ, p_ccb->local_id);
423 if (p_buf == NULL) {
424 log::warn("L2CAP - no buffer for conn_req");
425 return;
426 }
427
428 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
429 L2CAP_CMD_OVERHEAD;
430
431 UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm);
432 UINT16_TO_STREAM(p, p_ccb->local_cid);
433
434 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
435 }
436
437 /*******************************************************************************
438 *
439 * Function l2cu_send_peer_connect_rsp
440 *
441 * Description Build and send an L2CAP "connection response" message
442 * to the peer.
443 *
444 * Returns void
445 *
446 ******************************************************************************/
l2cu_send_peer_connect_rsp(tL2C_CCB * p_ccb,tL2CAP_CONN result,uint16_t status)447 void l2cu_send_peer_connect_rsp(tL2C_CCB* p_ccb, tL2CAP_CONN result, uint16_t status) {
448 if (result == tL2CAP_CONN::L2CAP_CONN_PENDING) {
449 /* if we already sent pending response */
450 if (p_ccb->flags & CCB_FLAG_SENT_PENDING) {
451 log::debug("Already sent connection pending, not sending again");
452 return;
453 } else {
454 p_ccb->flags |= CCB_FLAG_SENT_PENDING;
455 }
456 }
457
458 BT_HDR* p_buf =
459 l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, p_ccb->remote_id);
460 if (p_buf == nullptr) {
461 log::warn("no buffer for conn_rsp");
462 return;
463 }
464
465 uint8_t* p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
466 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
467
468 UINT16_TO_STREAM(p, p_ccb->local_cid);
469 UINT16_TO_STREAM(p, p_ccb->remote_cid);
470 UINT16_TO_STREAM(p, static_cast<uint16_t>(result));
471 UINT16_TO_STREAM(p, status);
472
473 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
474 }
475
476 /*******************************************************************************
477 *
478 * Function l2cu_reject_connection
479 *
480 * Description Build and send an L2CAP "connection response neg" message
481 * to the peer. This function is called when there is no peer
482 * CCB (non-existant PSM or no resources).
483 *
484 * Returns void
485 *
486 ******************************************************************************/
l2cu_reject_connection(tL2C_LCB * p_lcb,uint16_t remote_cid,uint8_t rem_id,tL2CAP_CONN result)487 void l2cu_reject_connection(tL2C_LCB* p_lcb, uint16_t remote_cid, uint8_t rem_id,
488 tL2CAP_CONN result) {
489 BT_HDR* p_buf;
490 uint8_t* p;
491
492 p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id);
493 if (p_buf == NULL) {
494 log::warn("L2CAP - no buffer for conn_req");
495 return;
496 }
497
498 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
499 L2CAP_CMD_OVERHEAD;
500
501 UINT16_TO_STREAM(p, 0); /* Local CID of 0 */
502 UINT16_TO_STREAM(p, remote_cid);
503 UINT16_TO_STREAM(p, static_cast<uint16_t>(result));
504 UINT16_TO_STREAM(p, 0); /* Status of 0 */
505
506 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
507 }
508
509 /*******************************************************************************
510 *
511 * Function l2cu_send_credit_based_reconfig_req
512 *
513 * Description Build and send an L2CAP "recoonfiguration request" message
514 * to the peer.
515 *
516 * Returns void
517 *
518 ******************************************************************************/
l2cu_send_credit_based_reconfig_req(tL2C_CCB * p_ccb,tL2CAP_LE_CFG_INFO * p_cfg)519 void l2cu_send_credit_based_reconfig_req(tL2C_CCB* p_ccb, tL2CAP_LE_CFG_INFO* p_cfg) {
520 BT_HDR* p_buf;
521 uint16_t cmd_len;
522 uint8_t* p;
523 tL2C_LCB* p_lcb = p_ccb->p_lcb;
524 tL2C_CCB* p_ccb_temp;
525
526 cmd_len = L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ_MIN_LEN +
527 sizeof(uint16_t) * p_lcb->pending_ecoc_reconfig_cnt;
528
529 /* Create an identifier for this packet */
530 p_lcb->signal_id++;
531 l2cu_adj_id(p_lcb);
532
533 p_ccb->local_id = p_lcb->signal_id;
534
535 p_buf = l2cu_build_header(p_lcb, cmd_len, L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ, p_lcb->signal_id);
536 if (p_buf == NULL) {
537 log::warn("l2cu_send_reconfig_req - no buffer");
538 return;
539 }
540
541 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
542 L2CAP_CMD_OVERHEAD;
543
544 log::verbose("l2cu_send_reconfig_req number of cids: {} mtu:{} mps:{}",
545 p_lcb->pending_ecoc_reconfig_cnt, p_cfg->mtu, p_cfg->mps);
546
547 UINT16_TO_STREAM(p, p_cfg->mtu);
548 UINT16_TO_STREAM(p, p_cfg->mps);
549
550 for (p_ccb_temp = p_lcb->ccb_queue.p_first_ccb; p_ccb_temp; p_ccb_temp = p_ccb_temp->p_next_ccb) {
551 if ((p_ccb_temp->in_use) && (p_ccb_temp->ecoc) && (p_ccb_temp->reconfig_started)) {
552 UINT16_TO_STREAM(p, p_ccb_temp->local_cid);
553 }
554 }
555
556 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
557 }
558
559 /*******************************************************************************
560 *
561 * Function l2cu_send_peer_config_req
562 *
563 * Description Build and send an L2CAP "configuration request" message
564 * to the peer.
565 *
566 * Returns void
567 *
568 ******************************************************************************/
l2cu_send_peer_config_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)569 void l2cu_send_peer_config_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
570 BT_HDR* p_buf;
571 uint16_t cfg_len = 0;
572 uint8_t* p;
573
574 /* Create an identifier for this packet */
575 p_ccb->p_lcb->signal_id++;
576 l2cu_adj_id(p_ccb->p_lcb);
577
578 p_ccb->local_id = p_ccb->p_lcb->signal_id;
579
580 if (p_cfg->mtu_present) {
581 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
582 }
583 if (p_cfg->flush_to_present) {
584 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
585 }
586 if (p_cfg->qos_present) {
587 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
588 }
589 if (p_cfg->fcr_present) {
590 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
591 }
592 if (p_cfg->fcs_present) {
593 cfg_len += L2CAP_CFG_FCS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
594 }
595 if (p_cfg->ext_flow_spec_present) {
596 cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
597 }
598
599 p_buf = l2cu_build_header(p_ccb->p_lcb, (uint16_t)(L2CAP_CONFIG_REQ_LEN + cfg_len),
600 L2CAP_CMD_CONFIG_REQ, p_ccb->local_id);
601 if (p_buf == NULL) {
602 log::warn("L2CAP - no buffer for conn_req");
603 return;
604 }
605
606 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
607 L2CAP_CMD_OVERHEAD;
608
609 UINT16_TO_STREAM(p, p_ccb->remote_cid);
610 UINT16_TO_STREAM(p, p_cfg->flags); /* Flags (continuation) */
611
612 /* Now, put the options */
613 if (p_cfg->mtu_present) {
614 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_MTU);
615 UINT8_TO_STREAM(p, L2CAP_CFG_MTU_OPTION_LEN);
616 UINT16_TO_STREAM(p, p_cfg->mtu);
617 }
618 if (p_cfg->flush_to_present) {
619 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FLUSH_TOUT);
620 UINT8_TO_STREAM(p, L2CAP_CFG_FLUSH_OPTION_LEN);
621 UINT16_TO_STREAM(p, p_cfg->flush_to);
622 }
623 if (p_cfg->qos_present) {
624 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_QOS);
625 UINT8_TO_STREAM(p, L2CAP_CFG_QOS_OPTION_LEN);
626 UINT8_TO_STREAM(p, p_cfg->qos.qos_flags);
627 UINT8_TO_STREAM(p, p_cfg->qos.service_type);
628 UINT32_TO_STREAM(p, p_cfg->qos.token_rate);
629 UINT32_TO_STREAM(p, p_cfg->qos.token_bucket_size);
630 UINT32_TO_STREAM(p, p_cfg->qos.peak_bandwidth);
631 UINT32_TO_STREAM(p, p_cfg->qos.latency);
632 UINT32_TO_STREAM(p, p_cfg->qos.delay_variation);
633 }
634 if (p_cfg->fcr_present) {
635 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCR);
636 UINT8_TO_STREAM(p, L2CAP_CFG_FCR_OPTION_LEN);
637 UINT8_TO_STREAM(p, p_cfg->fcr.mode);
638 UINT8_TO_STREAM(p, p_cfg->fcr.tx_win_sz);
639 UINT8_TO_STREAM(p, p_cfg->fcr.max_transmit);
640 UINT16_TO_STREAM(p, p_cfg->fcr.rtrans_tout);
641 UINT16_TO_STREAM(p, p_cfg->fcr.mon_tout);
642 UINT16_TO_STREAM(p, p_cfg->fcr.mps);
643 }
644
645 if (p_cfg->fcs_present) {
646 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCS);
647 UINT8_TO_STREAM(p, L2CAP_CFG_FCS_OPTION_LEN);
648 UINT8_TO_STREAM(p, p_cfg->fcs);
649 }
650
651 if (p_cfg->ext_flow_spec_present) {
652 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_EXT_FLOW);
653 UINT8_TO_STREAM(p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
654 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.id);
655 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.stype);
656 UINT16_TO_STREAM(p, p_cfg->ext_flow_spec.max_sdu_size);
657 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.sdu_inter_time);
658 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.access_latency);
659 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.flush_timeout);
660 }
661
662 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
663 }
664
665 /*******************************************************************************
666 *
667 * Function l2cu_send_peer_config_rsp
668 *
669 * Description Build and send an L2CAP "configuration response" message
670 * to the peer.
671 *
672 * Returns void
673 *
674 ******************************************************************************/
l2cu_send_peer_config_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)675 void l2cu_send_peer_config_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
676 BT_HDR* p_buf;
677 uint16_t cfg_len = 0;
678 uint8_t* p;
679
680 /* Create an identifier for this packet */
681 if (p_cfg->mtu_present) {
682 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
683 }
684 if (p_cfg->flush_to_present) {
685 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
686 }
687 if (p_cfg->qos_present) {
688 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
689 }
690 if (p_cfg->fcr_present) {
691 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
692 }
693 if (p_cfg->ext_flow_spec_present) {
694 cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
695 }
696
697 p_buf = l2cu_build_header(p_ccb->p_lcb, (uint16_t)(L2CAP_CONFIG_RSP_LEN + cfg_len),
698 L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id);
699 if (p_buf == NULL) {
700 log::warn("L2CAP - no buffer for conn_req");
701 return;
702 }
703
704 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
705 L2CAP_CMD_OVERHEAD;
706
707 UINT16_TO_STREAM(p, p_ccb->remote_cid);
708 UINT16_TO_STREAM(p, p_cfg->flags); /* Flags (continuation) Must match request */
709 UINT16_TO_STREAM(p, static_cast<uint16_t>(p_cfg->result));
710
711 /* Now, put the options */
712 if (p_cfg->mtu_present) {
713 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_MTU);
714 UINT8_TO_STREAM(p, L2CAP_CFG_MTU_OPTION_LEN);
715 UINT16_TO_STREAM(p, p_cfg->mtu);
716 }
717 if (p_cfg->flush_to_present) {
718 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FLUSH_TOUT);
719 UINT8_TO_STREAM(p, L2CAP_CFG_FLUSH_OPTION_LEN);
720 UINT16_TO_STREAM(p, p_cfg->flush_to);
721 }
722 if (p_cfg->qos_present) {
723 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_QOS);
724 UINT8_TO_STREAM(p, L2CAP_CFG_QOS_OPTION_LEN);
725 UINT8_TO_STREAM(p, p_cfg->qos.qos_flags);
726 UINT8_TO_STREAM(p, p_cfg->qos.service_type);
727 UINT32_TO_STREAM(p, p_cfg->qos.token_rate);
728 UINT32_TO_STREAM(p, p_cfg->qos.token_bucket_size);
729 UINT32_TO_STREAM(p, p_cfg->qos.peak_bandwidth);
730 UINT32_TO_STREAM(p, p_cfg->qos.latency);
731 UINT32_TO_STREAM(p, p_cfg->qos.delay_variation);
732 }
733 if (p_cfg->fcr_present) {
734 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_FCR);
735 UINT8_TO_STREAM(p, L2CAP_CFG_FCR_OPTION_LEN);
736 UINT8_TO_STREAM(p, p_cfg->fcr.mode);
737 UINT8_TO_STREAM(p, p_cfg->fcr.tx_win_sz);
738 UINT8_TO_STREAM(p, p_cfg->fcr.max_transmit);
739 UINT16_TO_STREAM(p, p_ccb->our_cfg.fcr.rtrans_tout);
740 UINT16_TO_STREAM(p, p_ccb->our_cfg.fcr.mon_tout);
741 UINT16_TO_STREAM(p, p_cfg->fcr.mps);
742 }
743
744 if (p_cfg->ext_flow_spec_present) {
745 UINT8_TO_STREAM(p, L2CAP_CFG_TYPE_EXT_FLOW);
746 UINT8_TO_STREAM(p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
747 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.id);
748 UINT8_TO_STREAM(p, p_cfg->ext_flow_spec.stype);
749 UINT16_TO_STREAM(p, p_cfg->ext_flow_spec.max_sdu_size);
750 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.sdu_inter_time);
751 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.access_latency);
752 UINT32_TO_STREAM(p, p_cfg->ext_flow_spec.flush_timeout);
753 }
754
755 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
756 }
757
758 /*******************************************************************************
759 *
760 * Function l2cu_send_peer_config_rej
761 *
762 * Description Build and send an L2CAP "configuration reject" message
763 * to the peer.
764 *
765 * Returns void
766 *
767 ******************************************************************************/
l2cu_send_peer_config_rej(tL2C_CCB * p_ccb,uint8_t * p_data,uint16_t data_len,uint16_t rej_len)768 void l2cu_send_peer_config_rej(tL2C_CCB* p_ccb, uint8_t* p_data, uint16_t data_len,
769 uint16_t rej_len) {
770 uint16_t len, cfg_len, buf_space, len1;
771 uint8_t *p, *p_hci_len, *p_data_end;
772 uint8_t cfg_code;
773
774 log::verbose("l2cu_send_peer_config_rej: data_len={}, rej_len={}", data_len, rej_len);
775
776 len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD +
777 L2CAP_CONFIG_RSP_LEN;
778 len1 = 0xFFFF - len;
779 if (rej_len > len1) {
780 log::error("L2CAP - cfg_rej pkt size exceeds buffer design max limit.");
781 return;
782 }
783
784 BT_HDR* p_buf = (BT_HDR*)osi_malloc(len + rej_len);
785 p_buf->offset = L2CAP_SEND_CMD_OFFSET;
786 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
787
788 /* Put in HCI header - handle + pkt boundary */
789 if (bluetooth::shim::GetController()->SupportsNonFlushablePb()) {
790 UINT16_TO_STREAM(
791 p, (p_ccb->p_lcb->Handle() | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
792 } else {
793 UINT16_TO_STREAM(p, (p_ccb->p_lcb->Handle() | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
794 }
795
796 /* Remember the HCI header length position, and save space for it */
797 p_hci_len = p;
798 p += 2;
799
800 /* Put in L2CAP packet header */
801 UINT16_TO_STREAM(p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
802 UINT16_TO_STREAM(p, L2CAP_SIGNALLING_CID);
803
804 /* Put in L2CAP command header */
805 UINT8_TO_STREAM(p, L2CAP_CMD_CONFIG_RSP);
806 UINT8_TO_STREAM(p, p_ccb->remote_id);
807
808 UINT16_TO_STREAM(p, L2CAP_CONFIG_RSP_LEN + rej_len);
809
810 UINT16_TO_STREAM(p, p_ccb->remote_cid);
811 UINT16_TO_STREAM(p, 0); /* Flags = 0 (no continuation) */
812 UINT16_TO_STREAM(p, static_cast<uint16_t>(tL2CAP_CFG_RESULT::L2CAP_CFG_UNKNOWN_OPTIONS));
813
814 buf_space = rej_len;
815
816 /* Now, put the rejected options */
817 p_data_end = p_data + data_len;
818 while (p_data < p_data_end) {
819 cfg_code = *p_data;
820 cfg_len = *(p_data + 1);
821
822 switch (cfg_code & 0x7F) {
823 /* skip known options */
824 case L2CAP_CFG_TYPE_MTU:
825 case L2CAP_CFG_TYPE_FLUSH_TOUT:
826 case L2CAP_CFG_TYPE_QOS:
827 case L2CAP_CFG_TYPE_FCR:
828 case L2CAP_CFG_TYPE_FCS:
829 case L2CAP_CFG_TYPE_EXT_FLOW:
830 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
831 break;
832
833 /* unknown options; copy into rsp if not hints */
834 default:
835 /* sanity check option length */
836 if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len) {
837 if ((cfg_code & 0x80) == 0) {
838 if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD)) {
839 memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
840 p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
841 buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
842 } else {
843 log::warn("L2CAP - cfg_rej exceeds allocated buffer");
844 p_data = p_data_end; /* force loop exit */
845 break;
846 }
847 }
848 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
849 } else {
850 /* bad length; force loop exit */
851 p_data = p_data_end;
852 }
853 break;
854 }
855 }
856
857 len = (uint16_t)(p - p_hci_len - 2);
858 UINT16_TO_STREAM(p_hci_len, len);
859
860 p_buf->len = len + 4;
861
862 log::verbose("L2CAP - cfg_rej pkt hci_len={}, l2cap_len={}", len,
863 L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
864
865 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
866 }
867
868 /*******************************************************************************
869 *
870 * Function l2cu_send_peer_disc_req
871 *
872 * Description Build and send an L2CAP "disconnect request" message
873 * to the peer.
874 *
875 * Returns void
876 *
877 ******************************************************************************/
l2cu_send_peer_disc_req(tL2C_CCB * p_ccb)878 void l2cu_send_peer_disc_req(tL2C_CCB* p_ccb) {
879 BT_HDR *p_buf, *p_buf2;
880 uint8_t* p;
881
882 if ((!p_ccb) || (p_ccb->p_lcb == NULL)) {
883 log::error("L2CAP - ccb or lcb invalid");
884 return;
885 }
886
887 /* Create an identifier for this packet */
888 p_ccb->p_lcb->signal_id++;
889 l2cu_adj_id(p_ccb->p_lcb);
890
891 p_ccb->local_id = p_ccb->p_lcb->signal_id;
892
893 p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_ccb->local_id);
894 if (p_buf == NULL) {
895 log::warn("L2CAP - no buffer for disc_req");
896 return;
897 }
898
899 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
900 L2CAP_CMD_OVERHEAD;
901
902 UINT16_TO_STREAM(p, p_ccb->remote_cid);
903 UINT16_TO_STREAM(p, p_ccb->local_cid);
904
905 /* Move all queued data packets to the LCB. In FCR mode, assume the higher
906 layer checks that all buffers are sent before disconnecting.
907 */
908 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) {
909 while ((p_buf2 = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q)) != NULL) {
910 l2cu_set_acl_hci_header(p_buf2, p_ccb);
911 l2c_link_check_send_pkts(p_ccb->p_lcb, p_ccb->local_cid, p_buf2);
912 }
913 }
914
915 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
916 }
917
918 /*******************************************************************************
919 *
920 * Function l2cu_send_peer_disc_rsp
921 *
922 * Description Build and send an L2CAP "disconnect response" message
923 * to the peer.
924 *
925 * This function is passed the parameters for the disconnect
926 * response instead of the CCB address, as it may be called
927 * to send a disconnect response when there is no CCB.
928 *
929 * Returns void
930 *
931 ******************************************************************************/
l2cu_send_peer_disc_rsp(tL2C_LCB * p_lcb,uint8_t remote_id,uint16_t local_cid,uint16_t remote_cid)932 void l2cu_send_peer_disc_rsp(tL2C_LCB* p_lcb, uint8_t remote_id, uint16_t local_cid,
933 uint16_t remote_cid) {
934 BT_HDR* p_buf;
935 uint8_t* p;
936
937 p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id);
938 if (p_buf == NULL) {
939 log::warn("L2CAP - no buffer for disc_rsp");
940 return;
941 }
942
943 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
944 L2CAP_CMD_OVERHEAD;
945
946 UINT16_TO_STREAM(p, local_cid);
947 UINT16_TO_STREAM(p, remote_cid);
948
949 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
950 }
951
952 /*******************************************************************************
953 *
954 * Function l2cu_send_peer_echo_rsp
955 *
956 * Description Build and send an L2CAP "echo response" message
957 * to the peer.
958 *
959 * Returns void
960 *
961 ******************************************************************************/
l2cu_send_peer_echo_rsp(tL2C_LCB * p_lcb,uint8_t signal_id,uint8_t * p_data,uint16_t data_len)962 void l2cu_send_peer_echo_rsp(tL2C_LCB* p_lcb, uint8_t signal_id, uint8_t* p_data,
963 uint16_t data_len) {
964 BT_HDR* p_buf;
965 uint8_t* p;
966 uint16_t maxlen;
967 /* Filter out duplicate IDs or if available buffers are low (intruder
968 * checking) */
969 if (!signal_id || signal_id == p_lcb->cur_echo_id) {
970 /* Dump this request since it is illegal */
971 log::warn("L2CAP ignoring duplicate echo request ({})", signal_id);
972 return;
973 } else {
974 p_lcb->cur_echo_id = signal_id;
975 }
976
977 constexpr int kHciDataPreambleSize = 4;
978 uint16_t acl_data_size = bluetooth::shim::GetController()->GetAclPacketLength();
979 uint16_t acl_packet_size =
980 bluetooth::shim::GetController()->GetAclPacketLength() + kHciDataPreambleSize;
981 /* Don't return data if it does not fit in ACL and L2CAP MTU */
982 maxlen = (L2CAP_CMD_BUF_SIZE > acl_packet_size) ? acl_data_size : (uint16_t)L2CAP_CMD_BUF_SIZE;
983 maxlen -= (uint16_t)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
984 L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN);
985
986 if (data_len > maxlen) {
987 data_len = 0;
988 }
989
990 p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP,
991 signal_id);
992 if (p_buf == NULL) {
993 log::warn("L2CAP - no buffer for echo_rsp");
994 return;
995 }
996
997 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
998 L2CAP_CMD_OVERHEAD;
999
1000 if (data_len) {
1001 ARRAY_TO_STREAM(p, p_data, data_len);
1002 }
1003
1004 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
1005 }
1006
1007 /*******************************************************************************
1008 *
1009 * Function l2cu_send_peer_info_req
1010 *
1011 * Description Build and send an L2CAP "info request" message
1012 * to the peer.
1013 * Returns void
1014 *
1015 ******************************************************************************/
l2cu_send_peer_info_req(tL2C_LCB * p_lcb,uint16_t info_type)1016 void l2cu_send_peer_info_req(tL2C_LCB* p_lcb, uint16_t info_type) {
1017 BT_HDR* p_buf;
1018 uint8_t* p;
1019
1020 /* Create an identifier for this packet */
1021 p_lcb->signal_id++;
1022 l2cu_adj_id(p_lcb);
1023
1024 p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->signal_id);
1025 if (p_buf == NULL) {
1026 log::warn("L2CAP - no buffer for info_req");
1027 return;
1028 }
1029
1030 log::verbose("l2cu_send_peer_info_req: type 0x{:04x}", info_type);
1031
1032 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
1033 L2CAP_CMD_OVERHEAD;
1034
1035 UINT16_TO_STREAM(p, info_type);
1036
1037 p_lcb->w4_info_rsp = true;
1038 alarm_set_on_mloop(p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
1039 l2c_info_resp_timer_timeout, p_lcb);
1040
1041 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
1042 }
1043
1044 /*******************************************************************************
1045 *
1046 * Function l2cu_send_peer_info_rsp
1047 *
1048 * Description Build and send an L2CAP "info response" message
1049 * to the peer.
1050 *
1051 * Returns void
1052 *
1053 ******************************************************************************/
l2cu_send_peer_info_rsp(tL2C_LCB * p_lcb,uint8_t remote_id,uint16_t info_type)1054 void l2cu_send_peer_info_rsp(tL2C_LCB* p_lcb, uint8_t remote_id, uint16_t info_type) {
1055 BT_HDR* p_buf;
1056 uint8_t* p;
1057 uint16_t len = L2CAP_INFO_RSP_LEN;
1058
1059 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1060 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1061 (l2cb.test_info_resp &
1062 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | L2CAP_EXTFEA_NO_CRC |
1063 L2CAP_EXTFEA_EXT_FLOW_SPEC | L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
1064 L2CAP_EXTFEA_UCD_RECEPTION)))
1065 #else
1066 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1067 (L2CAP_EXTFEA_SUPPORTED_MASK &
1068 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | L2CAP_EXTFEA_NO_CRC |
1069 L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_UCD_RECEPTION)) != 0)
1070 #endif
1071 {
1072 len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE;
1073 } else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) {
1074 len += L2CAP_FIXED_CHNL_ARRAY_SIZE;
1075 } else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) {
1076 len += L2CAP_CONNLESS_MTU_INFO_SIZE;
1077 }
1078
1079 p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id);
1080 if (p_buf == NULL) {
1081 log::warn("L2CAP - no buffer for info_rsp");
1082 return;
1083 }
1084
1085 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
1086 L2CAP_CMD_OVERHEAD;
1087
1088 UINT16_TO_STREAM(p, info_type);
1089
1090 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1091 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1092 (l2cb.test_info_resp &
1093 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | L2CAP_EXTFEA_UCD_RECEPTION)))
1094 #else
1095 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1096 (L2CAP_EXTFEA_SUPPORTED_MASK &
1097 (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE | L2CAP_EXTFEA_UCD_RECEPTION)) != 0)
1098 #endif
1099 {
1100 UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1101 if (p_lcb->transport == BT_TRANSPORT_LE) {
1102 /* optional data are not added for now */
1103 UINT32_TO_STREAM(p, L2CAP_BLE_EXTFEA_MASK);
1104 } else {
1105 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1106 UINT32_TO_STREAM(p, l2cb.test_info_resp);
1107 #else
1108 UINT32_TO_STREAM(p, L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS);
1109 #endif
1110 }
1111 } else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) {
1112 UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1113 memset(p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE);
1114
1115 p[0] = L2CAP_FIXED_CHNL_SIG_BIT;
1116
1117 if (L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION) {
1118 p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT;
1119 }
1120
1121 {
1122 int xx;
1123
1124 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
1125 /* Skip fixed channels not used on BR/EDR-ACL link */
1126 if ((xx >= L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL) &&
1127 (xx <= L2CAP_SMP_CID - L2CAP_FIRST_FIXED_CHNL)) {
1128 continue;
1129 }
1130
1131 if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) {
1132 p[(xx + L2CAP_FIRST_FIXED_CHNL) / 8] |= 1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8);
1133 }
1134 }
1135 }
1136 } else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) {
1137 UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1138 UINT16_TO_STREAM(p, L2CAP_MTU_SIZE);
1139 } else {
1140 UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED); /* 'not supported' */
1141 }
1142
1143 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
1144 }
1145
1146 /******************************************************************************
1147 *
1148 * Function l2cu_enqueue_ccb
1149 *
1150 * Description queue CCB by priority. The first CCB is highest priority and
1151 * is served at first. The CCB is queued to an LLCB or an LCB.
1152 *
1153 * Returns None
1154 *
1155 ******************************************************************************/
l2cu_enqueue_ccb(tL2C_CCB * p_ccb)1156 void l2cu_enqueue_ccb(tL2C_CCB* p_ccb) {
1157 tL2C_CCB* p_ccb1;
1158 tL2C_CCB_Q* p_q = NULL;
1159
1160 /* Find out which queue the channel is on
1161 */
1162 if (p_ccb->p_lcb != NULL) {
1163 p_q = &p_ccb->p_lcb->ccb_queue;
1164 }
1165
1166 if ((!p_ccb->in_use) || (p_q == NULL)) {
1167 log::error("CID: 0x{:04x} ERROR in_use: {} p_lcb: {}", p_ccb->local_cid, p_ccb->in_use,
1168 std::format_ptr(p_ccb->p_lcb));
1169 return;
1170 }
1171
1172 log::verbose("l2cu_enqueue_ccb CID: 0x{:04x} priority: {}", p_ccb->local_cid,
1173 p_ccb->ccb_priority);
1174
1175 /* If the queue is empty, we go at the front */
1176 if (!p_q->p_first_ccb) {
1177 p_q->p_first_ccb = p_q->p_last_ccb = p_ccb;
1178 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1179 } else {
1180 p_ccb1 = p_q->p_first_ccb;
1181
1182 while (p_ccb1 != NULL) {
1183 /* Insert new ccb at the end of the same priority. Lower number, higher
1184 * priority */
1185 if (p_ccb->ccb_priority < p_ccb1->ccb_priority) {
1186 /* Are we at the head of the queue ? */
1187 if (p_ccb1 == p_q->p_first_ccb) {
1188 p_q->p_first_ccb = p_ccb;
1189 } else {
1190 p_ccb1->p_prev_ccb->p_next_ccb = p_ccb;
1191 }
1192
1193 p_ccb->p_next_ccb = p_ccb1;
1194 p_ccb->p_prev_ccb = p_ccb1->p_prev_ccb;
1195 p_ccb1->p_prev_ccb = p_ccb;
1196 break;
1197 }
1198
1199 p_ccb1 = p_ccb1->p_next_ccb;
1200 }
1201
1202 /* If we are lower then anyone in the list, we go at the end */
1203 if (!p_ccb1) {
1204 /* add new ccb at the end of the list */
1205 p_q->p_last_ccb->p_next_ccb = p_ccb;
1206
1207 p_ccb->p_next_ccb = NULL;
1208 p_ccb->p_prev_ccb = p_q->p_last_ccb;
1209 p_q->p_last_ccb = p_ccb;
1210 }
1211 }
1212
1213 /* Adding CCB into round robin service table of its LCB */
1214 if (p_ccb->p_lcb != NULL) {
1215 /* if this is the first channel in this priority group */
1216 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0) {
1217 /* Set the first channel to this CCB */
1218 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1219 /* Set the next serving channel in this group to this CCB */
1220 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1221 /* Initialize quota of this priority group based on its priority */
1222 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota =
1223 L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1224 }
1225 /* increase number of channels in this group */
1226 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++;
1227 }
1228 }
1229
1230 /******************************************************************************
1231 *
1232 * Function l2cu_dequeue_ccb
1233 *
1234 * Description dequeue CCB from a queue
1235 *
1236 * Returns -
1237 *
1238 ******************************************************************************/
l2cu_dequeue_ccb(tL2C_CCB * p_ccb)1239 void l2cu_dequeue_ccb(tL2C_CCB* p_ccb) {
1240 tL2C_CCB_Q* p_q = NULL;
1241
1242 log::verbose("l2cu_dequeue_ccb CID: 0x{:04x}", p_ccb->local_cid);
1243
1244 /* Find out which queue the channel is on
1245 */
1246 if (p_ccb->p_lcb != NULL) {
1247 p_q = &p_ccb->p_lcb->ccb_queue;
1248 }
1249
1250 if ((!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL)) {
1251 log::error(
1252 "l2cu_dequeue_ccb CID: 0x{:04x} ERROR in_use: {} p_lcb: 0x{} p_q: "
1253 "0x{} p_q->p_first_ccb: 0x{}",
1254 p_ccb->local_cid, p_ccb->in_use, std::format_ptr(p_ccb->p_lcb), std::format_ptr(p_q),
1255 std::format_ptr(p_q ? p_q->p_first_ccb : 0));
1256 return;
1257 }
1258
1259 /* Removing CCB from round robin service table of its LCB */
1260 if (p_ccb->p_lcb != NULL) {
1261 /* decrease number of channels in this priority group */
1262 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--;
1263
1264 /* if it was the last channel in the priority group */
1265 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0) {
1266 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1267 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1268 } else {
1269 /* if it is the first channel of this group */
1270 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb) {
1271 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb->p_next_ccb;
1272 }
1273 /* if it is the next serving channel of this group */
1274 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb) {
1275 /* simply, start serving from the first channel */
1276 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb =
1277 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb;
1278 }
1279 }
1280 }
1281
1282 if (p_ccb == p_q->p_first_ccb) {
1283 /* We are removing the first in a queue */
1284 p_q->p_first_ccb = p_ccb->p_next_ccb;
1285
1286 if (p_q->p_first_ccb) {
1287 p_q->p_first_ccb->p_prev_ccb = NULL;
1288 } else {
1289 p_q->p_last_ccb = NULL;
1290 }
1291 } else if (p_ccb == p_q->p_last_ccb) {
1292 /* We are removing the last in a queue */
1293 p_q->p_last_ccb = p_ccb->p_prev_ccb;
1294 p_q->p_last_ccb->p_next_ccb = NULL;
1295 } else {
1296 /* In the middle of a chain. */
1297 p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb;
1298 p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb;
1299 }
1300
1301 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1302 }
1303
1304 /******************************************************************************
1305 *
1306 * Function l2cu_change_pri_ccb
1307 *
1308 * Description
1309 *
1310 * Returns -
1311 *
1312 ******************************************************************************/
l2cu_change_pri_ccb(tL2C_CCB * p_ccb,tL2CAP_CHNL_PRIORITY priority)1313 void l2cu_change_pri_ccb(tL2C_CCB* p_ccb, tL2CAP_CHNL_PRIORITY priority) {
1314 if (p_ccb->ccb_priority != priority) {
1315 /* If CCB is not the only guy on the queue */
1316 if ((p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL)) {
1317 log::verbose("Update CCB list in logical link");
1318
1319 /* Remove CCB from queue and re-queue it at new priority */
1320 l2cu_dequeue_ccb(p_ccb);
1321
1322 p_ccb->ccb_priority = priority;
1323 l2cu_enqueue_ccb(p_ccb);
1324 } else {
1325 /* If CCB is the only guy on the queue, no need to re-enqueue */
1326 /* update only round robin service data */
1327 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0;
1328 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1329 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1330
1331 p_ccb->ccb_priority = priority;
1332
1333 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1334 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1335 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota =
1336 L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1337 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1;
1338 }
1339 }
1340 }
1341
1342 /*******************************************************************************
1343 *
1344 * Function l2cu_allocate_ccb
1345 *
1346 * Description This function allocates a Channel Control Block and
1347 * attaches it to a link control block. The local CID
1348 * is also assigned.
1349 *
1350 * Returns pointer to CCB, or NULL if none
1351 *
1352 ******************************************************************************/
l2cu_allocate_ccb(tL2C_LCB * p_lcb,uint16_t cid,bool is_eatt)1353 tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid, bool is_eatt) {
1354 log::debug("is_dynamic = {}, cid 0x{:04x}", p_lcb != nullptr, cid);
1355 if (!l2cb.p_free_ccb_first) {
1356 log::error("First free ccb is null for cid 0x{:04x}", cid);
1357 return nullptr;
1358 }
1359 tL2C_CCB* p_ccb;
1360 /* If a CID was passed in, use that, else take the first free one */
1361 if (cid == 0) {
1362 p_ccb = l2cb.p_free_ccb_first;
1363 l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1364 } else {
1365 tL2C_CCB* p_prev = nullptr;
1366
1367 p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID];
1368
1369 if (p_ccb == l2cb.p_free_ccb_first) {
1370 l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1371 } else {
1372 for (p_prev = l2cb.p_free_ccb_first; p_prev != nullptr; p_prev = p_prev->p_next_ccb) {
1373 if (p_prev->p_next_ccb == p_ccb) {
1374 p_prev->p_next_ccb = p_ccb->p_next_ccb;
1375
1376 if (p_ccb == l2cb.p_free_ccb_last) {
1377 l2cb.p_free_ccb_last = p_prev;
1378 }
1379
1380 break;
1381 }
1382 }
1383 if (p_prev == nullptr) {
1384 log::error("Could not find CCB for CID 0x{:04x} in the free list", cid);
1385 return nullptr;
1386 }
1387 }
1388 }
1389
1390 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = nullptr;
1391
1392 p_ccb->in_use = true;
1393
1394 /* Get a CID for the connection */
1395 p_ccb->local_cid = L2CAP_BASE_APPL_CID + (uint16_t)(p_ccb - l2cb.ccb_pool);
1396
1397 p_ccb->p_lcb = p_lcb;
1398 p_ccb->p_rcb = nullptr;
1399
1400 /* Set priority then insert ccb into LCB queue (if we have an LCB) */
1401 p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW;
1402
1403 if (p_lcb) {
1404 l2cu_enqueue_ccb(p_ccb);
1405 }
1406
1407 /* Put in default values for configuration */
1408 memset(&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1409 memset(&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1410
1411 /* Put in default values for local/peer configurations */
1412 p_ccb->our_cfg.flush_to = p_ccb->peer_cfg.flush_to = L2CAP_NO_AUTOMATIC_FLUSH;
1413 p_ccb->our_cfg.mtu = p_ccb->peer_cfg.mtu = L2CAP_DEFAULT_MTU;
1414 p_ccb->our_cfg.qos.service_type = p_ccb->peer_cfg.qos.service_type = L2CAP_DEFAULT_SERV_TYPE;
1415 p_ccb->our_cfg.qos.token_rate = p_ccb->peer_cfg.qos.token_rate = L2CAP_DEFAULT_TOKEN_RATE;
1416 p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size =
1417 L2CAP_DEFAULT_BUCKET_SIZE;
1418 p_ccb->our_cfg.qos.peak_bandwidth = p_ccb->peer_cfg.qos.peak_bandwidth =
1419 L2CAP_DEFAULT_PEAK_BANDWIDTH;
1420 p_ccb->our_cfg.qos.latency = p_ccb->peer_cfg.qos.latency = L2CAP_DEFAULT_LATENCY;
1421 p_ccb->our_cfg.qos.delay_variation = p_ccb->peer_cfg.qos.delay_variation = L2CAP_DEFAULT_DELAY;
1422
1423 p_ccb->peer_cfg_already_rejected = false;
1424 p_ccb->fcr_cfg_tries = L2CAP_MAX_FCR_CFG_TRIES;
1425
1426 alarm_free(p_ccb->fcrb.ack_timer);
1427 p_ccb->fcrb.ack_timer = alarm_new("l2c_fcrb.ack_timer");
1428
1429 /* CSP408639 Fix: When L2CAP send amp move channel request or receive
1430 * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
1431 * request -> Stop retrans/monitor timer -> Change channel state to
1432 * CST_AMP_MOVING. */
1433 alarm_free(p_ccb->fcrb.mon_retrans_timer);
1434 p_ccb->fcrb.mon_retrans_timer = alarm_new("l2c_fcrb.mon_retrans_timer");
1435
1436 p_ccb->max_rx_mtu =
1437 BT_DEFAULT_BUFFER_SIZE - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
1438 p_ccb->tx_mps = BT_DEFAULT_BUFFER_SIZE - 32;
1439
1440 p_ccb->xmit_hold_q = fixed_queue_new(SIZE_MAX);
1441 p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(SIZE_MAX);
1442 p_ccb->fcrb.retrans_q = fixed_queue_new(SIZE_MAX);
1443 p_ccb->fcrb.waiting_for_ack_q = fixed_queue_new(SIZE_MAX);
1444
1445 p_ccb->cong_sent = false;
1446 p_ccb->buff_quota = 2; /* This gets set after config */
1447
1448 /* If CCB was reserved Config_Done can already have some value */
1449 if (cid == 0) {
1450 p_ccb->config_done = 0;
1451 } else {
1452 log::debug("cid 0x{:04x} config_done:0x{:x}", cid, p_ccb->config_done);
1453 }
1454
1455 p_ccb->chnl_state = CST_CLOSED;
1456 p_ccb->flags = 0;
1457 p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1458 p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1459
1460 p_ccb->is_flushable = false;
1461 p_ccb->ecoc = false;
1462
1463 alarm_free(p_ccb->l2c_ccb_timer);
1464 p_ccb->l2c_ccb_timer = alarm_new("l2c.l2c_ccb_timer");
1465
1466 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1467 alarm_free(p_ccb->pts_config_delay_timer);
1468 p_ccb->pts_config_delay_timer = alarm_new("pts.delay");
1469 #endif
1470
1471 l2c_link_adjust_chnl_allocation();
1472
1473 if (p_lcb != NULL) {
1474 // once a dynamic channel is opened, timeouts become active
1475 // the exception for this is EATT, since that is managed by GATT clients,
1476 // not by the L2CAP layer (GATT will keep the idle timeout at infinity while
1477 // clients are active)
1478 if (!is_eatt) {
1479 p_lcb->with_active_local_clients = true;
1480 }
1481 }
1482
1483 return p_ccb;
1484 }
1485
1486 /*******************************************************************************
1487 *
1488 * Function l2cu_start_post_bond_timer
1489 *
1490 * Description This function starts the ACL Link inactivity timer after
1491 * dedicated bonding
1492 * This timer can be longer than the normal link inactivity
1493 * timer for some platforms.
1494 *
1495 * Returns bool - true if idle timer started or disconnect initiated
1496 * false if there's one or more pending CCB's exist
1497 *
1498 ******************************************************************************/
l2cu_start_post_bond_timer(uint16_t handle)1499 bool l2cu_start_post_bond_timer(uint16_t handle) {
1500 tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1501 if (p_lcb == nullptr) {
1502 log::warn("Unable to find link control block for handle:0x{:04x}", handle);
1503 return true;
1504 }
1505 p_lcb->ResetBonding();
1506
1507 /* Only start timer if no control blocks allocated */
1508 if (p_lcb->ccb_queue.p_first_ccb != nullptr) {
1509 log::debug("Unable to start post bond timer with existing dynamic channels");
1510 return false;
1511 }
1512
1513 switch (p_lcb->link_state) {
1514 case LST_CONNECTED:
1515 case LST_CONNECTING:
1516 case LST_DISCONNECTING: {
1517 /* If no channels on the connection, start idle timeout */
1518 uint64_t timeout_ms = L2CAP_BONDING_TIMEOUT * 1000;
1519
1520 if (p_lcb->idle_timeout == 0) {
1521 acl_disconnect_from_handle(
1522 p_lcb->Handle(), HCI_ERR_PEER_USER,
1523 "stack::l2cap::l2c_utils::l2cu_start_post_bond_timer Idle timeout");
1524 p_lcb->link_state = LST_DISCONNECTING;
1525 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
1526 }
1527 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, p_lcb);
1528 log::debug("Started link IDLE timeout_ms:{}", timeout_ms);
1529 return true;
1530 } break;
1531
1532 default:
1533 log::debug("Will not start post bond timer with link state:{}",
1534 link_state_text(p_lcb->link_state));
1535 break;
1536 }
1537 return false;
1538 }
1539
1540 /*******************************************************************************
1541 *
1542 * Function l2cu_release_ccb
1543 *
1544 * Description This function releases a Channel Control Block. The timer
1545 * is stopped, any attached buffers freed, and the CCB is
1546 * removed from the link control block.
1547 *
1548 * Returns void
1549 *
1550 ******************************************************************************/
l2cu_release_ccb(tL2C_CCB * p_ccb)1551 void l2cu_release_ccb(tL2C_CCB* p_ccb) {
1552 tL2C_LCB* p_lcb = p_ccb->p_lcb;
1553 tL2C_RCB* p_rcb = p_ccb->p_rcb;
1554
1555 log::verbose("l2cu_release_ccb: cid 0x{:04x} in_use: {}", p_ccb->local_cid, p_ccb->in_use);
1556
1557 /* If already released, could be race condition */
1558 if (!p_ccb->in_use) {
1559 return;
1560 }
1561
1562 if (p_rcb && p_lcb && p_ccb->chnl_state >= CST_OPEN) {
1563 bluetooth::shim::GetSnoopLogger()->SetL2capChannelClose(p_ccb->p_lcb->Handle(),
1564 p_ccb->local_cid, p_ccb->remote_cid);
1565 }
1566
1567 if (p_lcb) {
1568 bluetooth::shim::GetSnoopLogger()->ClearL2capAcceptlist(p_lcb->Handle(), p_ccb->local_cid,
1569 p_ccb->remote_cid);
1570 }
1571
1572 if (p_rcb && (p_rcb->psm != p_rcb->real_psm)) {
1573 BTM_SecClrServiceByPsm(p_rcb->psm);
1574 }
1575
1576 /* Free the timer */
1577 alarm_free(p_ccb->l2c_ccb_timer);
1578 p_ccb->l2c_ccb_timer = NULL;
1579
1580 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1581 alarm_free(p_ccb->pts_config_delay_timer);
1582 p_ccb->pts_config_delay_timer = NULL;
1583 #endif
1584
1585 fixed_queue_free(p_ccb->xmit_hold_q, osi_free);
1586 p_ccb->xmit_hold_q = NULL;
1587
1588 l2c_fcr_cleanup(p_ccb);
1589
1590 /* Channel may not be assigned to any LCB if it was just pre-reserved */
1591 if ((p_lcb) && (p_ccb->local_cid >= L2CAP_BASE_APPL_CID)) {
1592 l2cu_dequeue_ccb(p_ccb);
1593
1594 /* Delink the CCB from the LCB */
1595 p_ccb->p_lcb = NULL;
1596 }
1597
1598 /* Put the CCB back on the free pool */
1599 if (!l2cb.p_free_ccb_first) {
1600 l2cb.p_free_ccb_first = p_ccb;
1601 l2cb.p_free_ccb_last = p_ccb;
1602 p_ccb->p_next_ccb = NULL;
1603 p_ccb->p_prev_ccb = NULL;
1604 } else {
1605 p_ccb->p_next_ccb = NULL;
1606 p_ccb->p_prev_ccb = l2cb.p_free_ccb_last;
1607 l2cb.p_free_ccb_last->p_next_ccb = p_ccb;
1608 l2cb.p_free_ccb_last = p_ccb;
1609 }
1610
1611 /* Flag as not in use */
1612 p_ccb->in_use = false;
1613 // Clear Remote CID and Local Id
1614 p_ccb->remote_cid = 0;
1615 p_ccb->local_id = 0;
1616
1617 /* If no channels on the connection, start idle timeout */
1618 if ((p_lcb) && p_lcb->in_use) {
1619 if (p_lcb->link_state == LST_CONNECTED) {
1620 if (!p_lcb->ccb_queue.p_first_ccb) {
1621 // Closing a security channel on LE device should not start connection
1622 // timeout
1623 if (p_lcb->transport == BT_TRANSPORT_LE && p_ccb->local_cid == L2CAP_SMP_CID) {
1624 return;
1625 }
1626
1627 l2cu_no_dynamic_ccbs(p_lcb);
1628 } else {
1629 /* Link is still active, adjust channel quotas. */
1630 l2c_link_adjust_chnl_allocation();
1631 }
1632 } else if (p_lcb->link_state == LST_CONNECTING) {
1633 if (!p_lcb->ccb_queue.p_first_ccb) {
1634 if (p_lcb->transport == BT_TRANSPORT_LE && p_ccb->local_cid == L2CAP_ATT_CID) {
1635 log::warn("disconnecting the LE link");
1636 l2cu_no_dynamic_ccbs(p_lcb);
1637 }
1638 }
1639 }
1640 }
1641 }
1642
l2cu_fixed_channel_restore(tL2C_LCB * p_lcb,uint16_t fixed_cid)1643 void l2cu_fixed_channel_restore(tL2C_LCB* p_lcb, uint16_t fixed_cid) {
1644 if (!com::android::bluetooth::flags::transmit_smp_packets_before_release()) {
1645 return;
1646 }
1647 auto it = p_lcb->suspended.begin();
1648 while (it != p_lcb->suspended.end()) {
1649 if (*it == fixed_cid) {
1650 it = p_lcb->suspended.erase(it);
1651 } else {
1652 it++;
1653 }
1654 }
1655 }
1656
l2cu_fixed_channel_suspended(tL2C_LCB * p_lcb,uint16_t fixed_cid)1657 bool l2cu_fixed_channel_suspended(tL2C_LCB* p_lcb, uint16_t fixed_cid) {
1658 if (!com::android::bluetooth::flags::transmit_smp_packets_before_release()) {
1659 return false;
1660 }
1661 return std::find(p_lcb->suspended.begin(), p_lcb->suspended.end(), fixed_cid) !=
1662 p_lcb->suspended.end();
1663 }
1664
l2cu_fixed_channel_data_cb(tL2C_LCB * p_lcb,uint16_t fixed_cid,BT_HDR * p_buf)1665 void l2cu_fixed_channel_data_cb(tL2C_LCB* p_lcb, uint16_t fixed_cid, BT_HDR* p_buf) {
1666 if (l2cu_fixed_channel_suspended(p_lcb, fixed_cid)) {
1667 log::warn("Packet received for disconnecting fixed CID: 0x{:04x} BDA: {}", fixed_cid,
1668 p_lcb->remote_bd_addr);
1669 }
1670 (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(
1671 fixed_cid, p_lcb->remote_bd_addr, p_buf);
1672 }
1673
1674 /*******************************************************************************
1675 *
1676 * Function l2cu_find_ccb_by_remote_cid
1677 *
1678 * Description Look through all active CCBs on a link for a match based
1679 * on the remote CID.
1680 *
1681 * Returns pointer to matched CCB, or NULL if no match
1682 *
1683 ******************************************************************************/
l2cu_find_ccb_by_remote_cid(tL2C_LCB * p_lcb,uint16_t remote_cid)1684 tL2C_CCB* l2cu_find_ccb_by_remote_cid(tL2C_LCB* p_lcb, uint16_t remote_cid) {
1685 tL2C_CCB* p_ccb;
1686
1687 /* If LCB is NULL, look through all active links */
1688 if (!p_lcb) {
1689 return NULL;
1690 } else {
1691 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
1692 if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid)) {
1693 return p_ccb;
1694 }
1695 }
1696 }
1697
1698 /* If here, no match found */
1699 return NULL;
1700 }
1701
1702 /*******************************************************************************
1703 *
1704 * Function l2cu_allocate_rcb
1705 *
1706 * Description Look through the Registration Control Blocks for a free
1707 * one.
1708 *
1709 * Returns Pointer to the RCB or NULL if not found
1710 *
1711 ******************************************************************************/
l2cu_allocate_rcb(uint16_t psm)1712 tL2C_RCB* l2cu_allocate_rcb(uint16_t psm) {
1713 tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
1714 uint16_t xx;
1715
1716 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1717 if (!p_rcb->in_use) {
1718 p_rcb->in_use = true;
1719 p_rcb->psm = psm;
1720 return p_rcb;
1721 }
1722 }
1723
1724 /* If here, no free RCB found */
1725 return NULL;
1726 }
1727
1728 /*******************************************************************************
1729 *
1730 * Function l2cu_allocate_ble_rcb
1731 *
1732 * Description Look through the BLE Registration Control Blocks for a free
1733 * one.
1734 *
1735 * Returns Pointer to the BLE RCB or NULL if not found
1736 *
1737 ******************************************************************************/
l2cu_allocate_ble_rcb(uint16_t psm)1738 tL2C_RCB* l2cu_allocate_ble_rcb(uint16_t psm) {
1739 tL2C_RCB* p_rcb = &l2cb.ble_rcb_pool[0];
1740 uint16_t xx;
1741
1742 for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1743 if (!p_rcb->in_use) {
1744 p_rcb->in_use = true;
1745 p_rcb->psm = psm;
1746 return p_rcb;
1747 }
1748 }
1749
1750 /* If here, no free RCB found */
1751 return NULL;
1752 }
1753
1754 /*******************************************************************************
1755 *
1756 * Function l2cu_release_rcb
1757 *
1758 * Description Mark an RCB as no longet in use
1759 *
1760 * Returns void
1761 *
1762 ******************************************************************************/
l2cu_release_rcb(tL2C_RCB * p_rcb)1763 void l2cu_release_rcb(tL2C_RCB* p_rcb) {
1764 p_rcb->in_use = false;
1765 p_rcb->psm = 0;
1766 }
1767
1768 /*******************************************************************************
1769 *
1770 * Function l2cu_release_ble_rcb
1771 *
1772 * Description Mark an LE RCB as no longer in use
1773 *
1774 * Returns void
1775 *
1776 ******************************************************************************/
l2cu_release_ble_rcb(tL2C_RCB * p_rcb)1777 void l2cu_release_ble_rcb(tL2C_RCB* p_rcb) {
1778 stack::l2cap::get_interface().L2CA_FreeLePSM(p_rcb->psm);
1779 p_rcb->in_use = false;
1780 p_rcb->psm = 0;
1781 }
1782
1783 /*******************************************************************************
1784 *
1785 * Function l2cu_disconnect_chnl
1786 *
1787 * Description Disconnect a channel. Typically, this is due to either
1788 * receiving a bad configuration, bad packet or max_retries
1789 * expiring.
1790 *
1791 ******************************************************************************/
l2cu_disconnect_chnl(tL2C_CCB * p_ccb)1792 void l2cu_disconnect_chnl(tL2C_CCB* p_ccb) {
1793 uint16_t local_cid = p_ccb->local_cid;
1794
1795 if (local_cid >= L2CAP_BASE_APPL_CID) {
1796 tL2CA_DISCONNECT_IND_CB* p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
1797
1798 log::warn("L2CAP - disconnect_chnl CID: 0x{:04x}", local_cid);
1799
1800 l2cu_send_peer_disc_req(p_ccb);
1801
1802 l2cu_release_ccb(p_ccb);
1803
1804 (*p_disc_cb)(local_cid, false);
1805 } else {
1806 /* failure on the AMP channel, probably need to disconnect ACL */
1807 log::error("L2CAP - disconnect_chnl CID: 0x{:04x} Ignored", local_cid);
1808 }
1809 }
1810
1811 /*******************************************************************************
1812 *
1813 * Function l2cu_find_rcb_by_psm
1814 *
1815 * Description Look through the Registration Control Blocks to see if
1816 * anyone registered to handle the PSM in question
1817 *
1818 * Returns Pointer to the RCB or NULL if not found
1819 *
1820 ******************************************************************************/
l2cu_find_rcb_by_psm(uint16_t psm)1821 tL2C_RCB* l2cu_find_rcb_by_psm(uint16_t psm) {
1822 tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
1823 uint16_t xx;
1824
1825 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1826 if ((p_rcb->in_use) && (p_rcb->psm == psm)) {
1827 return p_rcb;
1828 }
1829 }
1830
1831 /* If here, no match found */
1832 return NULL;
1833 }
1834
1835 /*******************************************************************************
1836 *
1837 * Function l2cu_find_ble_rcb_by_psm
1838 *
1839 * Description Look through the BLE Registration Control Blocks to see if
1840 * anyone registered to handle the PSM in question
1841 *
1842 * Returns Pointer to the BLE RCB or NULL if not found
1843 *
1844 ******************************************************************************/
l2cu_find_ble_rcb_by_psm(uint16_t psm)1845 tL2C_RCB* l2cu_find_ble_rcb_by_psm(uint16_t psm) {
1846 tL2C_RCB* p_rcb = &l2cb.ble_rcb_pool[0];
1847 uint16_t xx;
1848
1849 for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1850 if ((p_rcb->in_use) && (p_rcb->psm == psm)) {
1851 return p_rcb;
1852 }
1853 }
1854
1855 /* If here, no match found */
1856 return NULL;
1857 }
1858
1859 /*************************************************************************************
1860 *
1861 * Function l2cu_get_fcs_len
1862 *
1863 * Description This function is called to determine FCS len in S/I Frames.
1864 *
1865 *
1866 * Returns 0 or L2CAP_FCS_LEN: 0 is returned when both sides configure `No FCS`
1867 *
1868 **************************************************************************************/
l2cu_get_fcs_len(tL2C_CCB * p_ccb)1869 uint8_t l2cu_get_fcs_len(tL2C_CCB* p_ccb) {
1870 log::verbose("our.fcs_present: {} our.fcs: {}, peer.fcs_present: {} peer.fcs: {}",
1871 p_ccb->our_cfg.fcs_present, p_ccb->our_cfg.fcs, p_ccb->peer_cfg.fcs_present,
1872 p_ccb->peer_cfg.fcs);
1873
1874 if (com::android::bluetooth::flags::l2cap_fcs_option_fix() &&
1875 (p_ccb->peer_cfg.fcs_present && p_ccb->peer_cfg.fcs == 0x00) &&
1876 (p_ccb->our_cfg.fcs_present && p_ccb->our_cfg.fcs == 0x00)) {
1877 return 0;
1878 }
1879
1880 return L2CAP_FCS_LEN;
1881 }
1882
1883 /*******************************************************************************
1884 *
1885 * Function l2cu_process_peer_cfg_req
1886 *
1887 * Description This function is called when the peer sends us a "config
1888 * request" message. It extracts the configuration of interest
1889 * and saves it in the CCB.
1890 *
1891 * Note: Negotiation of the FCR channel type is handled
1892 * internally, all others are passed to the upper layer.
1893 *
1894 * Returns uint8_t - L2CAP_PEER_CFG_OK if passed to upper layer,
1895 * L2CAP_PEER_CFG_UNACCEPTABLE if automatically
1896 * responded to because parameters are
1897 * unnacceptable from a specification point
1898 * of view.
1899 * L2CAP_PEER_CFG_DISCONNECT if no compatible channel
1900 * modes between the two devices, and shall
1901 * be closed.
1902 *
1903 ******************************************************************************/
l2cu_process_peer_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)1904 uint8_t l2cu_process_peer_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
1905 bool mtu_ok = true;
1906 bool qos_type_ok = true;
1907 bool flush_to_ok = true;
1908 bool fcr_ok = true;
1909 uint8_t fcr_status;
1910 uint16_t required_remote_mtu =
1911 std::max<uint16_t>(L2CAP_MIN_MTU, p_ccb->p_rcb->required_remote_mtu);
1912
1913 /* Ignore FCR parameters for basic mode */
1914 if (!p_cfg->fcr_present) {
1915 p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
1916 }
1917
1918 if (com::android::bluetooth::flags::l2cap_fcs_option_fix() && p_cfg->fcs_present) {
1919 p_ccb->peer_cfg.fcs_present = 1;
1920 p_ccb->peer_cfg.fcs = p_cfg->fcs;
1921 }
1922
1923 if (!p_cfg->mtu_present && required_remote_mtu > L2CAP_DEFAULT_MTU) {
1924 // We reject if we have a MTU requirement higher than default MTU
1925 p_cfg->mtu = required_remote_mtu;
1926 mtu_ok = false;
1927 } else if (p_cfg->mtu_present) {
1928 /* Make sure MTU is at least the minimum */
1929 if (p_cfg->mtu >= required_remote_mtu) {
1930 /* In basic mode, limit the MTU to our buffer size */
1931 if ((!p_cfg->fcr_present) && (p_cfg->mtu > L2CAP_MTU_SIZE)) {
1932 p_cfg->mtu = L2CAP_MTU_SIZE;
1933 }
1934
1935 /* Save the accepted value in case of renegotiation */
1936 p_ccb->peer_cfg.mtu = p_cfg->mtu;
1937 p_ccb->peer_cfg.mtu_present = true;
1938 } else {
1939 /* Illegal MTU value */
1940 p_cfg->mtu = required_remote_mtu;
1941 mtu_ok = false;
1942 }
1943 } else if (p_ccb->peer_cfg.mtu_present && !(p_ccb->config_done & IB_CFG_DONE)) {
1944 /* Reload mtu from a previously accepted config request */
1945 p_cfg->mtu_present = true;
1946 p_cfg->mtu = p_ccb->peer_cfg.mtu;
1947 }
1948
1949 /* Verify that the flush timeout is a valid value (0 is illegal) */
1950 if (p_cfg->flush_to_present) {
1951 if (!p_cfg->flush_to) {
1952 p_cfg->flush_to = 0xFFFF; /* Infinite retransmissions (spec default) */
1953 flush_to_ok = false;
1954 } else {
1955 /* Save the accepted value in case of renegotiation */
1956 p_ccb->peer_cfg.flush_to_present = true;
1957 p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
1958 }
1959 } else if (p_ccb->peer_cfg.flush_to_present && !(p_ccb->config_done & IB_CFG_DONE)) {
1960 /* Reload flush_to from a previously accepted config request */
1961 p_cfg->flush_to_present = true;
1962 p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
1963 }
1964
1965 /* Save the QOS settings the the peer is using */
1966 if (p_cfg->qos_present) {
1967 /* Make sure service type is not a reserved value; otherwise let upper
1968 layer decide if acceptable
1969 */
1970 if (p_cfg->qos.service_type <= SVC_TYPE_GUARANTEED) {
1971 p_ccb->peer_cfg.qos = p_cfg->qos;
1972 p_ccb->peer_cfg.qos_present = true;
1973 } else {
1974 /* Illegal service type value */
1975 p_cfg->qos.service_type = SVC_TYPE_BEST_EFFORT;
1976 qos_type_ok = false;
1977 }
1978 } else if (p_ccb->peer_cfg.qos_present && !(p_ccb->config_done & IB_CFG_DONE)) {
1979 /* Reload QOS from a previously accepted config request */
1980 p_cfg->qos_present = true;
1981 p_cfg->qos = p_ccb->peer_cfg.qos;
1982 }
1983
1984 fcr_status = l2c_fcr_process_peer_cfg_req(p_ccb, p_cfg);
1985 if (fcr_status == L2CAP_PEER_CFG_DISCONNECT) {
1986 /* Notify caller to disconnect the channel (incompatible modes) */
1987 p_cfg->result = tL2CAP_CFG_RESULT::L2CAP_CFG_FAILED_NO_REASON;
1988 p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
1989
1990 return L2CAP_PEER_CFG_DISCONNECT;
1991 }
1992
1993 fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
1994
1995 /* Return any unacceptable parameters */
1996 if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok) {
1997 l2cu_adjust_out_mps(p_ccb);
1998 return L2CAP_PEER_CFG_OK;
1999 } else {
2000 p_cfg->result = tL2CAP_CFG_RESULT::L2CAP_CFG_UNACCEPTABLE_PARAMS;
2001
2002 if (mtu_ok) {
2003 p_cfg->mtu_present = false;
2004 }
2005 if (flush_to_ok) {
2006 p_cfg->flush_to_present = false;
2007 }
2008 if (qos_type_ok) {
2009 p_cfg->qos_present = false;
2010 }
2011 if (fcr_ok) {
2012 p_cfg->fcr_present = false;
2013 }
2014
2015 return L2CAP_PEER_CFG_UNACCEPTABLE;
2016 }
2017 }
2018
2019 /*******************************************************************************
2020 *
2021 * Function l2cu_process_peer_cfg_rsp
2022 *
2023 * Description This function is called when the peer sends us a "config
2024 * response" message. It extracts the configuration of interest
2025 * and saves it in the CCB.
2026 *
2027 * Returns void
2028 *
2029 ******************************************************************************/
l2cu_process_peer_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2030 void l2cu_process_peer_cfg_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2031 /* If we wanted QoS and the peer sends us a positive response with QoS, use
2032 * his values */
2033 if ((p_cfg->qos_present) && (p_ccb->our_cfg.qos_present)) {
2034 p_ccb->our_cfg.qos = p_cfg->qos;
2035 }
2036
2037 if (p_cfg->fcr_present) {
2038 /* Save the retransmission and monitor timeout values */
2039 if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE) {
2040 p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
2041 p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
2042 }
2043
2044 /* Calculate the max number of packets for which we can delay sending an ack
2045 */
2046 if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz) {
2047 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
2048 } else {
2049 p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
2050 }
2051
2052 log::verbose(
2053 "l2cu_process_peer_cfg_rsp(): peer tx_win_sz: {}, our tx_win_sz: {}, "
2054 "max_held_acks: {}",
2055 p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks);
2056 }
2057 }
2058
2059 /*******************************************************************************
2060 *
2061 * Function l2cu_process_our_cfg_req
2062 *
2063 * Description This function is called when we send a "config request"
2064 * message. It extracts the configuration of interest and saves
2065 * it in the CCB.
2066 *
2067 * Returns void
2068 *
2069 ******************************************************************************/
l2cu_process_our_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2070 void l2cu_process_our_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2071 /* Save the QOS settings we are using for transmit */
2072 if (p_cfg->qos_present) {
2073 p_ccb->our_cfg.qos_present = true;
2074 p_ccb->our_cfg.qos = p_cfg->qos;
2075 }
2076
2077 if (p_cfg->fcr_present) {
2078 /* Override FCR options if attempting streaming or basic */
2079 if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE) {
2080 memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
2081 } else {
2082 /* On BR/EDR, timer values are zero in config request */
2083 /* On class 2 AMP, timer value in config request shall be non-0 processing
2084 * time */
2085 /* timer value in config response shall be greater than
2086 * received processing time */
2087 p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
2088 }
2089
2090 /* Set the threshold to send acks (may be updated in the cfg response) */
2091 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
2092
2093 /* Include FCS option only if peer can handle it */
2094 if ((p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC) == 0) {
2095 p_cfg->fcs_present = false;
2096 }
2097 } else {
2098 p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
2099 }
2100
2101 p_ccb->our_cfg.fcr.mode = p_cfg->fcr.mode;
2102 p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
2103 }
2104
2105 /*******************************************************************************
2106 *
2107 * Function l2cu_process_our_cfg_rsp
2108 *
2109 * Description This function is called when we send the peer a "config
2110 * response" message. It extracts the configuration of interest
2111 * and saves it in the CCB.
2112 *
2113 * Returns void
2114 *
2115 ******************************************************************************/
l2cu_process_our_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2116 void l2cu_process_our_cfg_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2117 /* If peer wants QoS, we are allowed to change the values in a positive
2118 * response */
2119 if ((p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present)) {
2120 p_ccb->peer_cfg.qos = p_cfg->qos;
2121 } else {
2122 p_cfg->qos_present = false;
2123 }
2124
2125 l2c_fcr_adj_our_rsp_options(p_ccb, p_cfg);
2126 }
2127
2128 /*******************************************************************************
2129 *
2130 * Function l2cu_device_reset
2131 *
2132 * Description This function is called when reset of the device is
2133 * completed. For all active connection simulate HCI_DISC
2134 *
2135 * Returns void
2136 *
2137 ******************************************************************************/
l2cu_device_reset(void)2138 void l2cu_device_reset(void) {
2139 int xx;
2140 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
2141
2142 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
2143 if ((p_lcb->in_use) && (p_lcb->Handle() != HCI_INVALID_HANDLE)) {
2144 l2c_link_hci_disc_comp(p_lcb->Handle(), HCI_ERR_UNDEFINED);
2145 }
2146 }
2147 }
2148
2149 /* This function initiates an acl connection to a LE device.
2150 * Returns true if request started successfully, false otherwise. */
l2cu_create_conn_le(tL2C_LCB * p_lcb)2151 bool l2cu_create_conn_le(tL2C_LCB* p_lcb) {
2152 if (!bluetooth::shim::GetController()->SupportsBle()) {
2153 return false;
2154 }
2155 p_lcb->transport = BT_TRANSPORT_LE;
2156 return l2cble_create_conn(p_lcb);
2157 }
2158
2159 /* This function initiates an acl connection to a Classic device via HCI. */
l2cu_create_conn_br_edr(tL2C_LCB * p_lcb)2160 void l2cu_create_conn_br_edr(tL2C_LCB* p_lcb) {
2161 const bool controller_supports_role_switch =
2162 bluetooth::shim::GetController()->SupportsRoleSwitch();
2163
2164 /* While creating a new classic connection, check check all the other
2165 * active connections where we are not SCO nor central.
2166 * If our controller supports role switching, try switching
2167 * roles back to CENTRAL on those connections.
2168 */
2169 tL2C_LCB* p_lcb_cur = &l2cb.lcb_pool[0];
2170 for (uint8_t xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++) {
2171 if (p_lcb_cur == p_lcb) {
2172 continue;
2173 }
2174 if (!p_lcb_cur->in_use) {
2175 continue;
2176 }
2177 if (get_btm_client_interface().sco.BTM_IsScoActiveByBdaddr(p_lcb_cur->remote_bd_addr)) {
2178 log::verbose("Central peripheral switch not allowed when SCO active");
2179 continue;
2180 }
2181 if (p_lcb->IsLinkRoleCentral()) {
2182 continue;
2183 }
2184 /* The LMP_switch_req shall be sent only if the ACL logical transport
2185 is in active mode, when encryption is disabled, and all synchronous
2186 logical transports on the same physical link are disabled." */
2187
2188 /*4_1_TODO check if btm_cb.devcb.local_features to be used instead */
2189 if (controller_supports_role_switch) {
2190 /* mark this lcb waiting for switch to be completed and
2191 start switch on the other one */
2192 p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH;
2193 p_lcb->SetLinkRoleAsCentral();
2194
2195 if (get_btm_client_interface().link_policy.BTM_SwitchRoleToCentral(
2196 p_lcb_cur->remote_bd_addr) == tBTM_STATUS::BTM_CMD_STARTED) {
2197 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_ROLE_SWITCH_TIMEOUT_MS,
2198 l2c_lcb_timer_timeout, p_lcb);
2199 return;
2200 }
2201 }
2202 }
2203 p_lcb->link_state = LST_CONNECTING;
2204 l2cu_create_conn_after_switch(p_lcb);
2205 }
2206
2207 /*******************************************************************************
2208 *
2209 * Function l2cu_create_conn_after_switch
2210 *
2211 * Description This continues a connection creation possibly after
2212 * a role switch.
2213 *
2214 ******************************************************************************/
l2cu_create_conn_after_switch(tL2C_LCB * p_lcb)2215 void l2cu_create_conn_after_switch(tL2C_LCB* p_lcb) {
2216 bluetooth::shim::ACL_CreateClassicConnection(p_lcb->remote_bd_addr);
2217
2218 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS, l2c_lcb_timer_timeout,
2219 p_lcb);
2220 }
2221
2222 /*******************************************************************************
2223 *
2224 * Function l2cu_find_lcb_by_state
2225 *
2226 * Description Look through all active LCBs for a match based on the
2227 * LCB state.
2228 *
2229 * Returns pointer to first matched LCB, or NULL if no match
2230 *
2231 ******************************************************************************/
l2cu_find_lcb_by_state(tL2C_LINK_STATE state)2232 tL2C_LCB* l2cu_find_lcb_by_state(tL2C_LINK_STATE state) {
2233 uint16_t i;
2234 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
2235
2236 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
2237 if ((p_lcb->in_use) && (p_lcb->link_state == state)) {
2238 return p_lcb;
2239 }
2240 }
2241
2242 /* If here, no match found */
2243 return NULL;
2244 }
2245
2246 /*******************************************************************************
2247 *
2248 * Function l2cu_lcb_disconnecting
2249 *
2250 * Description On each active lcb, check if the lcb is in disconnecting
2251 * state, or if there are no ccb's on the lcb (implying
2252 idle timeout is running), or if last ccb on the link
2253 is in disconnecting state.
2254 *
2255 * Returns true if any of above conditions met, false otherwise
2256 *
2257 ******************************************************************************/
l2cu_lcb_disconnecting(void)2258 bool l2cu_lcb_disconnecting(void) {
2259 tL2C_CCB* p_ccb;
2260 uint16_t i;
2261 bool status = false;
2262
2263 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
2264
2265 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
2266 if (p_lcb->in_use) {
2267 /* no ccbs on lcb, or lcb is in disconnecting state */
2268 if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING)) {
2269 status = true;
2270 break;
2271 } else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb) {
2272 /* only one ccb left on lcb */
2273 p_ccb = p_lcb->ccb_queue.p_first_ccb;
2274
2275 if ((p_ccb->in_use) && ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
2276 (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) {
2277 status = true;
2278 break;
2279 }
2280 }
2281 }
2282 }
2283 return status;
2284 }
2285
2286 /*******************************************************************************
2287 *
2288 * Function l2cu_set_acl_priority_latency_brcm
2289 *
2290 * Description Sends a VSC to set the ACL priority and recorded latency on
2291 * Broadcom chip.
2292 *
2293 * Returns void
2294 *
2295 ******************************************************************************/
2296
l2cu_set_acl_priority_latency_brcm(tL2C_LCB * p_lcb,tL2CAP_PRIORITY priority)2297 static void l2cu_set_acl_priority_latency_brcm(tL2C_LCB* p_lcb, tL2CAP_PRIORITY priority) {
2298 uint8_t vs_param;
2299 if (priority == L2CAP_PRIORITY_HIGH) {
2300 // priority to high, if using latency mode check preset latency
2301 if (p_lcb->use_latency_mode && p_lcb->preset_acl_latency == L2CAP_LATENCY_LOW) {
2302 log::info("Set ACL priority: High Priority and Low Latency Mode");
2303 vs_param = HCI_BRCM_ACL_HIGH_PRIORITY_LOW_LATENCY;
2304 p_lcb->set_latency(L2CAP_LATENCY_LOW);
2305 } else {
2306 log::info("Set ACL priority: High Priority Mode");
2307 vs_param = HCI_BRCM_ACL_HIGH_PRIORITY;
2308 }
2309 } else {
2310 // priority to normal
2311 log::info("Set ACL priority: Normal Mode");
2312 vs_param = HCI_BRCM_ACL_NORMAL_PRIORITY;
2313 p_lcb->set_latency(L2CAP_LATENCY_NORMAL);
2314 }
2315
2316 uint8_t command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2317 uint8_t* pp = command;
2318 UINT16_TO_STREAM(pp, p_lcb->Handle());
2319 UINT8_TO_STREAM(pp, vs_param);
2320
2321 get_btm_client_interface().vendor.BTM_VendorSpecificCommand(
2322 HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2323 }
2324
2325 /*******************************************************************************
2326 *
2327 * Function l2cu_set_acl_priority_latency_syna
2328 *
2329 * Description Sends a VSC to set the ACL priority and recorded latency on
2330 * Synaptics chip.
2331 *
2332 * Returns void
2333 *
2334 ******************************************************************************/
2335
l2cu_set_acl_priority_latency_syna(tL2C_LCB * p_lcb,tL2CAP_PRIORITY priority)2336 static void l2cu_set_acl_priority_latency_syna(tL2C_LCB* p_lcb, tL2CAP_PRIORITY priority) {
2337 uint8_t vs_param;
2338 if (priority == L2CAP_PRIORITY_HIGH) {
2339 // priority to high, if using latency mode check preset latency
2340 if (p_lcb->use_latency_mode && p_lcb->preset_acl_latency == L2CAP_LATENCY_LOW) {
2341 log::info("Set ACL priority: High Priority and Low Latency Mode");
2342 vs_param = HCI_SYNA_ACL_HIGH_PRIORITY_LOW_LATENCY;
2343 p_lcb->set_latency(L2CAP_LATENCY_LOW);
2344 } else {
2345 log::info("Set ACL priority: High Priority Mode");
2346 vs_param = HCI_SYNA_ACL_HIGH_PRIORITY;
2347 }
2348 } else {
2349 // priority to normal
2350 log::info("Set ACL priority: Normal Mode");
2351 vs_param = HCI_SYNA_ACL_NORMAL_PRIORITY;
2352 p_lcb->set_latency(L2CAP_LATENCY_NORMAL);
2353 }
2354
2355 uint8_t command[HCI_SYNA_ACL_PRIORITY_PARAM_SIZE];
2356 uint8_t* pp = command;
2357 UINT16_TO_STREAM(pp, p_lcb->Handle());
2358 UINT8_TO_STREAM(pp, vs_param);
2359
2360 get_btm_client_interface().vendor.BTM_VendorSpecificCommand(
2361 HCI_SYNA_SET_ACL_PRIORITY, HCI_SYNA_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2362 }
2363
2364 /*******************************************************************************
2365 *
2366 * Function l2cu_set_acl_priority_unisoc
2367 *
2368 * Description Sends a VSC to set the ACL priority on Unisoc chip.
2369 *
2370 * Returns void
2371 *
2372 ******************************************************************************/
2373
l2cu_set_acl_priority_unisoc(tL2C_LCB * p_lcb,tL2CAP_PRIORITY priority)2374 static void l2cu_set_acl_priority_unisoc(tL2C_LCB* p_lcb, tL2CAP_PRIORITY priority) {
2375 uint8_t vs_param;
2376 if (priority == L2CAP_PRIORITY_HIGH) {
2377 // priority to high
2378 log::info("Set ACL priority: High Priority Mode");
2379 vs_param = HCI_UNISOC_ACL_HIGH_PRIORITY;
2380 } else {
2381 // priority to normal
2382 log::info("Set ACL priority: Normal Mode");
2383 vs_param = HCI_UNISOC_ACL_NORMAL_PRIORITY;
2384 }
2385
2386 uint8_t command[HCI_UNISOC_ACL_PRIORITY_PARAM_SIZE];
2387 uint8_t* pp = command;
2388 UINT16_TO_STREAM(pp, p_lcb->Handle());
2389 UINT8_TO_STREAM(pp, vs_param);
2390
2391 get_btm_client_interface().vendor.BTM_VendorSpecificCommand(
2392 HCI_UNISOC_SET_ACL_PRIORITY, HCI_UNISOC_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2393 }
2394
2395 /*******************************************************************************
2396 *
2397 * Function l2cu_set_acl_priority
2398 *
2399 * Description Sets the transmission priority for a channel.
2400 * (For initial implementation only two values are valid.
2401 * L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
2402 *
2403 * Returns true if a valid channel, else false
2404 *
2405 ******************************************************************************/
2406
l2cu_set_acl_priority(const RawAddress & bd_addr,tL2CAP_PRIORITY priority,bool reset_after_rs)2407 bool l2cu_set_acl_priority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority,
2408 bool reset_after_rs) {
2409 log::verbose("SET ACL PRIORITY {}", priority);
2410
2411 /* Find the link control block for the acl channel */
2412 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
2413 if (p_lcb == NULL) {
2414 log::warn("L2CAP - no LCB for L2CA_SetAclPriority");
2415 return false;
2416 }
2417
2418 /* Link priority is set if:
2419 * 1. Change in priority requested from above L2CAP through API, Or
2420 * 2. High priority requested because of central/peripheral role switch */
2421 if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
2422 (reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) {
2423 #ifndef TARGET_FLOSS
2424 /* Use vendor specific commands to set the link priority */
2425 switch (bluetooth::shim::GetController()->GetLocalVersionInformation().manufacturer_name_) {
2426 case LMP_COMPID_BROADCOM:
2427 l2cu_set_acl_priority_latency_brcm(p_lcb, priority);
2428 break;
2429
2430 case LMP_COMPID_SYNAPTICS:
2431 l2cu_set_acl_priority_latency_syna(p_lcb, priority);
2432 break;
2433
2434 case LMP_COMPID_UNISOC:
2435 l2cu_set_acl_priority_unisoc(p_lcb, priority);
2436 break;
2437
2438 default:
2439 /* Not supported/required for other vendors */
2440 break;
2441 }
2442 #endif
2443 }
2444
2445 /* Adjust lmp buffer allocation for this channel if priority changed */
2446 if (p_lcb->acl_priority != priority) {
2447 p_lcb->acl_priority = priority;
2448 l2c_link_adjust_allocation();
2449 }
2450 return true;
2451 }
2452
2453 /*******************************************************************************
2454 *
2455 * Function l2cu_set_acl_latency_brcm
2456 *
2457 * Description Sends a VSC to set the ACL latency on Broadcom chip.
2458 *
2459 * Returns void
2460 *
2461 ******************************************************************************/
2462
l2cu_set_acl_latency_brcm(tL2C_LCB * p_lcb,tL2CAP_LATENCY latency)2463 static void l2cu_set_acl_latency_brcm(tL2C_LCB* p_lcb, tL2CAP_LATENCY latency) {
2464 log::info("Set ACL latency: {}", latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency");
2465
2466 uint8_t command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2467 uint8_t* pp = command;
2468 uint8_t vs_param = latency == L2CAP_LATENCY_LOW ? HCI_BRCM_ACL_HIGH_PRIORITY_LOW_LATENCY
2469 : HCI_BRCM_ACL_HIGH_PRIORITY;
2470 UINT16_TO_STREAM(pp, p_lcb->Handle());
2471 UINT8_TO_STREAM(pp, vs_param);
2472
2473 get_btm_client_interface().vendor.BTM_VendorSpecificCommand(
2474 HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2475 }
2476
2477 /*******************************************************************************
2478 *
2479 * Function l2cu_set_acl_latency_syna
2480 *
2481 * Description Sends a VSC to set the ACL latency on Synatics chip.
2482 *
2483 * Returns void
2484 *
2485 ******************************************************************************/
2486
l2cu_set_acl_latency_syna(tL2C_LCB * p_lcb,tL2CAP_LATENCY latency)2487 static void l2cu_set_acl_latency_syna(tL2C_LCB* p_lcb, tL2CAP_LATENCY latency) {
2488 log::info("Set ACL latency: {}", latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency");
2489
2490 uint8_t command[HCI_SYNA_ACL_PRIORITY_PARAM_SIZE];
2491 uint8_t* pp = command;
2492 uint8_t vs_param = latency == L2CAP_LATENCY_LOW ? HCI_SYNA_ACL_HIGH_PRIORITY_LOW_LATENCY
2493 : HCI_SYNA_ACL_HIGH_PRIORITY;
2494 UINT16_TO_STREAM(pp, p_lcb->Handle());
2495 UINT8_TO_STREAM(pp, vs_param);
2496
2497 get_btm_client_interface().vendor.BTM_VendorSpecificCommand(
2498 HCI_SYNA_SET_ACL_PRIORITY, HCI_SYNA_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2499 }
2500
2501 /*******************************************************************************
2502 *
2503 * Function l2cu_set_acl_latency_mtk
2504 *
2505 * Description Sends a VSC to set the ACL latency on Mediatek chip.
2506 *
2507 * Returns void
2508 *
2509 ******************************************************************************/
2510
l2cu_set_acl_latency_mtk(tL2CAP_LATENCY latency)2511 static void l2cu_set_acl_latency_mtk(tL2CAP_LATENCY latency) {
2512 log::info("Set ACL latency: {}", latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency");
2513
2514 uint8_t command[HCI_MTK_ACL_PRIORITY_PARAM_SIZE];
2515 uint8_t* pp = command;
2516 uint8_t vs_param =
2517 latency == L2CAP_LATENCY_LOW ? HCI_MTK_ACL_HIGH_PRIORITY : HCI_MTK_ACL_NORMAL_PRIORITY;
2518 UINT8_TO_STREAM(pp, vs_param);
2519 UINT8_TO_STREAM(pp, 0);
2520 UINT16_TO_STREAM(pp, 0); // reserved bytes
2521
2522 get_btm_client_interface().vendor.BTM_VendorSpecificCommand(
2523 HCI_MTK_SET_ACL_PRIORITY, HCI_MTK_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2524 }
2525
2526 /*******************************************************************************
2527 *
2528 * Function l2cu_set_acl_latency
2529 *
2530 * Description Sets the transmission latency for a channel.
2531 *
2532 * Returns true if a valid channel, else false
2533 *
2534 ******************************************************************************/
2535
l2cu_set_acl_latency(const RawAddress & bd_addr,tL2CAP_LATENCY latency)2536 bool l2cu_set_acl_latency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) {
2537 log::info("Set ACL low latency: {}", latency);
2538
2539 /* Find the link control block for the acl channel */
2540 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
2541
2542 if (p_lcb == nullptr) {
2543 log::warn("Set latency failed: LCB is null");
2544 return false;
2545 }
2546 /* only change controller's latency when stream using latency mode */
2547 if (p_lcb->use_latency_mode && p_lcb->is_high_priority() && latency != p_lcb->acl_latency) {
2548 switch (bluetooth::shim::GetController()->GetLocalVersionInformation().manufacturer_name_) {
2549 case LMP_COMPID_BROADCOM:
2550 l2cu_set_acl_latency_brcm(p_lcb, latency);
2551 break;
2552
2553 case LMP_COMPID_SYNAPTICS:
2554 l2cu_set_acl_latency_syna(p_lcb, latency);
2555 break;
2556
2557 case LMP_COMPID_MEDIATEK:
2558 l2cu_set_acl_latency_mtk(latency);
2559 break;
2560
2561 default:
2562 /* Not supported/required for other vendors */
2563 break;
2564 }
2565 p_lcb->set_latency(latency);
2566 }
2567 /* save the latency mode even if acl does not use latency mode or start*/
2568 p_lcb->preset_acl_latency = latency;
2569
2570 return true;
2571 }
2572
2573 /******************************************************************************
2574 *
2575 * Function l2cu_set_non_flushable_pbf
2576 *
2577 * Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
2578 *
2579 * Returns void
2580 *
2581 ******************************************************************************/
l2cu_set_non_flushable_pbf(bool is_supported)2582 void l2cu_set_non_flushable_pbf(bool is_supported) {
2583 if (is_supported) {
2584 l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
2585 } else {
2586 l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
2587 }
2588 }
2589
2590 /*******************************************************************************
2591 *
2592 * Function l2cu_resubmit_pending_sec_req
2593 *
2594 * Description This function is called when required security procedures
2595 * are completed and any pending requests can be re-submitted.
2596 *
2597 * Returns void
2598 *
2599 ******************************************************************************/
l2cu_resubmit_pending_sec_req(const RawAddress * p_bda)2600 void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda) {
2601 tL2C_CCB* p_ccb;
2602 tL2C_CCB* p_next_ccb;
2603 int xx;
2604
2605 log::verbose("l2cu_resubmit_pending_sec_req p_bda: 0x{}", std::format_ptr(p_bda));
2606
2607 /* If we are called with a BDA, only resubmit for that BDA */
2608 if (p_bda) {
2609 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(*p_bda, BT_TRANSPORT_BR_EDR);
2610
2611 /* If we don't have one, this is an error */
2612 if (p_lcb) {
2613 /* For all channels, send the event through their FSMs */
2614 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2615 p_next_ccb = p_ccb->p_next_ccb;
2616 l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2617 }
2618 } else {
2619 log::warn("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
2620 }
2621 } else {
2622 /* No BDA pasesed in, so check all links */
2623 tL2C_LCB* p_lcb{nullptr};
2624 for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
2625 if (p_lcb->in_use) {
2626 /* For all channels, send the event through their FSMs */
2627 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2628 p_next_ccb = p_ccb->p_next_ccb;
2629 l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2630 }
2631 }
2632 }
2633 }
2634 }
2635
2636 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
2637 /*******************************************************************************
2638 *
2639 * Function l2cu_set_info_rsp_mask
2640 *
2641 * Description This function allows the script wrapper to change the
2642 * info resp mask for conformance testing.
2643 *
2644 * Returns pointer to CCB, or NULL if none
2645 *
2646 ******************************************************************************/
l2cu_set_info_rsp_mask(uint32_t mask)2647 void l2cu_set_info_rsp_mask(uint32_t mask) { l2cb.test_info_resp = mask; }
2648 #endif /* L2CAP_CONFORMANCE_TESTING */
2649
2650 /*******************************************************************************
2651 *
2652 * Function l2cu_adjust_out_mps
2653 *
2654 * Description Sets our MPS based on current controller capabilities
2655 *
2656 * Returns void
2657 *
2658 ******************************************************************************/
l2cu_adjust_out_mps(tL2C_CCB * p_ccb)2659 void l2cu_adjust_out_mps(tL2C_CCB* p_ccb) {
2660 uint16_t packet_size;
2661
2662 /* on the tx side MTU is selected based on packet size of the controller */
2663 packet_size = get_btm_client_interface().peer.BTM_GetMaxPacketSize(p_ccb->p_lcb->remote_bd_addr);
2664
2665 if (packet_size <=
2666 (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) {
2667 /* something is very wrong */
2668 log::error("l2cu_adjust_out_mps bad packet size: {} will use MPS: {}", packet_size,
2669 p_ccb->peer_cfg.fcr.mps);
2670 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2671 } else {
2672 packet_size -=
2673 (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
2674
2675 /* We try to negotiate MTU that each packet can be split into whole
2676 number of max packets. For example if link is 1.2 max packet size is 339
2677 bytes.
2678 At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4
2679 overhead.
2680 1695, that will be 5 Dh5 packets. Now maximum L2CAP packet is
2681 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
2682
2683 For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1 3DH5
2684 packet
2685 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. */
2686 if (p_ccb->peer_cfg.fcr.mps >= packet_size) {
2687 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
2688 } else {
2689 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2690 }
2691
2692 log::verbose(
2693 "l2cu_adjust_out_mps use {} Based on peer_cfg.fcr.mps: {} "
2694 "packet_size: {}",
2695 p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
2696 }
2697 }
2698
2699 /*******************************************************************************
2700 *
2701 * Function l2cu_initialize_fixed_ccb
2702 *
2703 * Description Initialize a fixed channel's CCB
2704 *
2705 * Returns true or false
2706 *
2707 ******************************************************************************/
l2cu_initialize_fixed_ccb(tL2C_LCB * p_lcb,uint16_t fixed_cid)2708 bool l2cu_initialize_fixed_ccb(tL2C_LCB* p_lcb, uint16_t fixed_cid) {
2709 tL2C_CCB* p_ccb;
2710
2711 /* If we already have a CCB, then simply return */
2712 p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
2713 if ((p_ccb != NULL) && p_ccb->in_use) {
2714 /*
2715 * NOTE: The "in_use" check is needed to ignore leftover entries
2716 * that have been already released by l2cu_release_ccb().
2717 */
2718 return true;
2719 }
2720
2721 p_ccb = l2cu_allocate_ccb(NULL, 0);
2722 if (p_ccb == NULL) {
2723 return false;
2724 }
2725
2726 if (p_lcb->link_state == LST_DISCONNECTED) {
2727 alarm_cancel(p_lcb->l2c_lcb_timer);
2728 } else {
2729 log::warn("Unable to cancel link control block for link connection to device {}",
2730 p_lcb->remote_bd_addr);
2731 }
2732
2733 /* Set CID for the connection */
2734 p_ccb->local_cid = fixed_cid;
2735 p_ccb->remote_cid = fixed_cid;
2736
2737 p_ccb->is_flushable = false;
2738
2739 /* Link ccb to lcb and lcb to ccb */
2740 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
2741 p_ccb->p_lcb = p_lcb;
2742
2743 /* There is no configuration, so if the link is up, the channel is up */
2744 if (p_lcb->link_state == LST_CONNECTED) {
2745 p_ccb->chnl_state = CST_OPEN;
2746 }
2747
2748 /* Set the default idle timeout value to use */
2749 p_ccb->fixed_chnl_idle_tout =
2750 l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
2751 return true;
2752 }
2753
2754 /*******************************************************************************
2755 *
2756 * Function l2cu_no_dynamic_ccbs
2757 *
2758 * Description Handles the case when there are no more dynamic CCBs. If
2759 * there are any fixed CCBs, start the longest of the fixed CCB
2760 * timeouts, otherwise start the default link idle timeout or
2761 * disconnect.
2762 *
2763 * Returns void
2764 *
2765 ******************************************************************************/
l2cu_no_dynamic_ccbs(tL2C_LCB * p_lcb)2766 void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) {
2767 tBTM_STATUS rc;
2768 uint64_t timeout_ms = p_lcb->idle_timeout * 1000;
2769 bool start_timeout = true;
2770
2771 int xx;
2772
2773 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2774 if ((p_lcb->p_fixed_ccbs[xx] != NULL) &&
2775 (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000 > timeout_ms)) {
2776 if (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout == L2CAP_NO_IDLE_TIMEOUT) {
2777 log::verbose("NO IDLE timeout set for fixed cid 0x{:04x}",
2778 p_lcb->p_fixed_ccbs[xx]->local_cid);
2779 start_timeout = false;
2780 }
2781 timeout_ms = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000;
2782 }
2783 }
2784
2785 /* If the link is pairing, do not mess with the timeouts */
2786 if (p_lcb->IsBonding()) {
2787 return;
2788 }
2789
2790 log::verbose("l2cu_no_dynamic_ccbs() with_active_local_clients={}",
2791 p_lcb->with_active_local_clients);
2792 // Inactive connections should not timeout, since the ATT channel might still
2793 // be in use even without a GATT client. We only timeout if either a dynamic
2794 // channel or a GATT client was used, since then we expect the client to
2795 // manage the lifecycle of the connection.
2796 if (!p_lcb->with_active_local_clients) {
2797 return;
2798 }
2799
2800 if (timeout_ms == 0) {
2801 log::verbose("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
2802
2803 rc = btm_sec_disconnect(p_lcb->Handle(), HCI_ERR_PEER_USER,
2804 "stack::l2cap::l2c_utils::l2cu_no_dynamic_ccbs Idle timer popped");
2805 if (rc == tBTM_STATUS::BTM_CMD_STARTED) {
2806 l2cu_process_fixed_disc_cback(p_lcb);
2807 p_lcb->link_state = LST_DISCONNECTING;
2808 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
2809 } else if (rc == tBTM_STATUS::BTM_SUCCESS) {
2810 l2cu_process_fixed_disc_cback(p_lcb);
2811 /* BTM SEC will make sure that link is release (probably after pairing is
2812 * done) */
2813 p_lcb->link_state = LST_DISCONNECTING;
2814 start_timeout = false;
2815 } else if (p_lcb->IsBonding()) {
2816 acl_disconnect_from_handle(
2817 p_lcb->Handle(), HCI_ERR_PEER_USER,
2818 "stack::l2cap::l2c_utils::l2cu_no_dynamic_ccbs Bonding no traffic");
2819 l2cu_process_fixed_disc_cback(p_lcb);
2820 p_lcb->link_state = LST_DISCONNECTING;
2821 timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
2822 } else {
2823 /* probably no buffer to send disconnect */
2824 timeout_ms = BT_1SEC_TIMEOUT_MS;
2825 }
2826 }
2827
2828 if (start_timeout) {
2829 alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, p_lcb);
2830 log::debug("Started link IDLE timeout_ms:{}", timeout_ms);
2831 } else {
2832 alarm_cancel(p_lcb->l2c_lcb_timer);
2833 }
2834 }
2835
2836 /*******************************************************************************
2837 *
2838 * Function l2cu_process_fixed_chnl_resp
2839 *
2840 * Description handle a fixed channel response (or lack thereof)
2841 * if the link failed, or a fixed channel response was
2842 * not received, the bitfield is all zeros.
2843 *
2844 ******************************************************************************/
l2cu_process_fixed_chnl_resp(tL2C_LCB * p_lcb)2845 void l2cu_process_fixed_chnl_resp(tL2C_LCB* p_lcb) {
2846 if (p_lcb->transport == BT_TRANSPORT_BR_EDR) {
2847 /* ignore all not assigned BR/EDR channels */
2848 p_lcb->peer_chnl_mask[0] &= (L2CAP_FIXED_CHNL_SIG_BIT | L2CAP_FIXED_CHNL_CNCTLESS_BIT |
2849 L2CAP_FIXED_CHNL_SMP_BR_BIT);
2850 } else {
2851 p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask;
2852 }
2853
2854 /* Tell all registered fixed channels about the connection */
2855 for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2856 uint16_t channel_id = xx + L2CAP_FIRST_FIXED_CHNL;
2857
2858 /* See BT Spec Ver 5.0 | Vol 3, Part A 2.1 table 2.1 and 2.2 */
2859
2860 /* skip sending LE fix channel callbacks on BR/EDR links */
2861 if (p_lcb->transport == BT_TRANSPORT_BR_EDR && channel_id >= L2CAP_ATT_CID &&
2862 channel_id <= L2CAP_SMP_CID) {
2863 continue;
2864 }
2865
2866 /* skip sending BR fix channel callbacks on LE links */
2867 if (p_lcb->transport == BT_TRANSPORT_LE && channel_id == L2CAP_SMP_BR_CID) {
2868 continue;
2869 }
2870
2871 if (!l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb) {
2872 continue;
2873 }
2874
2875 if (p_lcb->peer_chnl_mask[(channel_id) / 8] & (1 << ((channel_id) % 8))) {
2876 if (p_lcb->p_fixed_ccbs[xx]) {
2877 p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
2878 }
2879 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(channel_id, p_lcb->remote_bd_addr, true, 0,
2880 p_lcb->transport);
2881 } else {
2882 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(channel_id, p_lcb->remote_bd_addr, false,
2883 p_lcb->DisconnectReason(), p_lcb->transport);
2884
2885 if (p_lcb->p_fixed_ccbs[xx]) {
2886 l2cu_release_ccb(p_lcb->p_fixed_ccbs[xx]);
2887 p_lcb->p_fixed_ccbs[xx] = NULL;
2888 }
2889 }
2890 }
2891 }
2892
2893 /*******************************************************************************
2894 *
2895 * Function l2cu_process_fixed_disc_cback
2896 *
2897 * Description send l2cap fixed channel disconnection callback to the
2898 * application
2899 *
2900 * Returns void
2901 *
2902 ******************************************************************************/
l2cu_process_fixed_disc_cback(tL2C_LCB * p_lcb)2903 void l2cu_process_fixed_disc_cback(tL2C_LCB* p_lcb) {
2904 /* Select peer channels mask to use depending on transport */
2905 uint8_t peer_channel_mask = p_lcb->peer_chnl_mask[0];
2906
2907 // For LE, reset the stored peer channel mask
2908 if (p_lcb->transport == BT_TRANSPORT_LE) {
2909 p_lcb->peer_chnl_mask[0] = 0;
2910 }
2911
2912 for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2913 if (p_lcb->p_fixed_ccbs[xx]) {
2914 if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) {
2915 tL2C_CCB* p_l2c_chnl_ctrl_block;
2916 p_l2c_chnl_ctrl_block = p_lcb->p_fixed_ccbs[xx];
2917 p_lcb->p_fixed_ccbs[xx] = NULL;
2918 l2cu_release_ccb(p_l2c_chnl_ctrl_block);
2919 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr,
2920 false, p_lcb->DisconnectReason(),
2921 p_lcb->transport);
2922 }
2923 } else if ((peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) &&
2924 (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)) {
2925 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr,
2926 false, p_lcb->DisconnectReason(), p_lcb->transport);
2927 }
2928 }
2929 }
2930
2931 /*******************************************************************************
2932 *
2933 * Function l2cu_send_peer_ble_par_req
2934 *
2935 * Description Build and send a BLE parameter update request message
2936 * to the peer.
2937 *
2938 * Returns void
2939 *
2940 ******************************************************************************/
l2cu_send_peer_ble_par_req(tL2C_LCB * p_lcb,uint16_t min_int,uint16_t max_int,uint16_t latency,uint16_t timeout)2941 void l2cu_send_peer_ble_par_req(tL2C_LCB* p_lcb, uint16_t min_int, uint16_t max_int,
2942 uint16_t latency, uint16_t timeout) {
2943 BT_HDR* p_buf;
2944 uint8_t* p;
2945
2946 /* Create an identifier for this packet */
2947 p_lcb->signal_id++;
2948 l2cu_adj_id(p_lcb);
2949
2950 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN, L2CAP_CMD_BLE_UPDATE_REQ,
2951 p_lcb->signal_id);
2952 if (p_buf == NULL) {
2953 log::warn("l2cu_send_peer_ble_par_req - no buffer");
2954 return;
2955 }
2956
2957 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
2958 L2CAP_CMD_OVERHEAD;
2959
2960 UINT16_TO_STREAM(p, min_int);
2961 UINT16_TO_STREAM(p, max_int);
2962 UINT16_TO_STREAM(p, latency);
2963 UINT16_TO_STREAM(p, timeout);
2964
2965 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
2966 }
2967
2968 /*******************************************************************************
2969 *
2970 * Function l2cu_send_peer_ble_par_rsp
2971 *
2972 * Description Build and send a BLE parameter update response message
2973 * to the peer.
2974 *
2975 * Returns void
2976 *
2977 ******************************************************************************/
l2cu_send_peer_ble_par_rsp(tL2C_LCB * p_lcb,tL2CAP_CFG_RESULT reason,uint8_t rem_id)2978 void l2cu_send_peer_ble_par_rsp(tL2C_LCB* p_lcb, tL2CAP_CFG_RESULT reason, uint8_t rem_id) {
2979 BT_HDR* p_buf;
2980 uint8_t* p;
2981
2982 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN, L2CAP_CMD_BLE_UPDATE_RSP, rem_id);
2983 if (p_buf == NULL) {
2984 log::warn("l2cu_send_peer_ble_par_rsp - no buffer");
2985 return;
2986 }
2987
2988 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
2989 L2CAP_CMD_OVERHEAD;
2990
2991 UINT16_TO_STREAM(p, static_cast<uint16_t>(reason));
2992
2993 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
2994 }
2995
2996 /*******************************************************************************
2997 *
2998 * Function l2cu_send_peer_ble_credit_based_conn_req
2999 *
3000 * Description Build and send a BLE packet to establish LE connection
3001 * oriented L2CAP channel.
3002 *
3003 * Returns void
3004 *
3005 ******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB * p_ccb)3006 void l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB* p_ccb) {
3007 BT_HDR* p_buf;
3008 uint8_t* p;
3009 tL2C_LCB* p_lcb = NULL;
3010 uint16_t mtu;
3011 uint16_t mps;
3012 uint16_t initial_credit;
3013
3014 if (!p_ccb) {
3015 return;
3016 }
3017 p_lcb = p_ccb->p_lcb;
3018
3019 /* Create an identifier for this packet */
3020 p_ccb->p_lcb->signal_id++;
3021 l2cu_adj_id(p_ccb->p_lcb);
3022
3023 p_ccb->local_id = p_ccb->p_lcb->signal_id;
3024
3025 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN,
3026 L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ, p_lcb->signal_id);
3027 if (p_buf == NULL) {
3028 log::warn("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
3029 return;
3030 }
3031
3032 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3033 L2CAP_CMD_OVERHEAD;
3034
3035 mtu = p_ccb->local_conn_cfg.mtu;
3036 mps = p_ccb->local_conn_cfg.mps;
3037 initial_credit = p_ccb->local_conn_cfg.credits;
3038
3039 log::verbose(
3040 "l2cu_send_peer_ble_credit_based_conn_req PSM:0x{:04x} local_cid:{} "
3041 "mtu:{} mps:{} initial_credit:{}",
3042 p_ccb->p_rcb->real_psm, p_ccb->local_cid, mtu, mps, initial_credit);
3043
3044 UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm);
3045 UINT16_TO_STREAM(p, p_ccb->local_cid);
3046 UINT16_TO_STREAM(p, mtu);
3047 UINT16_TO_STREAM(p, mps);
3048 UINT16_TO_STREAM(p, initial_credit);
3049
3050 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
3051 }
3052
3053 /*******************************************************************************
3054 *
3055 * Function l2cu_send_peer_credit_based_conn_req
3056 *
3057 * Description Build and send a BLE packet to establish enhanced connection
3058 * oriented L2CAP channel.
3059 *
3060 * Returns void
3061 *
3062 ******************************************************************************/
l2cu_send_peer_credit_based_conn_req(tL2C_CCB * p_ccb)3063 void l2cu_send_peer_credit_based_conn_req(tL2C_CCB* p_ccb) {
3064 BT_HDR* p_buf;
3065 uint8_t* p;
3066 tL2C_LCB* p_lcb = NULL;
3067 uint16_t mtu;
3068 uint16_t mps;
3069 uint16_t initial_credit;
3070
3071 if (!p_ccb) {
3072 return;
3073 }
3074
3075 p_lcb = p_ccb->p_lcb;
3076
3077 /* Create an identifier for this packet */
3078 p_ccb->p_lcb->signal_id++;
3079 l2cu_adj_id(p_ccb->p_lcb);
3080
3081 p_ccb->local_id = p_lcb->signal_id;
3082
3083 p_buf = l2cu_build_header(
3084 p_lcb, L2CAP_CMD_CREDIT_BASED_CONN_REQ_MIN_LEN + 2 * p_lcb->pending_ecoc_conn_cnt,
3085 L2CAP_CMD_CREDIT_BASED_CONN_REQ, p_ccb->local_id);
3086 if (p_buf == NULL) {
3087 log::warn("no buffer");
3088 return;
3089 }
3090
3091 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3092 L2CAP_CMD_OVERHEAD;
3093
3094 mtu = p_ccb->local_conn_cfg.mtu;
3095 mps = p_ccb->local_conn_cfg.mps;
3096 initial_credit = p_ccb->local_conn_cfg.credits;
3097
3098 log::verbose("PSM:0x{:04x} mtu:{} mps:{} initial_credit:{}, cids_cnt {}", p_ccb->p_rcb->real_psm,
3099 mtu, mps, initial_credit, p_lcb->pending_ecoc_conn_cnt);
3100
3101 UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm);
3102 UINT16_TO_STREAM(p, mtu);
3103 UINT16_TO_STREAM(p, mps);
3104 UINT16_TO_STREAM(p, initial_credit);
3105
3106 for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) {
3107 uint16_t cid = p_lcb->pending_ecoc_connection_cids[i];
3108 log::verbose("cid: {}", cid);
3109 UINT16_TO_STREAM(p, cid);
3110 }
3111
3112 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
3113 }
3114
3115 /*******************************************************************************
3116 *
3117 * Function l2cu_reject_ble_coc_connection
3118 *
3119 * Description Build and send an L2CAP "Credit based connection res"
3120 * message to the peer. This function is called for non-success
3121 * cases.
3122 *
3123 * Returns void
3124 *
3125 ******************************************************************************/
l2cu_reject_ble_coc_connection(tL2C_LCB * p_lcb,uint8_t rem_id,tL2CAP_LE_RESULT_CODE result)3126 void l2cu_reject_ble_coc_connection(tL2C_LCB* p_lcb, uint8_t rem_id, tL2CAP_LE_RESULT_CODE result) {
3127 BT_HDR* p_buf;
3128 uint8_t* p;
3129
3130 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
3131 L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, rem_id);
3132 if (p_buf == NULL) {
3133 log::warn("l2cu_reject_ble_coc_connection - no buffer");
3134 return;
3135 }
3136
3137 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3138 L2CAP_CMD_OVERHEAD;
3139
3140 UINT16_TO_STREAM(p, 0); /* Local CID of 0 */
3141 UINT16_TO_STREAM(p, 0); /* MTU */
3142 UINT16_TO_STREAM(p, 0); /* MPS */
3143 UINT16_TO_STREAM(p, 0); /* initial credit */
3144 uint16_t result_u16 = static_cast<uint16_t>(result);
3145 UINT16_TO_STREAM(p, result_u16);
3146
3147 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
3148 }
3149
3150 /*******************************************************************************
3151 *
3152 * Function l2cu_reject_credit_based_connection_req
3153 *
3154 * Description Build and send an L2CAP "credit based connection
3155 *res" message to the peer. This function is called for non-success cases.
3156 *
3157 * Returns void
3158 *
3159 ******************************************************************************/
l2cu_reject_credit_based_conn_req(tL2C_LCB * p_lcb,uint8_t rem_id,uint8_t num_of_channels,tL2CAP_LE_RESULT_CODE result)3160 void l2cu_reject_credit_based_conn_req(tL2C_LCB* p_lcb, uint8_t rem_id, uint8_t num_of_channels,
3161 tL2CAP_LE_RESULT_CODE result) {
3162 BT_HDR* p_buf;
3163 uint8_t* p;
3164 uint8_t rsp_len = L2CAP_CMD_CREDIT_BASED_CONN_RES_MIN_LEN + sizeof(uint16_t) * num_of_channels;
3165
3166 p_buf = l2cu_build_header(p_lcb, rsp_len, L2CAP_CMD_CREDIT_BASED_CONN_RES, rem_id);
3167 if (p_buf == NULL) {
3168 log::warn("l2cu_reject_credit_based_conn_req - no buffer");
3169 return;
3170 }
3171
3172 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3173 L2CAP_CMD_OVERHEAD;
3174
3175 memset(p, 0, rsp_len);
3176 UINT16_TO_STREAM(p, L2CAP_CREDIT_BASED_MIN_MTU); /* dummy MTU to satisy PTS */
3177 UINT16_TO_STREAM(p, L2CAP_CREDIT_BASED_MIN_MPS); /* dummy MPS to satisy PTS*/
3178 UINT16_TO_STREAM(p, 1); /* dummy initial credit to satisy PTS */
3179 uint16_t result_u16 = static_cast<uint16_t>(result);
3180 UINT16_TO_STREAM(p, result_u16);
3181
3182 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
3183 }
3184
3185 /*******************************************************************************
3186 *
3187 * Function l2cu_send_peer_credit_based_conn_res
3188 *
3189 * Description Build and send an L2CAP "Credit based connection res"
3190 * message to the peer. This function is called in case of
3191 * success.
3192 *
3193 * Returns void
3194 *
3195 ******************************************************************************/
l2cu_send_peer_credit_based_conn_res(tL2C_CCB * p_ccb,std::vector<uint16_t> & accepted_cids,tL2CAP_LE_RESULT_CODE result)3196 void l2cu_send_peer_credit_based_conn_res(tL2C_CCB* p_ccb, std::vector<uint16_t>& accepted_cids,
3197 tL2CAP_LE_RESULT_CODE result) {
3198 BT_HDR* p_buf;
3199 uint8_t* p;
3200
3201 log::verbose("");
3202 uint8_t rsp_len = L2CAP_CMD_CREDIT_BASED_CONN_RES_MIN_LEN +
3203 p_ccb->p_lcb->pending_ecoc_conn_cnt * sizeof(uint16_t);
3204
3205 p_buf = l2cu_build_header(p_ccb->p_lcb, rsp_len, L2CAP_CMD_CREDIT_BASED_CONN_RES,
3206 p_ccb->remote_id);
3207 if (p_buf == NULL) {
3208 log::warn("no buffer");
3209 return;
3210 }
3211
3212 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3213 L2CAP_CMD_OVERHEAD;
3214
3215 memset(p, 0, rsp_len);
3216 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mtu); /* MTU */
3217 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mps); /* MPS */
3218 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.credits); /* initial credit */
3219
3220 if (result == tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK) {
3221 /* In case of success, we need to check if stack
3222 * did not have previous result stored e.g. when there was no
3223 * resources for allocation all the requrested channels,
3224 * before user indication.
3225 */
3226 result = static_cast<tL2CAP_LE_RESULT_CODE>(p_ccb->p_lcb->pending_l2cap_result);
3227 }
3228
3229 uint16_t result_u16 = static_cast<uint16_t>(result);
3230 UINT16_TO_STREAM(p, result_u16);
3231
3232 /* We need to keep order from the request.
3233 * if this vector contais 0 it means channel has been rejected by
3234 * the stack.
3235 * If there is valid cid, we need to verify if it is accepted by upper layer.
3236 */
3237 for (int i = 0; i < p_ccb->p_lcb->pending_ecoc_conn_cnt; i++) {
3238 uint16_t cid = p_ccb->p_lcb->pending_ecoc_connection_cids[i];
3239 if (cid == 0) {
3240 UINT16_TO_STREAM(p, 0);
3241 continue;
3242 }
3243 auto it = std::find(accepted_cids.begin(), accepted_cids.end(), cid);
3244 if (it != accepted_cids.end()) {
3245 UINT16_TO_STREAM(p, cid);
3246 } else {
3247 UINT16_TO_STREAM(p, 0);
3248 }
3249 }
3250
3251 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
3252 }
3253
3254 /*******************************************************************************
3255 *
3256 * Function l2cu_reject_ble_connection
3257 *
3258 * Description Build and send an L2CAP "Credit based connection res"
3259 * message to the peer. This function is called for non-success
3260 * cases.
3261 *
3262 * Returns void
3263 *
3264 ******************************************************************************/
l2cu_reject_ble_connection(tL2C_CCB * p_ccb,uint8_t rem_id,tL2CAP_LE_RESULT_CODE result)3265 void l2cu_reject_ble_connection(tL2C_CCB* p_ccb, uint8_t rem_id, tL2CAP_LE_RESULT_CODE result) {
3266 if (p_ccb->ecoc) {
3267 l2cu_reject_credit_based_conn_req(p_ccb->p_lcb, rem_id, p_ccb->p_lcb->pending_ecoc_conn_cnt,
3268 result);
3269 } else {
3270 l2cu_reject_ble_coc_connection(p_ccb->p_lcb, rem_id, result);
3271 }
3272 }
3273
3274 /*******************************************************************************
3275 *
3276 * Function l2cu_send_ble_reconfig_rsp
3277 *
3278 * Description Build and send an L2CAP "Credit based reconfig res"
3279 * message to the peer. This function is called for non-success
3280 * cases.
3281 *
3282 * Returns void
3283 *
3284 ******************************************************************************/
3285
l2cu_send_ble_reconfig_rsp(tL2C_LCB * p_lcb,uint8_t rem_id,tL2CAP_RECONFIG_RESULT result)3286 void l2cu_send_ble_reconfig_rsp(tL2C_LCB* p_lcb, uint8_t rem_id, tL2CAP_RECONFIG_RESULT result) {
3287 BT_HDR* p_buf;
3288 uint8_t* p;
3289
3290 log::verbose("l2cu_send_ble_reconfig_rsp result:{}", l2cap_reconfig_result_text(result));
3291
3292 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_CREDIT_BASED_RECONFIG_RES_LEN,
3293 L2CAP_CMD_CREDIT_BASED_RECONFIG_RES, rem_id);
3294 if (p_buf == NULL) {
3295 log::warn("l2cu_send_peer_ble_credit_based_conn_res - no buffer");
3296 return;
3297 }
3298
3299 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3300 L2CAP_CMD_OVERHEAD;
3301
3302 memset(p, 0, L2CAP_CMD_CREDIT_BASED_RECONFIG_RES_LEN);
3303 UINT16_TO_STREAM(p, static_cast<uint16_t>(result));
3304
3305 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
3306 }
3307
3308 /*******************************************************************************
3309 *
3310 * Function l2cu_send_peer_ble_credit_based_conn_res
3311 *
3312 * Description Build and send an L2CAP "Credit based connection res"
3313 * message to the peer. This function is called in case of
3314 * success.
3315 *
3316 * Returns void
3317 *
3318 ******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB * p_ccb,tL2CAP_LE_RESULT_CODE result)3319 void l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB* p_ccb, tL2CAP_LE_RESULT_CODE result) {
3320 BT_HDR* p_buf;
3321 uint8_t* p;
3322
3323 log::verbose("l2cu_send_peer_ble_credit_based_conn_res");
3324 p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
3325 L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id);
3326 if (p_buf == NULL) {
3327 log::warn("l2cu_send_peer_ble_credit_based_conn_res - no buffer");
3328 return;
3329 }
3330
3331 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3332 L2CAP_CMD_OVERHEAD;
3333
3334 log::verbose("local cid: {}, mtu: {}, mps: {}, initial credits: {}", p_ccb->local_cid,
3335 p_ccb->local_conn_cfg.mtu, p_ccb->local_conn_cfg.mps, p_ccb->local_conn_cfg.credits);
3336
3337 UINT16_TO_STREAM(p, p_ccb->local_cid); /* Local CID */
3338 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mtu); /* MTU */
3339 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mps); /* MPS */
3340 UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.credits); /* initial credit */
3341 uint16_t result_u16 = static_cast<uint16_t>(result);
3342 UINT16_TO_STREAM(p, result_u16);
3343
3344 l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf);
3345 }
3346
3347 /*******************************************************************************
3348 *
3349 * Function l2cu_send_peer_ble_flow_control_credit
3350 *
3351 * Description Build and send a BLE packet to give credits to peer device
3352 * for LE connection oriented L2CAP channel.
3353 *
3354 * Returns void
3355 *
3356 ******************************************************************************/
l2cu_send_peer_ble_flow_control_credit(tL2C_CCB * p_ccb,uint16_t credit_value)3357 void l2cu_send_peer_ble_flow_control_credit(tL2C_CCB* p_ccb, uint16_t credit_value) {
3358 BT_HDR* p_buf;
3359 uint8_t* p;
3360 tL2C_LCB* p_lcb = NULL;
3361
3362 if (!p_ccb) {
3363 return;
3364 }
3365 p_lcb = p_ccb->p_lcb;
3366
3367 /* Create an identifier for this packet */
3368 p_ccb->p_lcb->signal_id++;
3369 l2cu_adj_id(p_ccb->p_lcb);
3370
3371 p_ccb->local_id = p_ccb->p_lcb->signal_id;
3372
3373 p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN,
3374 L2CAP_CMD_BLE_FLOW_CTRL_CREDIT, p_lcb->signal_id);
3375 if (p_buf == NULL) {
3376 log::warn("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
3377 return;
3378 }
3379
3380 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3381 L2CAP_CMD_OVERHEAD;
3382
3383 UINT16_TO_STREAM(p, p_ccb->local_cid);
3384 UINT16_TO_STREAM(p, credit_value);
3385
3386 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
3387 }
3388
3389 /*******************************************************************************
3390 *
3391 * Function l2cu_send_peer_ble_credit_based_conn_req
3392 *
3393 * Description Build and send a BLE packet to disconnect LE connection
3394 * oriented L2CAP channel.
3395 *
3396 * Returns void
3397 *
3398 ******************************************************************************/
l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB * p_ccb)3399 void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB* p_ccb) {
3400 BT_HDR* p_buf;
3401 uint8_t* p;
3402 tL2C_LCB* p_lcb = NULL;
3403 log::verbose("");
3404
3405 if (!p_ccb) {
3406 return;
3407 }
3408 p_lcb = p_ccb->p_lcb;
3409
3410 /* Create an identifier for this packet */
3411 p_ccb->p_lcb->signal_id++;
3412 l2cu_adj_id(p_ccb->p_lcb);
3413
3414 p_ccb->local_id = p_ccb->p_lcb->signal_id;
3415 p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_lcb->signal_id);
3416 if (p_buf == NULL) {
3417 log::warn("l2cu_send_peer_ble_credit_based_disconn_req - no buffer");
3418 return;
3419 }
3420
3421 p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
3422 L2CAP_CMD_OVERHEAD;
3423
3424 UINT16_TO_STREAM(p, p_ccb->remote_cid);
3425 UINT16_TO_STREAM(p, p_ccb->local_cid);
3426
3427 l2c_link_check_send_pkts(p_lcb, 0, p_buf);
3428 }
3429
3430 /*******************************************************************************
3431 * Functions used by both Full and Light Stack
3432 ******************************************************************************/
3433
3434 /*******************************************************************************
3435 *
3436 * Function l2cu_find_lcb_by_handle
3437 *
3438 * Description Look through all active LCBs for a match based on the
3439 * HCI handle.
3440 *
3441 * Returns pointer to matched LCB, or NULL if no match
3442 *
3443 ******************************************************************************/
l2cu_find_lcb_by_handle(uint16_t handle)3444 tL2C_LCB* l2cu_find_lcb_by_handle(uint16_t handle) {
3445 int xx;
3446 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
3447
3448 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
3449 if ((p_lcb->in_use) && (p_lcb->Handle() == handle)) {
3450 return p_lcb;
3451 }
3452 }
3453
3454 /* If here, no match found */
3455 return NULL;
3456 }
3457
3458 /*******************************************************************************
3459 *
3460 * Function l2cu_find_ccb_by_cid
3461 *
3462 * Description Look through all active CCBs on a link for a match based
3463 * on the local CID. If passed the link pointer is NULL, all
3464 * active links are searched.
3465 *
3466 * Returns pointer to matched CCB, or NULL if no match
3467 *
3468 ******************************************************************************/
l2cu_find_ccb_by_cid(tL2C_LCB * p_lcb,uint16_t local_cid)3469 tL2C_CCB* l2cu_find_ccb_by_cid(tL2C_LCB* p_lcb, uint16_t local_cid) {
3470 tL2C_CCB* p_ccb = NULL;
3471 if (local_cid >= L2CAP_BASE_APPL_CID) {
3472 /* find the associated CCB by "index" */
3473 local_cid -= L2CAP_BASE_APPL_CID;
3474
3475 if (local_cid >= MAX_L2CAP_CHANNELS) {
3476 return NULL;
3477 }
3478
3479 p_ccb = l2cb.ccb_pool + local_cid;
3480
3481 /* make sure the CCB is in use */
3482 if (!p_ccb->in_use) {
3483 p_ccb = NULL;
3484 } else if (p_lcb && p_lcb != p_ccb->p_lcb) {
3485 /* make sure it's for the same LCB */
3486 p_ccb = NULL;
3487 }
3488 }
3489 return p_ccb;
3490 }
3491
l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO * p_cbi)3492 void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
3493 if (p_cbi->cb != NULL) {
3494 p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu);
3495 }
3496 }
3497
3498 /******************************************************************************
3499 *
3500 * Function l2cu_set_acl_hci_header
3501 *
3502 * Description Set HCI handle for ACL packet
3503 *
3504 * Returns None
3505 *
3506 ******************************************************************************/
l2cu_set_acl_hci_header(BT_HDR * p_buf,tL2C_CCB * p_ccb)3507 void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb) {
3508 uint8_t* p;
3509
3510 /* Set the pointer to the beginning of the data minus 4 bytes for the packet
3511 * header */
3512 p = (uint8_t*)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
3513
3514 if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3515 UINT16_TO_STREAM(
3516 p, p_ccb->p_lcb->Handle() | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT));
3517
3518 uint16_t acl_data_size =
3519 bluetooth::shim::GetController()->GetLeBufferSize().le_data_packet_length_;
3520 /* The HCI transport will segment the buffers. */
3521 if (p_buf->len > acl_data_size) {
3522 UINT16_TO_STREAM(p, acl_data_size);
3523 } else {
3524 UINT16_TO_STREAM(p, p_buf->len);
3525 }
3526 } else {
3527 if (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) &&
3528 (p_ccb->is_flushable)) {
3529 UINT16_TO_STREAM(p, p_ccb->p_lcb->Handle() | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3530 } else {
3531 UINT16_TO_STREAM(p, p_ccb->p_lcb->Handle() | l2cb.non_flushable_pbf);
3532 }
3533
3534 uint16_t acl_data_size = bluetooth::shim::GetController()->GetAclPacketLength();
3535 /* The HCI transport will segment the buffers. */
3536 if (p_buf->len > acl_data_size) {
3537 UINT16_TO_STREAM(p, acl_data_size);
3538 } else {
3539 UINT16_TO_STREAM(p, p_buf->len);
3540 }
3541 }
3542 p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
3543 p_buf->len += HCI_DATA_PREAMBLE_SIZE;
3544 }
3545
send_congestion_status_to_all_clients(tL2C_CCB * p_ccb,bool status)3546 static void send_congestion_status_to_all_clients(tL2C_CCB* p_ccb, bool status) {
3547 p_ccb->cong_sent = status;
3548
3549 if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) {
3550 log::verbose(
3551 "L2CAP - Calling CongestionStatus_Cb ({}), CID: 0x{:04x} "
3552 "xmit_hold_q.count: {} buff_quota: {}",
3553 status, p_ccb->local_cid, fixed_queue_length(p_ccb->xmit_hold_q), p_ccb->buff_quota);
3554
3555 /* Prevent recursive calling */
3556 if (status == false) {
3557 l2cb.is_cong_cback_context = true;
3558 }
3559
3560 (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, status);
3561
3562 if (status == false) {
3563 l2cb.is_cong_cback_context = false;
3564 }
3565 } else {
3566 for (uint8_t xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
3567 if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb) {
3568 if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL) {
3569 (*l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, status);
3570 }
3571 break;
3572 }
3573 }
3574 }
3575 }
3576
3577 /* check if any change in congestion status */
l2cu_check_channel_congestion(tL2C_CCB * p_ccb)3578 void l2cu_check_channel_congestion(tL2C_CCB* p_ccb) {
3579 /* If the CCB queue limit is subject to a quota, check for congestion if this
3580 * channel has outgoing traffic */
3581 if (p_ccb->buff_quota == 0) {
3582 return;
3583 }
3584
3585 size_t q_count = fixed_queue_length(p_ccb->xmit_hold_q);
3586
3587 if (p_ccb->cong_sent) {
3588 /* if channel was congested, but is not congested now, tell the app */
3589 if (q_count <= (p_ccb->buff_quota / 2)) {
3590 send_congestion_status_to_all_clients(p_ccb, false);
3591 }
3592 } else {
3593 /* if channel was not congested, but is congested now, tell the app */
3594 if (q_count > p_ccb->buff_quota) {
3595 send_congestion_status_to_all_clients(p_ccb, true);
3596 }
3597 }
3598 }
3599
3600 /*******************************************************************************
3601 *
3602 * Function l2cu_is_ccb_active
3603 *
3604 * Description Check if Channel Control Block is in use or released
3605 *
3606 * Returns bool - true if Channel Control Block is in use
3607 * false if p_ccb is null or is released.
3608 *
3609 ******************************************************************************/
l2cu_is_ccb_active(tL2C_CCB * p_ccb)3610 bool l2cu_is_ccb_active(tL2C_CCB* p_ccb) { return p_ccb && p_ccb->in_use; }
3611
3612 /*******************************************************************************
3613 *
3614 * Function le_result_to_l2c_conn
3615 *
3616 * Description Connvert an LE result code to L2C connection code.
3617 *
3618 * Returns The converted L2C connection code.
3619 *
3620 ******************************************************************************/
le_result_to_l2c_conn(tL2CAP_LE_RESULT_CODE result)3621 tL2CAP_CONN le_result_to_l2c_conn(tL2CAP_LE_RESULT_CODE result) {
3622 tL2CAP_LE_RESULT_CODE code = (tL2CAP_LE_RESULT_CODE)result;
3623 switch (code) {
3624 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_CONN_OK:
3625 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_NO_PSM:
3626 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_NO_RESOURCES:
3627 return static_cast<tL2CAP_CONN>(code);
3628 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION:
3629 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION:
3630 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE:
3631 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP:
3632 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INVALID_SOURCE_CID:
3633 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED:
3634 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS:
3635 case tL2CAP_LE_RESULT_CODE::L2CAP_LE_RESULT_INVALID_PARAMETERS:
3636 return static_cast<tL2CAP_CONN>(L2CAP_CONN_LE_MASK | static_cast<uint16_t>(code));
3637 default:
3638 if (static_cast<uint16_t>(result) < L2CAP_CONN_LE_MASK) {
3639 return static_cast<tL2CAP_CONN>(L2CAP_CONN_LE_MASK | static_cast<uint16_t>(code));
3640 }
3641 return tL2CAP_CONN::L2CAP_CONN_OTHER_ERROR;
3642 }
3643 }
3644
3645 /*******************************************************************************
3646 *
3647 * Function l2c_acl_flush
3648 *
3649 * Description API functions call this function to flush data.
3650 *
3651 ******************************************************************************/
l2c_acl_flush(uint16_t handle)3652 void l2c_acl_flush(uint16_t handle) { btm_acl_flush(handle); }
3653