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