• 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 <= 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 = 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     page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
2249     page_scan_mode = p_inq_info->results.page_scan_mode;
2250     clock_offset = (uint16_t)(p_inq_info->results.clock_offset);
2251   } else {
2252     /* No info known. Use default settings */
2253     page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
2254     page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
2255 
2256     clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
2257   }
2258 
2259   btsnd_hcic_create_conn(
2260       p_lcb->remote_bd_addr, (HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1 |
2261                               HCI_PKT_TYPES_MASK_DM3 | HCI_PKT_TYPES_MASK_DH3 |
2262                               HCI_PKT_TYPES_MASK_DM5 | HCI_PKT_TYPES_MASK_DH5),
2263       page_scan_rep_mode, page_scan_mode, clock_offset, allow_switch);
2264 
2265   btm_acl_update_busy_level(BTM_BLI_PAGE_EVT);
2266 
2267   alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS,
2268                      l2c_lcb_timer_timeout, p_lcb);
2269 
2270   return (true);
2271 }
2272 
2273 /*******************************************************************************
2274  *
2275  * Function         l2cu_find_lcb_by_state
2276  *
2277  * Description      Look through all active LCBs for a match based on the
2278  *                  LCB state.
2279  *
2280  * Returns          pointer to first matched LCB, or NULL if no match
2281  *
2282  ******************************************************************************/
l2cu_find_lcb_by_state(tL2C_LINK_STATE state)2283 tL2C_LCB* l2cu_find_lcb_by_state(tL2C_LINK_STATE state) {
2284   uint16_t i;
2285   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
2286 
2287   for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
2288     if ((p_lcb->in_use) && (p_lcb->link_state == state)) {
2289       return (p_lcb);
2290     }
2291   }
2292 
2293   /* If here, no match found */
2294   return (NULL);
2295 }
2296 
2297 /*******************************************************************************
2298  *
2299  * Function         l2cu_lcb_disconnecting
2300  *
2301  * Description      On each active lcb, check if the lcb is in disconnecting
2302  *                  state, or if there are no ccb's on the lcb (implying
2303                     idle timeout is running), or if last ccb on the link
2304                     is in disconnecting state.
2305  *
2306  * Returns          true if any of above conditions met, false otherwise
2307  *
2308  ******************************************************************************/
l2cu_lcb_disconnecting(void)2309 bool l2cu_lcb_disconnecting(void) {
2310   tL2C_LCB* p_lcb;
2311   tL2C_CCB* p_ccb;
2312   uint16_t i;
2313   bool status = false;
2314 
2315   p_lcb = &l2cb.lcb_pool[0];
2316 
2317   for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
2318     if (p_lcb->in_use) {
2319       /* no ccbs on lcb, or lcb is in disconnecting state */
2320       if ((!p_lcb->ccb_queue.p_first_ccb) ||
2321           (p_lcb->link_state == LST_DISCONNECTING)) {
2322         status = true;
2323         break;
2324       }
2325       /* only one ccb left on lcb */
2326       else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb) {
2327         p_ccb = p_lcb->ccb_queue.p_first_ccb;
2328 
2329         if ((p_ccb->in_use) &&
2330             ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
2331              (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) {
2332           status = true;
2333           break;
2334         }
2335       }
2336     }
2337   }
2338   return status;
2339 }
2340 
2341 /*******************************************************************************
2342  *
2343  * Function         l2cu_set_acl_priority
2344  *
2345  * Description      Sets the transmission priority for a channel.
2346  *                  (For initial implementation only two values are valid.
2347  *                  L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
2348  *
2349  * Returns          true if a valid channel, else false
2350  *
2351  ******************************************************************************/
2352 
l2cu_set_acl_priority(const RawAddress & bd_addr,uint8_t priority,bool reset_after_rs)2353 bool l2cu_set_acl_priority(const RawAddress& bd_addr, uint8_t priority,
2354                            bool reset_after_rs) {
2355   tL2C_LCB* p_lcb;
2356   uint8_t* pp;
2357   uint8_t command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2358   uint8_t vs_param;
2359 
2360   APPL_TRACE_EVENT("SET ACL PRIORITY %d", priority);
2361 
2362   /* Find the link control block for the acl channel */
2363   p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
2364   if (p_lcb == NULL) {
2365     L2CAP_TRACE_WARNING("L2CAP - no LCB for L2CA_SetAclPriority");
2366     return (false);
2367   }
2368 
2369   if (BTM_IS_BRCM_CONTROLLER()) {
2370     /* Called from above L2CAP through API; send VSC if changed */
2371     if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
2372         /* Called because of a master/slave role switch; if high resend VSC */
2373         (reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) {
2374       pp = command;
2375 
2376       vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH
2377                                                    : HCI_BRCM_ACL_PRIORITY_LOW;
2378 
2379       UINT16_TO_STREAM(pp, p_lcb->handle);
2380       UINT8_TO_STREAM(pp, vs_param);
2381 
2382       BTM_VendorSpecificCommand(HCI_BRCM_SET_ACL_PRIORITY,
2383                                 HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command,
2384                                 NULL);
2385     }
2386   }
2387 
2388   /* Adjust lmp buffer allocation for this channel if priority changed */
2389   if (p_lcb->acl_priority != priority) {
2390     p_lcb->acl_priority = priority;
2391     l2c_link_adjust_allocation();
2392   }
2393   return (true);
2394 }
2395 
2396 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2397 /******************************************************************************
2398  *
2399  * Function         l2cu_set_non_flushable_pbf
2400  *
2401  * Description      set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
2402  *
2403  * Returns          void
2404  *
2405  ******************************************************************************/
l2cu_set_non_flushable_pbf(bool is_supported)2406 void l2cu_set_non_flushable_pbf(bool is_supported) {
2407   if (is_supported)
2408     l2cb.non_flushable_pbf =
2409         (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
2410   else
2411     l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
2412 }
2413 #endif
2414 
2415 /*******************************************************************************
2416  *
2417  * Function         l2cu_resubmit_pending_sec_req
2418  *
2419  * Description      This function is called when required security procedures
2420  *                  are completed and any pending requests can be re-submitted.
2421  *
2422  * Returns          void
2423  *
2424  ******************************************************************************/
l2cu_resubmit_pending_sec_req(const RawAddress * p_bda)2425 void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda) {
2426   tL2C_LCB* p_lcb;
2427   tL2C_CCB* p_ccb;
2428   tL2C_CCB* p_next_ccb;
2429   int xx;
2430 
2431   L2CAP_TRACE_DEBUG("l2cu_resubmit_pending_sec_req  p_bda: 0x%08x", p_bda);
2432 
2433   /* If we are called with a BDA, only resubmit for that BDA */
2434   if (p_bda) {
2435     p_lcb = l2cu_find_lcb_by_bd_addr(*p_bda, BT_TRANSPORT_BR_EDR);
2436 
2437     /* If we don't have one, this is an error */
2438     if (p_lcb) {
2439       /* For all channels, send the event through their FSMs */
2440       for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2441         p_next_ccb = p_ccb->p_next_ccb;
2442         l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2443       }
2444     } else {
2445       L2CAP_TRACE_WARNING("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
2446     }
2447   } else {
2448     /* No BDA pasesed in, so check all links */
2449     for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS;
2450          xx++, p_lcb++) {
2451       if (p_lcb->in_use) {
2452         /* For all channels, send the event through their FSMs */
2453         for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2454           p_next_ccb = p_ccb->p_next_ccb;
2455           l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2456         }
2457       }
2458     }
2459   }
2460 }
2461 
2462 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
2463 /*******************************************************************************
2464  *
2465  * Function         l2cu_set_info_rsp_mask
2466  *
2467  * Description      This function allows the script wrapper to change the
2468  *                  info resp mask for conformance testing.
2469  *
2470  * Returns          pointer to CCB, or NULL if none
2471  *
2472  ******************************************************************************/
l2cu_set_info_rsp_mask(uint32_t mask)2473 void l2cu_set_info_rsp_mask(uint32_t mask) { l2cb.test_info_resp = mask; }
2474 #endif /* L2CAP_CONFORMANCE_TESTING */
2475 
2476 /*******************************************************************************
2477  *
2478  * Function         l2cu_adjust_out_mps
2479  *
2480  * Description      Sets our MPS based on current controller capabilities
2481  *
2482  * Returns          void
2483  *
2484  ******************************************************************************/
l2cu_adjust_out_mps(tL2C_CCB * p_ccb)2485 void l2cu_adjust_out_mps(tL2C_CCB* p_ccb) {
2486   uint16_t packet_size;
2487 
2488   /* on the tx side MTU is selected based on packet size of the controller */
2489   packet_size = btm_get_max_packet_size(p_ccb->p_lcb->remote_bd_addr);
2490 
2491   if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD +
2492                       L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) {
2493     /* something is very wrong */
2494     L2CAP_TRACE_ERROR(
2495         "l2cu_adjust_out_mps bad packet size: %u  will use MPS: %u",
2496         packet_size, p_ccb->peer_cfg.fcr.mps);
2497     p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2498   } else {
2499     packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD +
2500                     L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
2501 
2502     /* We try to negotiate MTU that each packet can be split into whole
2503     number of max packets.  For example if link is 1.2 max packet size is 339
2504     bytes.
2505     At first calculate how many whole packets it is.  MAX L2CAP is 1691 + 4
2506     overhead.
2507     1695, that will be 5 Dh5 packets.  Now maximum L2CAP packet is
2508     5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
2509 
2510     For EDR 2.0 packet size is 1027.  So we better send RFCOMM packet as 1 3DH5
2511     packet
2512     1 * 1027 = 1027.  Minus 4 bytes L2CAP header 1023.  */
2513     if (p_ccb->peer_cfg.fcr.mps >= packet_size)
2514       p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
2515     else
2516       p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2517 
2518     L2CAP_TRACE_DEBUG(
2519         "l2cu_adjust_out_mps use %d   Based on peer_cfg.fcr.mps: %u  "
2520         "packet_size: %u",
2521         p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
2522   }
2523 }
2524 
2525 /*******************************************************************************
2526  *
2527  * Function         l2cu_initialize_fixed_ccb
2528  *
2529  * Description      Initialize a fixed channel's CCB
2530  *
2531  * Returns          true or false
2532  *
2533  ******************************************************************************/
l2cu_initialize_fixed_ccb(tL2C_LCB * p_lcb,uint16_t fixed_cid,tL2CAP_FCR_OPTS * p_fcr)2534 bool l2cu_initialize_fixed_ccb(tL2C_LCB* p_lcb, uint16_t fixed_cid,
2535                                tL2CAP_FCR_OPTS* p_fcr) {
2536 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2537   tL2C_CCB* p_ccb;
2538 
2539   /* If we already have a CCB, then simply return */
2540   p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
2541   if ((p_ccb != NULL) && p_ccb->in_use) {
2542     /*
2543      * NOTE: The "in_use" check is needed to ignore leftover entries
2544      * that have been already released by l2cu_release_ccb().
2545      */
2546     return (true);
2547   }
2548 
2549   p_ccb = l2cu_allocate_ccb(NULL, 0);
2550   if (p_ccb == NULL) return (false);
2551 
2552   alarm_cancel(p_lcb->l2c_lcb_timer);
2553 
2554   /* Set CID for the connection */
2555   p_ccb->local_cid = fixed_cid;
2556   p_ccb->remote_cid = fixed_cid;
2557 
2558   p_ccb->is_flushable = false;
2559 
2560   if (p_fcr) {
2561     /* Set the FCR parameters. For now, we will use default pools */
2562     p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr;
2563 
2564     p_ccb->ertm_info.fcr_rx_buf_size = L2CAP_FCR_RX_BUF_SIZE;
2565     p_ccb->ertm_info.fcr_tx_buf_size = L2CAP_FCR_TX_BUF_SIZE;
2566     p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE;
2567     p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
2568 
2569     p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3;
2570   }
2571 
2572   /* Link ccb to lcb and lcb to ccb */
2573   p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
2574   p_ccb->p_lcb = p_lcb;
2575 
2576   /* There is no configuration, so if the link is up, the channel is up */
2577   if (p_lcb->link_state == LST_CONNECTED) p_ccb->chnl_state = CST_OPEN;
2578 
2579   /* Set the default idle timeout value to use */
2580   p_ccb->fixed_chnl_idle_tout =
2581       l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
2582 #endif
2583   return (true);
2584 }
2585 
2586 /*******************************************************************************
2587  *
2588  * Function         l2cu_no_dynamic_ccbs
2589  *
2590  * Description      Handles the case when there are no more dynamic CCBs. If
2591  *                  there are any fixed CCBs, start the longest of the fixed CCB
2592  *                  timeouts, otherwise start the default link idle timeout or
2593  *                  disconnect.
2594  *
2595  * Returns          void
2596  *
2597  ******************************************************************************/
l2cu_no_dynamic_ccbs(tL2C_LCB * p_lcb)2598 void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) {
2599   tBTM_STATUS rc;
2600   uint64_t timeout_ms = p_lcb->idle_timeout * 1000;
2601   bool start_timeout = true;
2602 
2603 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2604   int xx;
2605 
2606   for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2607     if ((p_lcb->p_fixed_ccbs[xx] != NULL) &&
2608         (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000 > timeout_ms)) {
2609 
2610       if (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout == L2CAP_NO_IDLE_TIMEOUT) {
2611          L2CAP_TRACE_DEBUG("%s NO IDLE timeout set for fixed cid 0x%04x", __func__,
2612             p_lcb->p_fixed_ccbs[xx]->local_cid);
2613          start_timeout = false;
2614       }
2615       timeout_ms = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000;
2616     }
2617   }
2618 #endif
2619 
2620   /* If the link is pairing, do not mess with the timeouts */
2621   if (p_lcb->is_bonding) return;
2622 
2623   if (timeout_ms == 0) {
2624     L2CAP_TRACE_DEBUG(
2625         "l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
2626 
2627     rc = btm_sec_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
2628     if (rc == BTM_CMD_STARTED) {
2629       l2cu_process_fixed_disc_cback(p_lcb);
2630       p_lcb->link_state = LST_DISCONNECTING;
2631       timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
2632     } else if (rc == BTM_SUCCESS) {
2633       l2cu_process_fixed_disc_cback(p_lcb);
2634       /* BTM SEC will make sure that link is release (probably after pairing is
2635        * done) */
2636       p_lcb->link_state = LST_DISCONNECTING;
2637       start_timeout = false;
2638     } else if (p_lcb->is_bonding) {
2639       btsnd_hcic_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
2640       l2cu_process_fixed_disc_cback(p_lcb);
2641       p_lcb->link_state = LST_DISCONNECTING;
2642       timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
2643     } else {
2644       /* probably no buffer to send disconnect */
2645       timeout_ms = BT_1SEC_TIMEOUT_MS;
2646     }
2647   }
2648 
2649   if (start_timeout) {
2650     L2CAP_TRACE_DEBUG("%s starting IDLE timeout: %d ms", __func__, timeout_ms);
2651     alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout,
2652                        p_lcb);
2653   } else {
2654     alarm_cancel(p_lcb->l2c_lcb_timer);
2655   }
2656 }
2657 
2658 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2659 /*******************************************************************************
2660  *
2661  * Function         l2cu_process_fixed_chnl_resp
2662  *
2663  * Description      handle a fixed channel response (or lack thereof)
2664  *                  if the link failed, or a fixed channel response was
2665  *                  not received, the bitfield is all zeros.
2666  *
2667  ******************************************************************************/
l2cu_process_fixed_chnl_resp(tL2C_LCB * p_lcb)2668 void l2cu_process_fixed_chnl_resp(tL2C_LCB* p_lcb) {
2669   if (p_lcb->transport == BT_TRANSPORT_BR_EDR) {
2670     /* ignore all not assigned BR/EDR channels */
2671     p_lcb->peer_chnl_mask[0] &=
2672         (L2CAP_FIXED_CHNL_SIG_BIT | L2CAP_FIXED_CHNL_CNCTLESS_BIT |
2673          L2CAP_FIXED_CHNL_SMP_BR_BIT);
2674   } else
2675     p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask;
2676 
2677   /* Tell all registered fixed channels about the connection */
2678   for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2679     uint16_t channel_id = xx + L2CAP_FIRST_FIXED_CHNL;
2680 
2681     /* See BT Spec Ver 5.0 | Vol 3, Part A 2.1 table 2.1 and 2.2 */
2682 
2683     /* skip sending LE fix channel callbacks on BR/EDR links */
2684     if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
2685         channel_id >= L2CAP_ATT_CID && channel_id <= L2CAP_SMP_CID)
2686       continue;
2687 
2688     /* skip sending BR fix channel callbacks on LE links */
2689     if (p_lcb->transport == BT_TRANSPORT_LE && channel_id == L2CAP_SMP_BR_CID)
2690       continue;
2691 
2692     if (!l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb) continue;
2693 
2694     if (p_lcb->peer_chnl_mask[(channel_id) / 8] & (1 << ((channel_id) % 8))) {
2695       if (p_lcb->p_fixed_ccbs[xx])
2696         p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
2697       (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2698           channel_id, p_lcb->remote_bd_addr, true, 0, p_lcb->transport);
2699     } else {
2700       (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2701           channel_id, p_lcb->remote_bd_addr, false, p_lcb->disc_reason,
2702           p_lcb->transport);
2703 
2704       if (p_lcb->p_fixed_ccbs[xx]) {
2705         l2cu_release_ccb(p_lcb->p_fixed_ccbs[xx]);
2706         p_lcb->p_fixed_ccbs[xx] = NULL;
2707       }
2708     }
2709   }
2710 }
2711 #endif
2712 
2713 /*******************************************************************************
2714  *
2715  * Function         l2cu_process_fixed_disc_cback
2716  *
2717  * Description      send l2cap fixed channel disconnection callback to the
2718  *                  application
2719  *
2720  * Returns          void
2721  *
2722  ******************************************************************************/
l2cu_process_fixed_disc_cback(tL2C_LCB * p_lcb)2723 void l2cu_process_fixed_disc_cback(tL2C_LCB* p_lcb) {
2724 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2725 
2726   /* Select peer channels mask to use depending on transport */
2727   uint8_t peer_channel_mask = p_lcb->peer_chnl_mask[0];
2728 
2729   // For LE, reset the stored peer channel mask
2730   if (p_lcb->transport == BT_TRANSPORT_LE) p_lcb->peer_chnl_mask[0] = 0;
2731 
2732   for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2733     if (p_lcb->p_fixed_ccbs[xx]) {
2734       if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) {
2735         tL2C_CCB* p_l2c_chnl_ctrl_block;
2736         p_l2c_chnl_ctrl_block = p_lcb->p_fixed_ccbs[xx];
2737         p_lcb->p_fixed_ccbs[xx] = NULL;
2738         l2cu_release_ccb(p_l2c_chnl_ctrl_block);
2739         (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2740             xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false,
2741             p_lcb->disc_reason, p_lcb->transport);
2742       }
2743     } else if ((peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) &&
2744                (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL))
2745       (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2746           xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false,
2747           p_lcb->disc_reason, p_lcb->transport);
2748   }
2749 #endif
2750 }
2751 
2752 /*******************************************************************************
2753  *
2754  * Function         l2cu_send_peer_ble_par_req
2755  *
2756  * Description      Build and send a BLE parameter update request message
2757  *                  to the peer.
2758  *
2759  * Returns          void
2760  *
2761  ******************************************************************************/
l2cu_send_peer_ble_par_req(tL2C_LCB * p_lcb,uint16_t min_int,uint16_t max_int,uint16_t latency,uint16_t timeout)2762 void l2cu_send_peer_ble_par_req(tL2C_LCB* p_lcb, uint16_t min_int,
2763                                 uint16_t max_int, uint16_t latency,
2764                                 uint16_t timeout) {
2765   BT_HDR* p_buf;
2766   uint8_t* p;
2767 
2768   /* Create an identifier for this packet */
2769   p_lcb->id++;
2770   l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
2771 
2772   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN,
2773                             L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id);
2774   if (p_buf == NULL) {
2775     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_par_req - no buffer");
2776     return;
2777   }
2778 
2779   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2780       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2781 
2782   UINT16_TO_STREAM(p, min_int);
2783   UINT16_TO_STREAM(p, max_int);
2784   UINT16_TO_STREAM(p, latency);
2785   UINT16_TO_STREAM(p, timeout);
2786 
2787   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2788 }
2789 
2790 /*******************************************************************************
2791  *
2792  * Function         l2cu_send_peer_ble_par_rsp
2793  *
2794  * Description      Build and send a BLE parameter update response message
2795  *                  to the peer.
2796  *
2797  * Returns          void
2798  *
2799  ******************************************************************************/
l2cu_send_peer_ble_par_rsp(tL2C_LCB * p_lcb,uint16_t reason,uint8_t rem_id)2800 void l2cu_send_peer_ble_par_rsp(tL2C_LCB* p_lcb, uint16_t reason,
2801                                 uint8_t rem_id) {
2802   BT_HDR* p_buf;
2803   uint8_t* p;
2804 
2805   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN,
2806                             L2CAP_CMD_BLE_UPDATE_RSP, rem_id);
2807   if (p_buf == NULL) {
2808     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_par_rsp - no buffer");
2809     return;
2810   }
2811 
2812   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2813       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2814 
2815   UINT16_TO_STREAM(p, reason);
2816 
2817   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2818 }
2819 
2820 /*******************************************************************************
2821  *
2822  * Function         l2cu_send_peer_ble_credit_based_conn_req
2823  *
2824  * Description      Build and send a BLE packet to establish LE connection
2825  *                  oriented L2CAP channel.
2826  *
2827  * Returns          void
2828  *
2829  ******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB * p_ccb)2830 void l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB* p_ccb) {
2831   BT_HDR* p_buf;
2832   uint8_t* p;
2833   tL2C_LCB* p_lcb = NULL;
2834   uint16_t mtu;
2835   uint16_t mps;
2836   uint16_t initial_credit;
2837 
2838   if (!p_ccb) return;
2839   p_lcb = p_ccb->p_lcb;
2840 
2841   /* Create an identifier for this packet */
2842   p_ccb->p_lcb->id++;
2843   l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
2844 
2845   p_ccb->local_id = p_ccb->p_lcb->id;
2846 
2847   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN,
2848                             L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ, p_lcb->id);
2849   if (p_buf == NULL) {
2850     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
2851     return;
2852   }
2853 
2854   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2855       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2856 
2857   mtu = p_ccb->local_conn_cfg.mtu;
2858   mps = p_ccb->local_conn_cfg.mps;
2859   initial_credit = p_ccb->local_conn_cfg.credits;
2860 
2861   L2CAP_TRACE_DEBUG(
2862       "l2cu_send_peer_ble_credit_based_conn_req PSM:0x%04x local_cid:%d\
2863                 mtu:%d mps:%d initial_credit:%d",
2864       p_ccb->p_rcb->real_psm, p_ccb->local_cid, mtu, mps, initial_credit);
2865 
2866   UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm);
2867   UINT16_TO_STREAM(p, p_ccb->local_cid);
2868   UINT16_TO_STREAM(p, mtu);
2869   UINT16_TO_STREAM(p, mps);
2870   UINT16_TO_STREAM(p, initial_credit);
2871 
2872   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2873 }
2874 
2875 /*******************************************************************************
2876  *
2877  * Function         l2cu_reject_ble_connection
2878  *
2879  * Description      Build and send an L2CAP "Credit based connection res"
2880  *                  message to the peer. This function is called for non-success
2881  *                  cases.
2882  *
2883  * Returns          void
2884  *
2885  ******************************************************************************/
l2cu_reject_ble_connection(tL2C_LCB * p_lcb,uint8_t rem_id,uint16_t result)2886 void l2cu_reject_ble_connection(tL2C_LCB* p_lcb, uint8_t rem_id,
2887                                 uint16_t result) {
2888   BT_HDR* p_buf;
2889   uint8_t* p;
2890 
2891   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
2892                             L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, rem_id);
2893   if (p_buf == NULL) {
2894     L2CAP_TRACE_WARNING("l2cu_reject_ble_connection - no buffer");
2895     return;
2896   }
2897 
2898   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2899       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2900 
2901   UINT16_TO_STREAM(p, 0); /* Local CID of 0   */
2902   UINT16_TO_STREAM(p, 0); /* MTU */
2903   UINT16_TO_STREAM(p, 0); /* MPS */
2904   UINT16_TO_STREAM(p, 0); /* initial credit */
2905   UINT16_TO_STREAM(p, result);
2906 
2907   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2908 }
2909 
2910 /*******************************************************************************
2911  *
2912  * Function         l2cu_send_peer_ble_credit_based_conn_res
2913  *
2914  * Description      Build and send an L2CAP "Credit based connection res"
2915  *                  message to the peer. This function is called in case of
2916  *                  success.
2917  *
2918  * Returns          void
2919  *
2920  ******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB * p_ccb,uint16_t result)2921 void l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB* p_ccb,
2922                                               uint16_t result) {
2923   BT_HDR* p_buf;
2924   uint8_t* p;
2925 
2926   L2CAP_TRACE_DEBUG("l2cu_send_peer_ble_credit_based_conn_res");
2927   p_buf =
2928       l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
2929                         L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id);
2930   if (p_buf == NULL) {
2931     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_res - no buffer");
2932     return;
2933   }
2934 
2935   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2936       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2937 
2938   UINT16_TO_STREAM(p, p_ccb->local_cid);              /* Local CID */
2939   UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mtu);     /* MTU */
2940   UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mps);     /* MPS */
2941   UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.credits); /* initial credit */
2942   UINT16_TO_STREAM(p, result);
2943 
2944   l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf);
2945 }
2946 
2947 /*******************************************************************************
2948  *
2949  * Function         l2cu_send_peer_ble_flow_control_credit
2950  *
2951  * Description      Build and send a BLE packet to give credits to peer device
2952  *                  for LE connection oriented L2CAP channel.
2953  *
2954  * Returns          void
2955  *
2956  ******************************************************************************/
l2cu_send_peer_ble_flow_control_credit(tL2C_CCB * p_ccb,uint16_t credit_value)2957 void l2cu_send_peer_ble_flow_control_credit(tL2C_CCB* p_ccb,
2958                                             uint16_t credit_value) {
2959   BT_HDR* p_buf;
2960   uint8_t* p;
2961   tL2C_LCB* p_lcb = NULL;
2962 
2963   if (!p_ccb) return;
2964   p_lcb = p_ccb->p_lcb;
2965 
2966   /* Create an identifier for this packet */
2967   p_ccb->p_lcb->id++;
2968   l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
2969 
2970   p_ccb->local_id = p_ccb->p_lcb->id;
2971 
2972   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN,
2973                             L2CAP_CMD_BLE_FLOW_CTRL_CREDIT, p_lcb->id);
2974   if (p_buf == NULL) {
2975     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
2976     return;
2977   }
2978 
2979   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2980       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2981 
2982   UINT16_TO_STREAM(p, p_ccb->local_cid);
2983   UINT16_TO_STREAM(p, credit_value);
2984 
2985   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2986 }
2987 
2988 /*******************************************************************************
2989  *
2990  * Function         l2cu_send_peer_ble_credit_based_conn_req
2991  *
2992  * Description      Build and send a BLE packet to disconnect LE connection
2993  *                  oriented L2CAP channel.
2994  *
2995  * Returns          void
2996  *
2997  ******************************************************************************/
l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB * p_ccb)2998 void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB* p_ccb) {
2999   BT_HDR* p_buf;
3000   uint8_t* p;
3001   tL2C_LCB* p_lcb = NULL;
3002   L2CAP_TRACE_DEBUG("%s", __func__);
3003 
3004   if (!p_ccb) return;
3005   p_lcb = p_ccb->p_lcb;
3006 
3007   /* Create an identifier for this packet */
3008   p_ccb->p_lcb->id++;
3009   l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
3010 
3011   p_ccb->local_id = p_ccb->p_lcb->id;
3012   p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ,
3013                             p_lcb->id);
3014   if (p_buf == NULL) {
3015     L2CAP_TRACE_WARNING(
3016         "l2cu_send_peer_ble_credit_based_disconn_req - no buffer");
3017     return;
3018   }
3019 
3020   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3021       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3022 
3023   UINT16_TO_STREAM(p, p_ccb->remote_cid);
3024   UINT16_TO_STREAM(p, p_ccb->local_cid);
3025 
3026   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
3027 }
3028 
3029 /*******************************************************************************
3030  * Functions used by both Full and Light Stack
3031  ******************************************************************************/
3032 
3033 /*******************************************************************************
3034  *
3035  * Function         l2cu_find_lcb_by_handle
3036  *
3037  * Description      Look through all active LCBs for a match based on the
3038  *                  HCI handle.
3039  *
3040  * Returns          pointer to matched LCB, or NULL if no match
3041  *
3042  ******************************************************************************/
l2cu_find_lcb_by_handle(uint16_t handle)3043 tL2C_LCB* l2cu_find_lcb_by_handle(uint16_t handle) {
3044   int xx;
3045   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
3046 
3047   for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
3048     if ((p_lcb->in_use) && (p_lcb->handle == handle)) {
3049       return (p_lcb);
3050     }
3051   }
3052 
3053   /* If here, no match found */
3054   return (NULL);
3055 }
3056 
3057 /*******************************************************************************
3058  *
3059  * Function         l2cu_find_ccb_by_cid
3060  *
3061  * Description      Look through all active CCBs on a link for a match based
3062  *                  on the local CID. If passed the link pointer is NULL, all
3063  *                  active links are searched.
3064  *
3065  * Returns          pointer to matched CCB, or NULL if no match
3066  *
3067  ******************************************************************************/
l2cu_find_ccb_by_cid(tL2C_LCB * p_lcb,uint16_t local_cid)3068 tL2C_CCB* l2cu_find_ccb_by_cid(tL2C_LCB* p_lcb, uint16_t local_cid) {
3069   tL2C_CCB* p_ccb = NULL;
3070   if (local_cid >= L2CAP_BASE_APPL_CID) {
3071     /* find the associated CCB by "index" */
3072     local_cid -= L2CAP_BASE_APPL_CID;
3073 
3074     if (local_cid >= MAX_L2CAP_CHANNELS) return NULL;
3075 
3076     p_ccb = l2cb.ccb_pool + local_cid;
3077 
3078     /* make sure the CCB is in use */
3079     if (!p_ccb->in_use) {
3080       p_ccb = NULL;
3081     }
3082     /* make sure it's for the same LCB */
3083     else if (p_lcb && p_lcb != p_ccb->p_lcb) {
3084       p_ccb = NULL;
3085     }
3086   }
3087   return (p_ccb);
3088 }
3089 
3090 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3091 
3092 /******************************************************************************
3093  *
3094  * Function         l2cu_get_next_channel_in_rr
3095  *
3096  * Description      get the next channel to send on a link. It also adjusts the
3097  *                  CCB queue to do a basic priority and round-robin scheduling.
3098  *
3099  * Returns          pointer to CCB or NULL
3100  *
3101  ******************************************************************************/
l2cu_get_next_channel_in_rr(tL2C_LCB * p_lcb)3102 static tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) {
3103   tL2C_CCB* p_serve_ccb = NULL;
3104   tL2C_CCB* p_ccb;
3105 
3106   int i, j;
3107 
3108   /* scan all of priority until finding a channel to serve */
3109   for (i = 0; (i < L2CAP_NUM_CHNL_PRIORITY) && (!p_serve_ccb); i++) {
3110     /* scan all channel within serving priority group until finding a channel to
3111      * serve */
3112     for (j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb) && (!p_serve_ccb);
3113          j++) {
3114       /* scaning from next serving channel */
3115       p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
3116 
3117       if (!p_ccb) {
3118         L2CAP_TRACE_ERROR("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
3119         return NULL;
3120       }
3121 
3122       L2CAP_TRACE_DEBUG("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
3123                         p_ccb->ccb_priority, p_ccb->local_cid,
3124                         fixed_queue_length(p_ccb->xmit_hold_q));
3125 
3126       /* store the next serving channel */
3127       /* this channel is the last channel of its priority group */
3128       if ((p_ccb->p_next_ccb == NULL) ||
3129           (p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority)) {
3130         /* next serving channel is set to the first channel in the group */
3131         p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb =
3132             p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb;
3133       } else {
3134         /* next serving channel is set to the next channel in the group */
3135         p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
3136       }
3137 
3138       if (p_ccb->chnl_state != CST_OPEN) continue;
3139 
3140       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3141         L2CAP_TRACE_DEBUG("%s : Connection oriented channel", __func__);
3142         if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3143 
3144       } else {
3145         /* eL2CAP option in use */
3146         if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3147           if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) continue;
3148 
3149           if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
3150             if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3151 
3152             /* If in eRTM mode, check for window closure */
3153             if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
3154                 (l2c_fcr_is_flow_controlled(p_ccb)))
3155               continue;
3156           }
3157         } else {
3158           if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3159         }
3160       }
3161 
3162       /* found a channel to serve */
3163       p_serve_ccb = p_ccb;
3164       /* decrease quota of its priority group */
3165       p_lcb->rr_serv[p_lcb->rr_pri].quota--;
3166     }
3167 
3168     /* if there is no more quota of the priority group or no channel to have
3169      * data to send */
3170     if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0) || (!p_serve_ccb)) {
3171       /* serve next priority group */
3172       p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
3173       /* initialize its quota */
3174       p_lcb->rr_serv[p_lcb->rr_pri].quota =
3175           L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
3176     }
3177   }
3178 
3179   if (p_serve_ccb) {
3180     L2CAP_TRACE_DEBUG("RR service pri=%d, quota=%d, lcid=0x%04x",
3181                       p_serve_ccb->ccb_priority,
3182                       p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
3183                       p_serve_ccb->local_cid);
3184   }
3185 
3186   return p_serve_ccb;
3187 }
3188 
3189 #else  /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3190 
3191 /******************************************************************************
3192  *
3193  * Function         l2cu_get_next_channel
3194  *
3195  * Description      get the next channel to send on a link bassed on priority
3196  *                  scheduling.
3197  *
3198  * Returns          pointer to CCB or NULL
3199  *
3200  ******************************************************************************/
l2cu_get_next_channel(tL2C_LCB * p_lcb)3201 static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) {
3202   tL2C_CCB* p_ccb;
3203 
3204   /* Get the first CCB with data to send.
3205   */
3206   for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
3207     if (p_ccb->chnl_state != CST_OPEN) continue;
3208 
3209     if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) continue;
3210 
3211     if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) return p_ccb;
3212 
3213     if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3214 
3215     /* If in eRTM mode, check for window closure */
3216     if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
3217         (l2c_fcr_is_flow_controlled(p_ccb)))
3218       continue;
3219 
3220     /* If here, we found someone */
3221     return p_ccb;
3222   }
3223 
3224   return NULL;
3225 }
3226 #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3227 
l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO * p_cbi)3228 void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
3229   if (p_cbi->cb != NULL) p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu);
3230 }
3231 
3232 /******************************************************************************
3233  *
3234  * Function         l2cu_get_next_buffer_to_send
3235  *
3236  * Description      get the next buffer to send on a link. It also adjusts the
3237  *                  CCB queue to do a basic priority and round-robin scheduling.
3238  *
3239  * Returns          pointer to buffer or NULL
3240  *
3241  ******************************************************************************/
l2cu_get_next_buffer_to_send(tL2C_LCB * p_lcb,tL2C_TX_COMPLETE_CB_INFO * p_cbi)3242 BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb,
3243                                      tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
3244   tL2C_CCB* p_ccb;
3245   BT_HDR* p_buf;
3246 
3247 /* Highest priority are fixed channels */
3248 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3249   int xx;
3250 
3251   p_cbi->cb = NULL;
3252 
3253   for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
3254     p_ccb = p_lcb->p_fixed_ccbs[xx];
3255     if (p_ccb == NULL) continue;
3256 
3257     /* eL2CAP option in use */
3258     if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3259       if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) continue;
3260 
3261       /* No more checks needed if sending from the reatransmit queue */
3262       if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
3263         if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3264 
3265         /* If in eRTM mode, check for window closure */
3266         if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
3267             (l2c_fcr_is_flow_controlled(p_ccb)))
3268           continue;
3269       }
3270 
3271       p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0);
3272       if (p_buf != NULL) {
3273         l2cu_check_channel_congestion(p_ccb);
3274         l2cu_set_acl_hci_header(p_buf, p_ccb);
3275         return (p_buf);
3276       }
3277     } else {
3278       if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
3279         p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
3280         if (NULL == p_buf) {
3281           L2CAP_TRACE_ERROR("%s: No data to be sent", __func__);
3282           return (NULL);
3283         }
3284 
3285         /* Prepare callback info for TX completion */
3286         p_cbi->cb = l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb;
3287         p_cbi->local_cid = p_ccb->local_cid;
3288         p_cbi->num_sdu = 1;
3289 
3290         l2cu_check_channel_congestion(p_ccb);
3291         l2cu_set_acl_hci_header(p_buf, p_ccb);
3292         return (p_buf);
3293       }
3294     }
3295   }
3296 #endif
3297 
3298 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3299   /* get next serving channel in round-robin */
3300   p_ccb = l2cu_get_next_channel_in_rr(p_lcb);
3301 #else
3302   p_ccb = l2cu_get_next_channel(p_lcb);
3303 #endif
3304 
3305   /* Return if no buffer */
3306   if (p_ccb == NULL) return (NULL);
3307 
3308   if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3309     /* Check credits */
3310     if (p_ccb->peer_conn_cfg.credits == 0) {
3311       L2CAP_TRACE_DEBUG("%s No credits to send packets", __func__);
3312       return NULL;
3313     }
3314 
3315     bool last_piece_of_sdu = false;
3316     p_buf = l2c_lcc_get_next_xmit_sdu_seg(p_ccb, &last_piece_of_sdu);
3317     p_ccb->peer_conn_cfg.credits--;
3318 
3319     if (last_piece_of_sdu) {
3320       // TODO: send callback up the stack. Investigate setting p_cbi->cb to
3321       // notify after controller ack send.
3322     }
3323 
3324   } else {
3325     if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3326       p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0);
3327       if (p_buf == NULL) return (NULL);
3328     } else {
3329       p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
3330       if (NULL == p_buf) {
3331         L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send() #2: No data to be sent");
3332         return (NULL);
3333       }
3334     }
3335   }
3336 
3337   if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_TxComplete_Cb &&
3338       (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE))
3339     (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
3340 
3341   l2cu_check_channel_congestion(p_ccb);
3342 
3343   l2cu_set_acl_hci_header(p_buf, p_ccb);
3344 
3345   return (p_buf);
3346 }
3347 
3348 /******************************************************************************
3349  *
3350  * Function         l2cu_set_acl_hci_header
3351  *
3352  * Description      Set HCI handle for ACL packet
3353  *
3354  * Returns          None
3355  *
3356  ******************************************************************************/
l2cu_set_acl_hci_header(BT_HDR * p_buf,tL2C_CCB * p_ccb)3357 void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb) {
3358   uint8_t* p;
3359 
3360   /* Set the pointer to the beginning of the data minus 4 bytes for the packet
3361    * header */
3362   p = (uint8_t*)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
3363 
3364   if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3365     UINT16_TO_STREAM(p, p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE
3366                                                 << L2CAP_PKT_TYPE_SHIFT));
3367 
3368     uint16_t acl_data_size =
3369         controller_get_interface()->get_acl_data_size_ble();
3370     /* The HCI transport will segment the buffers. */
3371     if (p_buf->len > acl_data_size) {
3372       UINT16_TO_STREAM(p, acl_data_size);
3373     } else {
3374       UINT16_TO_STREAM(p, p_buf->len);
3375     }
3376   } else {
3377 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3378     if ((((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) ==
3379           L2CAP_FLUSHABLE_CH_BASED) &&
3380          (p_ccb->is_flushable)) ||
3381         ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) ==
3382          L2CAP_FLUSHABLE_PKT)) {
3383       UINT16_TO_STREAM(
3384           p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3385     } else {
3386       UINT16_TO_STREAM(p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
3387     }
3388 #else
3389     UINT16_TO_STREAM(
3390         p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3391 #endif
3392 
3393     uint16_t acl_data_size =
3394         controller_get_interface()->get_acl_data_size_classic();
3395     /* The HCI transport will segment the buffers. */
3396     if (p_buf->len > acl_data_size) {
3397       UINT16_TO_STREAM(p, acl_data_size);
3398     } else {
3399       UINT16_TO_STREAM(p, p_buf->len);
3400     }
3401   }
3402   p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
3403   p_buf->len += HCI_DATA_PREAMBLE_SIZE;
3404 }
3405 
send_congestion_status_to_all_clients(tL2C_CCB * p_ccb,bool status)3406 static void send_congestion_status_to_all_clients(tL2C_CCB* p_ccb,
3407                                                   bool status) {
3408   p_ccb->cong_sent = status;
3409 
3410   if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) {
3411     L2CAP_TRACE_DEBUG(
3412         "L2CAP - Calling CongestionStatus_Cb (%d), CID: 0x%04x "
3413         "xmit_hold_q.count: %u  buff_quota: %u",
3414         status, p_ccb->local_cid, fixed_queue_length(p_ccb->xmit_hold_q),
3415         p_ccb->buff_quota);
3416 
3417     /* Prevent recursive calling */
3418     if (status == false) l2cb.is_cong_cback_context = true;
3419 
3420     (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, status);
3421 
3422     if (status == false) l2cb.is_cong_cback_context = false;
3423   }
3424 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3425   else {
3426     for (uint8_t xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
3427       if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb) {
3428         if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3429           (*l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr,
3430                                                    status);
3431         break;
3432       }
3433     }
3434   }
3435 #endif
3436 }
3437 
3438 /* check if any change in congestion status */
l2cu_check_channel_congestion(tL2C_CCB * p_ccb)3439 void l2cu_check_channel_congestion(tL2C_CCB* p_ccb) {
3440   /* If the CCB queue limit is subject to a quota, check for congestion if this
3441    * channel has outgoing traffic */
3442   if (p_ccb->buff_quota == 0) return;
3443 
3444   size_t q_count = fixed_queue_length(p_ccb->xmit_hold_q);
3445 
3446   if (p_ccb->cong_sent) {
3447     /* if channel was congested, but is not congested now, tell the app */
3448     if (q_count <= (p_ccb->buff_quota / 2))
3449       send_congestion_status_to_all_clients(p_ccb, false);
3450   } else {
3451     /* if channel was not congested, but is congested now, tell the app */
3452     if (q_count > p_ccb->buff_quota)
3453       send_congestion_status_to_all_clients(p_ccb, true);
3454   }
3455 }
3456 
3457 /*******************************************************************************
3458  *
3459  * Function         l2cu_is_ccb_active
3460  *
3461  * Description      Check if Channel Control Block is in use or released
3462  *
3463  * Returns          bool    - true if Channel Control Block is in use
3464  *                            false if p_ccb is null or is released.
3465  *
3466  ******************************************************************************/
l2cu_is_ccb_active(tL2C_CCB * p_ccb)3467 bool l2cu_is_ccb_active(tL2C_CCB* p_ccb) { return (p_ccb && p_ccb->in_use); }
3468