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