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