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