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