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