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