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   const controller_t* controller = controller_get_interface();
751 
752 /* Put in HCI header - handle + pkt boundary */
753 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
754   if (controller->supports_non_flushable_pb()) {
755     UINT16_TO_STREAM(p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE
756                                                  << L2CAP_PKT_TYPE_SHIFT)));
757   } else
758 #endif
759   {
760     UINT16_TO_STREAM(
761         p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
762   }
763 
764   /* Remember the HCI header length position, and save space for it */
765   p_hci_len = p;
766   p += 2;
767 
768   /* Put in L2CAP packet header */
769   UINT16_TO_STREAM(p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
770   UINT16_TO_STREAM(p, L2CAP_SIGNALLING_CID);
771 
772   /* Put in L2CAP command header */
773   UINT8_TO_STREAM(p, L2CAP_CMD_CONFIG_RSP);
774   UINT8_TO_STREAM(p, p_ccb->remote_id);
775 
776   UINT16_TO_STREAM(p, L2CAP_CONFIG_RSP_LEN + rej_len);
777 
778   UINT16_TO_STREAM(p, p_ccb->remote_cid);
779   UINT16_TO_STREAM(p, 0); /* Flags = 0 (no continuation) */
780   UINT16_TO_STREAM(p, L2CAP_CFG_UNKNOWN_OPTIONS);
781 
782   buf_space = rej_len;
783 
784   /* Now, put the rejected options */
785   p_data_end = p_data + data_len;
786   while (p_data < p_data_end) {
787     cfg_code = *p_data;
788     cfg_len = *(p_data + 1);
789 
790     switch (cfg_code & 0x7F) {
791       /* skip known options */
792       case L2CAP_CFG_TYPE_MTU:
793       case L2CAP_CFG_TYPE_FLUSH_TOUT:
794       case L2CAP_CFG_TYPE_QOS:
795       case L2CAP_CFG_TYPE_FCR:
796       case L2CAP_CFG_TYPE_FCS:
797       case L2CAP_CFG_TYPE_EXT_FLOW:
798         p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
799         break;
800 
801       /* unknown options; copy into rsp if not hints */
802       default:
803         /* sanity check option length */
804         if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len) {
805           if ((cfg_code & 0x80) == 0) {
806             if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD)) {
807               memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
808               p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
809               buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
810             } else {
811               L2CAP_TRACE_WARNING("L2CAP - cfg_rej exceeds allocated buffer");
812               p_data = p_data_end; /* force loop exit */
813               break;
814             }
815           }
816           p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
817         }
818         /* bad length; force loop exit */
819         else {
820           p_data = p_data_end;
821         }
822         break;
823     }
824   }
825 
826   len = (uint16_t)(p - p_hci_len - 2);
827   UINT16_TO_STREAM(p_hci_len, len);
828 
829   p_buf->len = len + 4;
830 
831   L2CAP_TRACE_DEBUG("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d", len,
832                     (L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len));
833 
834   l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf);
835 }
836 
837 /*******************************************************************************
838  *
839  * Function         l2cu_send_peer_disc_req
840  *
841  * Description      Build and send an L2CAP "disconnect request" message
842  *                  to the peer.
843  *
844  * Returns          void
845  *
846  ******************************************************************************/
l2cu_send_peer_disc_req(tL2C_CCB * p_ccb)847 void l2cu_send_peer_disc_req(tL2C_CCB* p_ccb) {
848   BT_HDR *p_buf, *p_buf2;
849   uint8_t* p;
850 
851   if ((!p_ccb) || (p_ccb->p_lcb == NULL)) {
852     L2CAP_TRACE_ERROR("%s L2CAP - ccb or lcb invalid", __func__);
853     return;
854   }
855 
856   /* Create an identifier for this packet */
857   p_ccb->p_lcb->id++;
858   l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
859 
860   p_ccb->local_id = p_ccb->p_lcb->id;
861 
862   p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN,
863                             L2CAP_CMD_DISC_REQ, p_ccb->local_id);
864   if (p_buf == NULL) {
865     L2CAP_TRACE_WARNING("L2CAP - no buffer for disc_req");
866     return;
867   }
868 
869   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
870       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
871 
872   UINT16_TO_STREAM(p, p_ccb->remote_cid);
873   UINT16_TO_STREAM(p, p_ccb->local_cid);
874 
875   /* Move all queued data packets to the LCB. In FCR mode, assume the higher
876      layer checks that all buffers are sent before disconnecting.
877   */
878   if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) {
879     while ((p_buf2 = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q)) !=
880            NULL) {
881       l2cu_set_acl_hci_header(p_buf2, p_ccb);
882       l2c_link_check_send_pkts(p_ccb->p_lcb, p_ccb, p_buf2);
883     }
884   }
885 
886   l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf);
887 }
888 
889 /*******************************************************************************
890  *
891  * Function         l2cu_send_peer_disc_rsp
892  *
893  * Description      Build and send an L2CAP "disconnect response" message
894  *                  to the peer.
895  *
896  *                  This function is passed the parameters for the disconnect
897  *                  response instead of the CCB address, as it may be called
898  *                  to send a disconnect response when there is no CCB.
899  *
900  * Returns          void
901  *
902  ******************************************************************************/
l2cu_send_peer_disc_rsp(tL2C_LCB * p_lcb,uint8_t remote_id,uint16_t local_cid,uint16_t remote_cid)903 void l2cu_send_peer_disc_rsp(tL2C_LCB* p_lcb, uint8_t remote_id,
904                              uint16_t local_cid, uint16_t remote_cid) {
905   BT_HDR* p_buf;
906   uint8_t* p;
907 
908   p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP,
909                             remote_id);
910   if (p_buf == NULL) {
911     L2CAP_TRACE_WARNING("L2CAP - no buffer for disc_rsp");
912     return;
913   }
914 
915   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
916       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
917 
918   UINT16_TO_STREAM(p, local_cid);
919   UINT16_TO_STREAM(p, remote_cid);
920 
921   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
922 }
923 
924 /*******************************************************************************
925  *
926  * Function         l2cu_send_peer_echo_req
927  *
928  * Description      Build and send an L2CAP "echo request" message
929  *                  to the peer. Note that we do not currently allow
930  *                  data in the echo request.
931  *
932  * Returns          void
933  *
934  ******************************************************************************/
l2cu_send_peer_echo_req(tL2C_LCB * p_lcb,uint8_t * p_data,uint16_t data_len)935 void l2cu_send_peer_echo_req(tL2C_LCB* p_lcb, uint8_t* p_data,
936                              uint16_t data_len) {
937   BT_HDR* p_buf;
938   uint8_t* p;
939 
940   p_lcb->id++;
941   l2cu_adj_id(p_lcb, L2CAP_ADJ_ZERO_ID); /* check for wrap to '0' */
942 
943   p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_ECHO_REQ_LEN + data_len),
944                             L2CAP_CMD_ECHO_REQ, p_lcb->id);
945   if (p_buf == NULL) {
946     L2CAP_TRACE_WARNING("L2CAP - no buffer for echo_req");
947     return;
948   }
949 
950   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
951       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
952 
953   if (data_len) {
954     ARRAY_TO_STREAM(p, p_data, data_len);
955   }
956 
957   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
958 }
959 
960 /*******************************************************************************
961  *
962  * Function         l2cu_send_peer_echo_rsp
963  *
964  * Description      Build and send an L2CAP "echo response" message
965  *                  to the peer.
966  *
967  * Returns          void
968  *
969  ******************************************************************************/
l2cu_send_peer_echo_rsp(tL2C_LCB * p_lcb,uint8_t id,uint8_t * p_data,uint16_t data_len)970 void l2cu_send_peer_echo_rsp(tL2C_LCB* p_lcb, uint8_t id, uint8_t* p_data,
971                              uint16_t data_len) {
972   BT_HDR* p_buf;
973   uint8_t* p;
974   uint16_t maxlen;
975   /* Filter out duplicate IDs or if available buffers are low (intruder
976    * checking) */
977   if (!id || id == p_lcb->cur_echo_id) {
978     /* Dump this request since it is illegal */
979     L2CAP_TRACE_WARNING("L2CAP ignoring duplicate echo request (%d)", id);
980     return;
981   } else
982     p_lcb->cur_echo_id = id;
983 
984   uint16_t acl_data_size =
985       controller_get_interface()->get_acl_data_size_classic();
986   uint16_t acl_packet_size =
987       controller_get_interface()->get_acl_packet_size_classic();
988   /* Don't return data if it does not fit in ACL and L2CAP MTU */
989   maxlen = (L2CAP_CMD_BUF_SIZE > acl_packet_size)
990                ? acl_data_size
991                : (uint16_t)L2CAP_CMD_BUF_SIZE;
992   maxlen -=
993       (uint16_t)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
994                  L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN);
995 
996   if (data_len > maxlen) data_len = 0;
997 
998   p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_ECHO_RSP_LEN + data_len),
999                             L2CAP_CMD_ECHO_RSP, id);
1000   if (p_buf == NULL) {
1001     L2CAP_TRACE_WARNING("L2CAP - no buffer for echo_rsp");
1002     return;
1003   }
1004 
1005   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
1006       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1007 
1008   if (data_len) {
1009     ARRAY_TO_STREAM(p, p_data, data_len);
1010   }
1011 
1012   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
1013 }
1014 
1015 /*******************************************************************************
1016  *
1017  * Function         l2cu_send_peer_info_req
1018  *
1019  * Description      Build and send an L2CAP "info request" message
1020  *                  to the peer.
1021  * Returns          void
1022  *
1023  ******************************************************************************/
l2cu_send_peer_info_req(tL2C_LCB * p_lcb,uint16_t info_type)1024 void l2cu_send_peer_info_req(tL2C_LCB* p_lcb, uint16_t info_type) {
1025   BT_HDR* p_buf;
1026   uint8_t* p;
1027 
1028   /* check for wrap and/or BRCM ID */
1029   p_lcb->id++;
1030   l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
1031 
1032   p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->id);
1033   if (p_buf == NULL) {
1034     L2CAP_TRACE_WARNING("L2CAP - no buffer for info_req");
1035     return;
1036   }
1037 
1038   L2CAP_TRACE_EVENT("l2cu_send_peer_info_req: type 0x%04x", info_type);
1039 
1040   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
1041       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1042 
1043   UINT16_TO_STREAM(p, info_type);
1044 
1045   p_lcb->w4_info_rsp = true;
1046   alarm_set_on_mloop(p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
1047                      l2c_info_resp_timer_timeout, p_lcb);
1048 
1049   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
1050 }
1051 
1052 /*******************************************************************************
1053  *
1054  * Function         l2cu_send_peer_info_rsp
1055  *
1056  * Description      Build and send an L2CAP "info response" message
1057  *                  to the peer.
1058  *
1059  * Returns          void
1060  *
1061  ******************************************************************************/
l2cu_send_peer_info_rsp(tL2C_LCB * p_lcb,uint8_t remote_id,uint16_t info_type)1062 void l2cu_send_peer_info_rsp(tL2C_LCB* p_lcb, uint8_t remote_id,
1063                              uint16_t info_type) {
1064   BT_HDR* p_buf;
1065   uint8_t* p;
1066   uint16_t len = L2CAP_INFO_RSP_LEN;
1067 
1068 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1069   if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1070       (l2cb.test_info_resp &
1071        (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1072         L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
1073         L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
1074         L2CAP_EXTFEA_UCD_RECEPTION)))
1075 #else
1076   if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1077       (L2CAP_EXTFEA_SUPPORTED_MASK &
1078        (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1079         L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_FIXED_CHNLS |
1080         L2CAP_EXTFEA_UCD_RECEPTION)) != 0)
1081 #endif
1082   {
1083     len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE;
1084   } else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) {
1085     len += L2CAP_FIXED_CHNL_ARRAY_SIZE;
1086   } else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) {
1087     len += L2CAP_CONNLESS_MTU_INFO_SIZE;
1088   }
1089 
1090   p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id);
1091   if (p_buf == NULL) {
1092     L2CAP_TRACE_WARNING("L2CAP - no buffer for info_rsp");
1093     return;
1094   }
1095 
1096   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
1097       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1098 
1099   UINT16_TO_STREAM(p, info_type);
1100 
1101 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1102   if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1103       (l2cb.test_info_resp &
1104        (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1105         L2CAP_EXTFEA_UCD_RECEPTION)))
1106 #else
1107   if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) &&
1108       (L2CAP_EXTFEA_SUPPORTED_MASK &
1109        (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1110         L2CAP_EXTFEA_UCD_RECEPTION)) != 0)
1111 #endif
1112   {
1113     UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1114     if (p_lcb->transport == BT_TRANSPORT_LE) {
1115       /* optional data are not added for now */
1116       UINT32_TO_STREAM(p, L2CAP_BLE_EXTFEA_MASK);
1117     } else {
1118 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1119       UINT32_TO_STREAM(p, l2cb.test_info_resp);
1120 #else
1121 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1122       UINT32_TO_STREAM(p,
1123                        L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS);
1124 #else
1125       UINT32_TO_STREAM(p, L2CAP_EXTFEA_SUPPORTED_MASK);
1126 #endif
1127 #endif
1128     }
1129   } else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) {
1130     UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1131     memset(p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE);
1132 
1133     p[0] = L2CAP_FIXED_CHNL_SIG_BIT;
1134 
1135     if (L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION)
1136       p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT;
1137 
1138 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1139     {
1140       int xx;
1141 
1142       for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
1143         /* Skip fixed channels not used on BR/EDR-ACL link */
1144         if ((xx >= L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL) &&
1145             (xx <= L2CAP_SMP_CID - L2CAP_FIRST_FIXED_CHNL))
1146           continue;
1147 
1148         if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
1149           p[(xx + L2CAP_FIRST_FIXED_CHNL) / 8] |=
1150               1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8);
1151       }
1152     }
1153 #endif
1154   } else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) {
1155     UINT16_TO_STREAM(p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1156     UINT16_TO_STREAM(p, L2CAP_MTU_SIZE);
1157   } else {
1158     UINT16_TO_STREAM(
1159         p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED); /* 'not supported' */
1160   }
1161 
1162   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
1163 }
1164 
1165 /******************************************************************************
1166  *
1167  * Function         l2cu_enqueue_ccb
1168  *
1169  * Description      queue CCB by priority. The first CCB is highest priority and
1170  *                  is served at first. The CCB is queued to an LLCB or an LCB.
1171  *
1172  * Returns          None
1173  *
1174  ******************************************************************************/
l2cu_enqueue_ccb(tL2C_CCB * p_ccb)1175 void l2cu_enqueue_ccb(tL2C_CCB* p_ccb) {
1176   tL2C_CCB* p_ccb1;
1177   tL2C_CCB_Q* p_q = NULL;
1178 
1179   /* Find out which queue the channel is on
1180   */
1181   if (p_ccb->p_lcb != NULL) p_q = &p_ccb->p_lcb->ccb_queue;
1182 
1183   if ((!p_ccb->in_use) || (p_q == NULL)) {
1184     L2CAP_TRACE_ERROR("%s: CID: 0x%04x ERROR in_use: %u  p_lcb: %p", __func__,
1185                       p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb);
1186     return;
1187   }
1188 
1189   L2CAP_TRACE_DEBUG("l2cu_enqueue_ccb CID: 0x%04x  priority: %d",
1190                     p_ccb->local_cid, p_ccb->ccb_priority);
1191 
1192   /* If the queue is empty, we go at the front */
1193   if (!p_q->p_first_ccb) {
1194     p_q->p_first_ccb = p_q->p_last_ccb = p_ccb;
1195     p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1196   } else {
1197     p_ccb1 = p_q->p_first_ccb;
1198 
1199     while (p_ccb1 != NULL) {
1200       /* Insert new ccb at the end of the same priority. Lower number, higher
1201        * priority */
1202       if (p_ccb->ccb_priority < p_ccb1->ccb_priority) {
1203         /* Are we at the head of the queue ? */
1204         if (p_ccb1 == p_q->p_first_ccb)
1205           p_q->p_first_ccb = p_ccb;
1206         else
1207           p_ccb1->p_prev_ccb->p_next_ccb = p_ccb;
1208 
1209         p_ccb->p_next_ccb = p_ccb1;
1210         p_ccb->p_prev_ccb = p_ccb1->p_prev_ccb;
1211         p_ccb1->p_prev_ccb = p_ccb;
1212         break;
1213       }
1214 
1215       p_ccb1 = p_ccb1->p_next_ccb;
1216     }
1217 
1218     /* If we are lower then anyone in the list, we go at the end */
1219     if (!p_ccb1) {
1220       /* add new ccb at the end of the list */
1221       p_q->p_last_ccb->p_next_ccb = p_ccb;
1222 
1223       p_ccb->p_next_ccb = NULL;
1224       p_ccb->p_prev_ccb = p_q->p_last_ccb;
1225       p_q->p_last_ccb = p_ccb;
1226     }
1227   }
1228 
1229 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1230   /* Adding CCB into round robin service table of its LCB */
1231   if (p_ccb->p_lcb != NULL) {
1232     /* if this is the first channel in this priority group */
1233     if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0) {
1234       /* Set the first channel to this CCB */
1235       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1236       /* Set the next serving channel in this group to this CCB */
1237       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1238       /* Initialize quota of this priority group based on its priority */
1239       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota =
1240           L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1241     }
1242     /* increase number of channels in this group */
1243     p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++;
1244   }
1245 #endif
1246 }
1247 
1248 /******************************************************************************
1249  *
1250  * Function         l2cu_dequeue_ccb
1251  *
1252  * Description      dequeue CCB from a queue
1253  *
1254  * Returns          -
1255  *
1256  ******************************************************************************/
l2cu_dequeue_ccb(tL2C_CCB * p_ccb)1257 void l2cu_dequeue_ccb(tL2C_CCB* p_ccb) {
1258   tL2C_CCB_Q* p_q = NULL;
1259 
1260   L2CAP_TRACE_DEBUG("l2cu_dequeue_ccb  CID: 0x%04x", p_ccb->local_cid);
1261 
1262   /* Find out which queue the channel is on
1263   */
1264   if (p_ccb->p_lcb != NULL) p_q = &p_ccb->p_lcb->ccb_queue;
1265 
1266   if ((!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL)) {
1267     L2CAP_TRACE_ERROR(
1268         "l2cu_dequeue_ccb  CID: 0x%04x ERROR in_use: %u  p_lcb: 0x%08x  p_q: "
1269         "0x%08x  p_q->p_first_ccb: 0x%08x",
1270         p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q,
1271         p_q ? p_q->p_first_ccb : 0);
1272     return;
1273   }
1274 
1275 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1276   /* Removing CCB from round robin service table of its LCB */
1277   if (p_ccb->p_lcb != NULL) {
1278     /* decrease number of channels in this priority group */
1279     p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--;
1280 
1281     /* if it was the last channel in the priority group */
1282     if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0) {
1283       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1284       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1285     } else {
1286       /* if it is the first channel of this group */
1287       if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb) {
1288         p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb =
1289             p_ccb->p_next_ccb;
1290       }
1291       /* if it is the next serving channel of this group */
1292       if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb) {
1293         /* simply, start serving from the first channel */
1294         p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb =
1295             p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb;
1296       }
1297     }
1298   }
1299 #endif
1300 
1301   if (p_ccb == p_q->p_first_ccb) {
1302     /* We are removing the first in a queue */
1303     p_q->p_first_ccb = p_ccb->p_next_ccb;
1304 
1305     if (p_q->p_first_ccb)
1306       p_q->p_first_ccb->p_prev_ccb = NULL;
1307     else
1308       p_q->p_last_ccb = NULL;
1309   } else if (p_ccb == p_q->p_last_ccb) {
1310     /* We are removing the last in a queue */
1311     p_q->p_last_ccb = p_ccb->p_prev_ccb;
1312     p_q->p_last_ccb->p_next_ccb = NULL;
1313   } else {
1314     /* In the middle of a chain. */
1315     p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb;
1316     p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb;
1317   }
1318 
1319   p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1320 }
1321 
1322 /******************************************************************************
1323  *
1324  * Function         l2cu_change_pri_ccb
1325  *
1326  * Description
1327  *
1328  * Returns          -
1329  *
1330  ******************************************************************************/
l2cu_change_pri_ccb(tL2C_CCB * p_ccb,tL2CAP_CHNL_PRIORITY priority)1331 void l2cu_change_pri_ccb(tL2C_CCB* p_ccb, tL2CAP_CHNL_PRIORITY priority) {
1332   if (p_ccb->ccb_priority != priority) {
1333     /* If CCB is not the only guy on the queue */
1334     if ((p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL)) {
1335       L2CAP_TRACE_DEBUG("Update CCB list in logical link");
1336 
1337       /* Remove CCB from queue and re-queue it at new priority */
1338       l2cu_dequeue_ccb(p_ccb);
1339 
1340       p_ccb->ccb_priority = priority;
1341       l2cu_enqueue_ccb(p_ccb);
1342     }
1343 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1344     else {
1345       /* If CCB is the only guy on the queue, no need to re-enqueue */
1346       /* update only round robin service data */
1347       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0;
1348       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1349       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1350 
1351       p_ccb->ccb_priority = priority;
1352 
1353       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1354       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1355       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota =
1356           L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1357       p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1;
1358     }
1359 #endif
1360   }
1361 }
1362 
1363 /*******************************************************************************
1364  *
1365  * Function         l2cu_allocate_ccb
1366  *
1367  * Description      This function allocates a Channel Control Block and
1368  *                  attaches it to a link control block. The local CID
1369  *                  is also assigned.
1370  *
1371  * Returns          pointer to CCB, or NULL if none
1372  *
1373  ******************************************************************************/
l2cu_allocate_ccb(tL2C_LCB * p_lcb,uint16_t cid)1374 tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid) {
1375   tL2C_CCB* p_ccb;
1376   tL2C_CCB* p_prev;
1377 
1378   L2CAP_TRACE_DEBUG("l2cu_allocate_ccb: cid 0x%04x", cid);
1379 
1380   if (!l2cb.p_free_ccb_first) return (NULL);
1381 
1382   /* If a CID was passed in, use that, else take the first free one */
1383   if (cid == 0) {
1384     p_ccb = l2cb.p_free_ccb_first;
1385     l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1386   } else {
1387     p_prev = NULL;
1388 
1389     p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID];
1390 
1391     if (p_ccb == l2cb.p_free_ccb_first)
1392       l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1393     else {
1394       for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL;
1395            p_prev = p_prev->p_next_ccb) {
1396         if (p_prev->p_next_ccb == p_ccb) {
1397           p_prev->p_next_ccb = p_ccb->p_next_ccb;
1398 
1399           if (p_ccb == l2cb.p_free_ccb_last) l2cb.p_free_ccb_last = p_prev;
1400 
1401           break;
1402         }
1403       }
1404       if (p_prev == NULL) {
1405         L2CAP_TRACE_ERROR(
1406             "l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free "
1407             "list",
1408             cid);
1409         return NULL;
1410       }
1411     }
1412   }
1413 
1414   p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1415 
1416   p_ccb->in_use = true;
1417 
1418   /* Get a CID for the connection */
1419   p_ccb->local_cid = L2CAP_BASE_APPL_CID + (uint16_t)(p_ccb - l2cb.ccb_pool);
1420 
1421   p_ccb->p_lcb = p_lcb;
1422   p_ccb->p_rcb = NULL;
1423   p_ccb->should_free_rcb = false;
1424 
1425   /* Set priority then insert ccb into LCB queue (if we have an LCB) */
1426   p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW;
1427 
1428   if (p_lcb) l2cu_enqueue_ccb(p_ccb);
1429 
1430   /* clear what peer wants to configure */
1431   p_ccb->peer_cfg_bits = 0;
1432 
1433   /* Put in default values for configuration */
1434   memset(&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1435   memset(&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1436 
1437   /* Put in default values for local/peer configurations */
1438   p_ccb->our_cfg.flush_to = p_ccb->peer_cfg.flush_to = L2CAP_DEFAULT_FLUSH_TO;
1439   p_ccb->our_cfg.mtu = p_ccb->peer_cfg.mtu = L2CAP_DEFAULT_MTU;
1440   p_ccb->our_cfg.qos.service_type = p_ccb->peer_cfg.qos.service_type =
1441       L2CAP_DEFAULT_SERV_TYPE;
1442   p_ccb->our_cfg.qos.token_rate = p_ccb->peer_cfg.qos.token_rate =
1443       L2CAP_DEFAULT_TOKEN_RATE;
1444   p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size =
1445       L2CAP_DEFAULT_BUCKET_SIZE;
1446   p_ccb->our_cfg.qos.peak_bandwidth = p_ccb->peer_cfg.qos.peak_bandwidth =
1447       L2CAP_DEFAULT_PEAK_BANDWIDTH;
1448   p_ccb->our_cfg.qos.latency = p_ccb->peer_cfg.qos.latency =
1449       L2CAP_DEFAULT_LATENCY;
1450   p_ccb->our_cfg.qos.delay_variation = p_ccb->peer_cfg.qos.delay_variation =
1451       L2CAP_DEFAULT_DELAY;
1452 
1453   p_ccb->bypass_fcs = 0;
1454   memset(&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO));
1455   p_ccb->peer_cfg_already_rejected = false;
1456   p_ccb->fcr_cfg_tries = L2CAP_MAX_FCR_CFG_TRIES;
1457 
1458   alarm_free(p_ccb->fcrb.ack_timer);
1459   p_ccb->fcrb.ack_timer = alarm_new("l2c_fcrb.ack_timer");
1460 
1461   /*  CSP408639 Fix: When L2CAP send amp move channel request or receive
1462     * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
1463     * request -> Stop retrans/monitor timer -> Change channel state to
1464    * CST_AMP_MOVING. */
1465   alarm_free(p_ccb->fcrb.mon_retrans_timer);
1466   p_ccb->fcrb.mon_retrans_timer = alarm_new("l2c_fcrb.mon_retrans_timer");
1467 
1468   p_ccb->ertm_info.preferred_mode =
1469       L2CAP_FCR_BASIC_MODE; /* Default mode for channel is basic mode */
1470   p_ccb->ertm_info.allowed_modes =
1471       L2CAP_FCR_CHAN_OPT_BASIC; /* Default mode for channel is basic mode */
1472   p_ccb->ertm_info.fcr_rx_buf_size = L2CAP_FCR_RX_BUF_SIZE;
1473   p_ccb->ertm_info.fcr_tx_buf_size = L2CAP_FCR_TX_BUF_SIZE;
1474   p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE;
1475   p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
1476   p_ccb->max_rx_mtu = L2CAP_MTU_SIZE;
1477   p_ccb->tx_mps = L2CAP_FCR_TX_BUF_SIZE - 32;
1478 
1479   p_ccb->xmit_hold_q = fixed_queue_new(SIZE_MAX);
1480   p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(SIZE_MAX);
1481   p_ccb->fcrb.retrans_q = fixed_queue_new(SIZE_MAX);
1482   p_ccb->fcrb.waiting_for_ack_q = fixed_queue_new(SIZE_MAX);
1483 
1484   p_ccb->cong_sent = false;
1485   p_ccb->buff_quota = 2; /* This gets set after config */
1486 
1487   /* If CCB was reserved Config_Done can already have some value */
1488   if (cid == 0)
1489     p_ccb->config_done = 0;
1490   else {
1491     L2CAP_TRACE_DEBUG("l2cu_allocate_ccb: cid 0x%04x config_done:0x%x", cid,
1492                       p_ccb->config_done);
1493   }
1494 
1495   p_ccb->chnl_state = CST_CLOSED;
1496   p_ccb->flags = 0;
1497   p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1498   p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1499 
1500 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
1501   p_ccb->is_flushable = false;
1502 #endif
1503 
1504   alarm_free(p_ccb->l2c_ccb_timer);
1505   p_ccb->l2c_ccb_timer = alarm_new("l2c.l2c_ccb_timer");
1506 
1507   l2c_link_adjust_chnl_allocation();
1508 
1509   return (p_ccb);
1510 }
1511 
1512 /*******************************************************************************
1513  *
1514  * Function         l2cu_start_post_bond_timer
1515  *
1516  * Description      This function starts the ACL Link inactivity timer after
1517  *                  dedicated bonding
1518  *                  This timer can be longer than the normal link inactivity
1519  *                  timer for some platforms.
1520  *
1521  * Returns          bool  - true if idle timer started or disconnect initiated
1522  *                          false if there's one or more pending CCB's exist
1523  *
1524  ******************************************************************************/
l2cu_start_post_bond_timer(uint16_t handle)1525 bool l2cu_start_post_bond_timer(uint16_t handle) {
1526   tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
1527 
1528   if (!p_lcb) return (true);
1529 
1530   p_lcb->is_bonding = false;
1531 
1532   /* Only start timer if no control blocks allocated */
1533   if (p_lcb->ccb_queue.p_first_ccb != NULL) return (false);
1534 
1535   /* If no channels on the connection, start idle timeout */
1536   if ((p_lcb->link_state == LST_CONNECTED) ||
1537       (p_lcb->link_state == LST_CONNECTING) ||
1538       (p_lcb->link_state == LST_DISCONNECTING)) {
1539     uint64_t timeout_ms = L2CAP_BONDING_TIMEOUT * 1000;
1540 
1541     if (p_lcb->idle_timeout == 0) {
1542       btsnd_hcic_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
1543       p_lcb->link_state = LST_DISCONNECTING;
1544       timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
1545     }
1546     alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout,
1547                        p_lcb);
1548     return (true);
1549   }
1550 
1551   return (false);
1552 }
1553 
1554 /*******************************************************************************
1555  *
1556  * Function         l2cu_release_ccb
1557  *
1558  * Description      This function releases a Channel Control Block. The timer
1559  *                  is stopped, any attached buffers freed, and the CCB is
1560  *                  removed from the link control block.
1561  *
1562  * Returns          void
1563  *
1564  ******************************************************************************/
l2cu_release_ccb(tL2C_CCB * p_ccb)1565 void l2cu_release_ccb(tL2C_CCB* p_ccb) {
1566   tL2C_LCB* p_lcb = p_ccb->p_lcb;
1567   tL2C_RCB* p_rcb = p_ccb->p_rcb;
1568 
1569   L2CAP_TRACE_DEBUG("l2cu_release_ccb: cid 0x%04x  in_use: %u",
1570                     p_ccb->local_cid, p_ccb->in_use);
1571 
1572   /* If already released, could be race condition */
1573   if (!p_ccb->in_use) return;
1574 
1575   btsnoop_get_interface()->clear_l2cap_whitelist(
1576       p_lcb->handle, p_ccb->local_cid, p_ccb->remote_cid);
1577 
1578   if (p_rcb && (p_rcb->psm != p_rcb->real_psm)) {
1579     btm_sec_clr_service_by_psm(p_rcb->psm);
1580   }
1581 
1582   if (p_ccb->should_free_rcb) {
1583     osi_free(p_rcb);
1584     p_ccb->p_rcb = NULL;
1585     p_ccb->should_free_rcb = false;
1586   }
1587 
1588   btm_sec_clr_temp_auth_service(p_lcb->remote_bd_addr);
1589 
1590   /* Free the timer */
1591   alarm_free(p_ccb->l2c_ccb_timer);
1592   p_ccb->l2c_ccb_timer = NULL;
1593 
1594   fixed_queue_free(p_ccb->xmit_hold_q, osi_free);
1595   p_ccb->xmit_hold_q = NULL;
1596 
1597   l2c_fcr_cleanup(p_ccb);
1598 
1599   /* Channel may not be assigned to any LCB if it was just pre-reserved */
1600   if ((p_lcb) && ((p_ccb->local_cid >= L2CAP_BASE_APPL_CID))) {
1601     l2cu_dequeue_ccb(p_ccb);
1602 
1603     /* Delink the CCB from the LCB */
1604     p_ccb->p_lcb = NULL;
1605   }
1606 
1607   /* Put the CCB back on the free pool */
1608   if (!l2cb.p_free_ccb_first) {
1609     l2cb.p_free_ccb_first = p_ccb;
1610     l2cb.p_free_ccb_last = p_ccb;
1611     p_ccb->p_next_ccb = NULL;
1612     p_ccb->p_prev_ccb = NULL;
1613   } else {
1614     p_ccb->p_next_ccb = NULL;
1615     p_ccb->p_prev_ccb = l2cb.p_free_ccb_last;
1616     l2cb.p_free_ccb_last->p_next_ccb = p_ccb;
1617     l2cb.p_free_ccb_last = p_ccb;
1618   }
1619 
1620   /* Flag as not in use */
1621   p_ccb->in_use = false;
1622 
1623   /* If no channels on the connection, start idle timeout */
1624   if ((p_lcb) && p_lcb->in_use) {
1625     if (p_lcb->link_state == LST_CONNECTED) {
1626       if (!p_lcb->ccb_queue.p_first_ccb) {
1627         // Closing a security channel on LE device should not start connection
1628         // timeout
1629         if (p_lcb->transport == BT_TRANSPORT_LE &&
1630             p_ccb->local_cid == L2CAP_SMP_CID)
1631           return;
1632 
1633         l2cu_no_dynamic_ccbs(p_lcb);
1634       } else {
1635         /* Link is still active, adjust channel quotas. */
1636         l2c_link_adjust_chnl_allocation();
1637       }
1638     } else if (p_lcb->link_state == LST_CONNECTING) {
1639       if (!p_lcb->ccb_queue.p_first_ccb) {
1640         if (p_lcb->transport == BT_TRANSPORT_LE &&
1641             p_ccb->local_cid == L2CAP_ATT_CID) {
1642           L2CAP_TRACE_WARNING("%s - disconnecting the LE link", __func__);
1643           l2cu_no_dynamic_ccbs(p_lcb);
1644         }
1645       }
1646     }
1647   }
1648 }
1649 
1650 /*******************************************************************************
1651  *
1652  * Function         l2cu_find_ccb_by_remote_cid
1653  *
1654  * Description      Look through all active CCBs on a link for a match based
1655  *                  on the remote CID.
1656  *
1657  * Returns          pointer to matched CCB, or NULL if no match
1658  *
1659  ******************************************************************************/
l2cu_find_ccb_by_remote_cid(tL2C_LCB * p_lcb,uint16_t remote_cid)1660 tL2C_CCB* l2cu_find_ccb_by_remote_cid(tL2C_LCB* p_lcb, uint16_t remote_cid) {
1661   tL2C_CCB* p_ccb;
1662 
1663   /* If LCB is NULL, look through all active links */
1664   if (!p_lcb) {
1665     return NULL;
1666   } else {
1667     for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
1668       if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid)) return (p_ccb);
1669   }
1670 
1671   /* If here, no match found */
1672   return (NULL);
1673 }
1674 
1675 /*******************************************************************************
1676  *
1677  * Function         l2cu_allocate_rcb
1678  *
1679  * Description      Look through the Registration Control Blocks for a free
1680  *                  one.
1681  *
1682  * Returns          Pointer to the RCB or NULL if not found
1683  *
1684  ******************************************************************************/
l2cu_allocate_rcb(uint16_t psm)1685 tL2C_RCB* l2cu_allocate_rcb(uint16_t psm) {
1686   tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
1687   uint16_t xx;
1688 
1689   for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1690     if (!p_rcb->in_use) {
1691       p_rcb->in_use = true;
1692       p_rcb->psm = psm;
1693       return (p_rcb);
1694     }
1695   }
1696 
1697   /* If here, no free RCB found */
1698   return (NULL);
1699 }
1700 
1701 /*******************************************************************************
1702  *
1703  * Function         l2cu_allocate_ble_rcb
1704  *
1705  * Description      Look through the BLE Registration Control Blocks for a free
1706  *                  one.
1707  *
1708  * Returns          Pointer to the BLE RCB or NULL if not found
1709  *
1710  ******************************************************************************/
l2cu_allocate_ble_rcb(uint16_t psm)1711 tL2C_RCB* l2cu_allocate_ble_rcb(uint16_t psm) {
1712   tL2C_RCB* p_rcb = &l2cb.ble_rcb_pool[0];
1713   uint16_t xx;
1714 
1715   for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1716     if (!p_rcb->in_use) {
1717       p_rcb->in_use = true;
1718       p_rcb->psm = psm;
1719       return (p_rcb);
1720     }
1721   }
1722 
1723   /* If here, no free RCB found */
1724   return (NULL);
1725 }
1726 
1727 /*******************************************************************************
1728  *
1729  * Function         l2cu_release_rcb
1730  *
1731  * Description      Mark an RCB as no longet in use
1732  *
1733  * Returns          void
1734  *
1735  ******************************************************************************/
l2cu_release_rcb(tL2C_RCB * p_rcb)1736 void l2cu_release_rcb(tL2C_RCB* p_rcb) {
1737   p_rcb->in_use = false;
1738   p_rcb->psm = 0;
1739 }
1740 
1741 /*******************************************************************************
1742  *
1743  * Function         l2cu_release_ble_rcb
1744  *
1745  * Description      Mark an LE RCB as no longer in use
1746  *
1747  * Returns          void
1748  *
1749  ******************************************************************************/
l2cu_release_ble_rcb(tL2C_RCB * p_rcb)1750 void l2cu_release_ble_rcb(tL2C_RCB* p_rcb) {
1751   L2CA_FreeLePSM(p_rcb->psm);
1752   p_rcb->in_use = false;
1753   p_rcb->psm = 0;
1754 }
1755 
1756 /*******************************************************************************
1757  *
1758  * Function         l2cu_disconnect_chnl
1759  *
1760  * Description      Disconnect a channel. Typically, this is due to either
1761  *                  receiving a bad configuration,  bad packet or max_retries
1762  *                  expiring.
1763  *
1764  ******************************************************************************/
l2cu_disconnect_chnl(tL2C_CCB * p_ccb)1765 void l2cu_disconnect_chnl(tL2C_CCB* p_ccb) {
1766   uint16_t local_cid = p_ccb->local_cid;
1767 
1768   if (local_cid >= L2CAP_BASE_APPL_CID) {
1769     tL2CA_DISCONNECT_IND_CB* p_disc_cb =
1770         p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
1771 
1772     L2CAP_TRACE_WARNING("L2CAP - disconnect_chnl CID: 0x%04x", local_cid);
1773 
1774     l2cu_send_peer_disc_req(p_ccb);
1775 
1776     l2cu_release_ccb(p_ccb);
1777 
1778     (*p_disc_cb)(local_cid, false);
1779   } else {
1780     /* failure on the AMP channel, probably need to disconnect ACL */
1781     L2CAP_TRACE_ERROR("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid);
1782   }
1783 }
1784 
1785 /*******************************************************************************
1786  *
1787  * Function         l2cu_find_rcb_by_psm
1788  *
1789  * Description      Look through the Registration Control Blocks to see if
1790  *                  anyone registered to handle the PSM in question
1791  *
1792  * Returns          Pointer to the RCB or NULL if not found
1793  *
1794  ******************************************************************************/
l2cu_find_rcb_by_psm(uint16_t psm)1795 tL2C_RCB* l2cu_find_rcb_by_psm(uint16_t psm) {
1796   tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
1797   uint16_t xx;
1798 
1799   for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1800     if ((p_rcb->in_use) && (p_rcb->psm == psm)) return (p_rcb);
1801   }
1802 
1803   /* If here, no match found */
1804   return (NULL);
1805 }
1806 
1807 /*******************************************************************************
1808  *
1809  * Function         l2cu_find_ble_rcb_by_psm
1810  *
1811  * Description      Look through the BLE Registration Control Blocks to see if
1812  *                  anyone registered to handle the PSM in question
1813  *
1814  * Returns          Pointer to the BLE RCB or NULL if not found
1815  *
1816  ******************************************************************************/
l2cu_find_ble_rcb_by_psm(uint16_t psm)1817 tL2C_RCB* l2cu_find_ble_rcb_by_psm(uint16_t psm) {
1818   tL2C_RCB* p_rcb = &l2cb.ble_rcb_pool[0];
1819   uint16_t xx;
1820 
1821   for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++) {
1822     if ((p_rcb->in_use) && (p_rcb->psm == psm)) return (p_rcb);
1823   }
1824 
1825   /* If here, no match found */
1826   return (NULL);
1827 }
1828 
1829 /*******************************************************************************
1830  *
1831  * Function         l2cu_process_peer_cfg_req
1832  *
1833  * Description      This function is called when the peer sends us a "config
1834  *                  request" message. It extracts the configuration of interest
1835  *                  and saves it in the CCB.
1836  *
1837  *                  Note:  Negotiation of the FCR channel type is handled
1838  *                         internally, all others are passed to the upper layer.
1839  *
1840  * Returns          uint8_t - L2CAP_PEER_CFG_OK if passed to upper layer,
1841  *                            L2CAP_PEER_CFG_UNACCEPTABLE if automatically
1842  *                                      responded to because parameters are
1843  *                                      unnacceptable from a specification point
1844  *                                      of view.
1845  *                            L2CAP_PEER_CFG_DISCONNECT if no compatible channel
1846  *                                      modes between the two devices, and shall
1847  *                                      be closed.
1848  *
1849  ******************************************************************************/
l2cu_process_peer_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)1850 uint8_t l2cu_process_peer_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
1851   bool mtu_ok = true;
1852   bool qos_type_ok = true;
1853   bool flush_to_ok = true;
1854   bool fcr_ok = true;
1855   uint8_t fcr_status;
1856 
1857   /* Ignore FCR parameters for basic mode */
1858   if (!p_cfg->fcr_present) p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
1859 
1860   /* Save the MTU that our peer can receive */
1861   if (p_cfg->mtu_present) {
1862     /* Make sure MTU is at least the minimum */
1863     if (p_cfg->mtu >= L2CAP_MIN_MTU) {
1864       /* In basic mode, limit the MTU to our buffer size */
1865       if ((!p_cfg->fcr_present) && (p_cfg->mtu > L2CAP_MTU_SIZE))
1866         p_cfg->mtu = L2CAP_MTU_SIZE;
1867 
1868       /* Save the accepted value in case of renegotiation */
1869       p_ccb->peer_cfg.mtu = p_cfg->mtu;
1870       p_ccb->peer_cfg.mtu_present = true;
1871       p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
1872     } else /* Illegal MTU value */
1873     {
1874       p_cfg->mtu = L2CAP_MIN_MTU;
1875       mtu_ok = false;
1876     }
1877   }
1878   /* Reload mtu from a previously accepted config request */
1879   else if (p_ccb->peer_cfg.mtu_present) {
1880     p_cfg->mtu_present = true;
1881     p_cfg->mtu = p_ccb->peer_cfg.mtu;
1882   }
1883 
1884   /* Verify that the flush timeout is a valid value (0 is illegal) */
1885   if (p_cfg->flush_to_present) {
1886     if (!p_cfg->flush_to) {
1887       p_cfg->flush_to = 0xFFFF; /* Infinite retransmissions (spec default) */
1888       flush_to_ok = false;
1889     } else /* Save the accepted value in case of renegotiation */
1890     {
1891       p_ccb->peer_cfg.flush_to_present = true;
1892       p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
1893       p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
1894     }
1895   }
1896   /* Reload flush_to from a previously accepted config request */
1897   else if (p_ccb->peer_cfg.flush_to_present) {
1898     p_cfg->flush_to_present = true;
1899     p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
1900   }
1901 
1902   /* Save the QOS settings the the peer is using */
1903   if (p_cfg->qos_present) {
1904     /* Make sure service type is not a reserved value; otherwise let upper
1905        layer decide if acceptable
1906     */
1907     if (p_cfg->qos.service_type <= SVC_TYPE_GUARANTEED) {
1908       p_ccb->peer_cfg.qos = p_cfg->qos;
1909       p_ccb->peer_cfg.qos_present = true;
1910       p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
1911     } else /* Illegal service type value */
1912     {
1913       p_cfg->qos.service_type = SVC_TYPE_BEST_EFFORT;
1914       qos_type_ok = false;
1915     }
1916   }
1917   /* Reload QOS from a previously accepted config request */
1918   else if (p_ccb->peer_cfg.qos_present) {
1919     p_cfg->qos_present = true;
1920     p_cfg->qos = p_ccb->peer_cfg.qos;
1921   }
1922 
1923   fcr_status = l2c_fcr_process_peer_cfg_req(p_ccb, p_cfg);
1924   if (fcr_status == L2CAP_PEER_CFG_DISCONNECT) {
1925     /* Notify caller to disconnect the channel (incompatible modes) */
1926     p_cfg->result = L2CAP_CFG_FAILED_NO_REASON;
1927     p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
1928 
1929     return (L2CAP_PEER_CFG_DISCONNECT);
1930   }
1931 
1932   fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
1933 
1934   /* Return any unacceptable parameters */
1935   if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok) {
1936     l2cu_adjust_out_mps(p_ccb);
1937     return (L2CAP_PEER_CFG_OK);
1938   } else {
1939     p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
1940 
1941     if (mtu_ok) p_cfg->mtu_present = false;
1942     if (flush_to_ok) p_cfg->flush_to_present = false;
1943     if (qos_type_ok) p_cfg->qos_present = false;
1944     if (fcr_ok) p_cfg->fcr_present = false;
1945 
1946     return (L2CAP_PEER_CFG_UNACCEPTABLE);
1947   }
1948 }
1949 
1950 /*******************************************************************************
1951  *
1952  * Function         l2cu_process_peer_cfg_rsp
1953  *
1954  * Description      This function is called when the peer sends us a "config
1955  *                  response" message. It extracts the configuration of interest
1956  *                  and saves it in the CCB.
1957  *
1958  * Returns          void
1959  *
1960  ******************************************************************************/
l2cu_process_peer_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)1961 void l2cu_process_peer_cfg_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
1962   /* If we wanted QoS and the peer sends us a positive response with QoS, use
1963    * his values */
1964   if ((p_cfg->qos_present) && (p_ccb->our_cfg.qos_present))
1965     p_ccb->our_cfg.qos = p_cfg->qos;
1966 
1967   if (p_cfg->fcr_present) {
1968     /* Save the retransmission and monitor timeout values */
1969     if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE) {
1970       p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
1971       p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
1972     }
1973 
1974     /* Calculate the max number of packets for which we can delay sending an ack
1975      */
1976     if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz)
1977       p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
1978     else
1979       p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
1980 
1981     L2CAP_TRACE_DEBUG(
1982         "l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, "
1983         "max_held_acks: %d",
1984         p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz,
1985         p_ccb->fcrb.max_held_acks);
1986   }
1987 }
1988 
1989 /*******************************************************************************
1990  *
1991  * Function         l2cu_process_our_cfg_req
1992  *
1993  * Description      This function is called when we send a "config request"
1994  *                  message. It extracts the configuration of interest and saves
1995  *                  it in the CCB.
1996  *
1997  * Returns          void
1998  *
1999  ******************************************************************************/
l2cu_process_our_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2000 void l2cu_process_our_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2001   tL2C_LCB* p_lcb;
2002   uint16_t hci_flush_to;
2003 
2004   /* Save the QOS settings we are using for transmit */
2005   if (p_cfg->qos_present) {
2006     p_ccb->our_cfg.qos_present = true;
2007     p_ccb->our_cfg.qos = p_cfg->qos;
2008   }
2009 
2010   if (p_cfg->fcr_present) {
2011     /* Override FCR options if attempting streaming or basic */
2012     if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)
2013       memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
2014     else {
2015       /* On BR/EDR, timer values are zero in config request */
2016       /* On class 2 AMP, timer value in config request shall be non-0 processing
2017        * time */
2018       /*                 timer value in config response shall be greater than
2019        * received processing time */
2020       p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
2021     }
2022 
2023     /* Set the threshold to send acks (may be updated in the cfg response) */
2024     p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
2025 
2026     /* Include FCS option only if peer can handle it */
2027     if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC) {
2028       /* FCS check can be bypassed if peer also desires to bypass */
2029       if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS)
2030         p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR;
2031     } else
2032       p_cfg->fcs_present = false;
2033   } else {
2034     p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
2035   }
2036 
2037   p_ccb->our_cfg.fcr.mode = p_cfg->fcr.mode;
2038   p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
2039 
2040   /* Check the flush timeout. If it is lower than the current one used */
2041   /* then we need to adjust the flush timeout sent to the controller   */
2042   if (p_cfg->flush_to_present) {
2043     if ((p_cfg->flush_to == 0) ||
2044         (p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH)) {
2045       /* don't send invalid flush timeout */
2046       /* SPEC: The sender of the Request shall specify its flush timeout value
2047        */
2048       /*       if it differs from the default value of 0xFFFF */
2049       p_cfg->flush_to_present = false;
2050     } else {
2051       p_ccb->our_cfg.flush_to = p_cfg->flush_to;
2052       p_lcb = p_ccb->p_lcb;
2053 
2054       if (p_cfg->flush_to < p_lcb->link_flush_tout) {
2055         p_lcb->link_flush_tout = p_cfg->flush_to;
2056 
2057         /* If the timeout is within range of HCI, set the flush timeout */
2058         if (p_cfg->flush_to <= ((HCI_MAX_AUTOMATIC_FLUSH_TIMEOUT * 5) / 8)) {
2059           /* Convert flush timeout to 0.625 ms units, with round */
2060           hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
2061           btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to);
2062         }
2063       }
2064     }
2065   }
2066 }
2067 
2068 /*******************************************************************************
2069  *
2070  * Function         l2cu_process_our_cfg_rsp
2071  *
2072  * Description      This function is called when we send the peer a "config
2073  *                  response" message. It extracts the configuration of interest
2074  *                  and saves it in the CCB.
2075  *
2076  * Returns          void
2077  *
2078  ******************************************************************************/
l2cu_process_our_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2079 void l2cu_process_our_cfg_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) {
2080   /* If peer wants QoS, we are allowed to change the values in a positive
2081    * response */
2082   if ((p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present))
2083     p_ccb->peer_cfg.qos = p_cfg->qos;
2084   else
2085     p_cfg->qos_present = false;
2086 
2087   l2c_fcr_adj_our_rsp_options(p_ccb, p_cfg);
2088 }
2089 
2090 /*******************************************************************************
2091  *
2092  * Function         l2cu_device_reset
2093  *
2094  * Description      This function is called when reset of the device is
2095  *                  completed.  For all active connection simulate HCI_DISC
2096  *
2097  * Returns          void
2098  *
2099  ******************************************************************************/
l2cu_device_reset(void)2100 void l2cu_device_reset(void) {
2101   int xx;
2102   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
2103 
2104   for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
2105     if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE)) {
2106       l2c_link_hci_disc_comp(p_lcb->handle, (uint8_t)-1);
2107     }
2108   }
2109 }
2110 
l2cu_create_conn_le(tL2C_LCB * p_lcb)2111 bool l2cu_create_conn_le(tL2C_LCB* p_lcb) {
2112   uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
2113   return l2cu_create_conn_le(p_lcb, phy);
2114 }
2115 
2116 /* This function initiates an acl connection to a LE device.
2117  * Returns true if request started successfully, false otherwise. */
l2cu_create_conn_le(tL2C_LCB * p_lcb,uint8_t initiating_phys)2118 bool l2cu_create_conn_le(tL2C_LCB* p_lcb, uint8_t initiating_phys) {
2119   tBT_DEVICE_TYPE dev_type;
2120   tBLE_ADDR_TYPE addr_type;
2121 
2122   BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
2123 
2124   if (!controller_get_interface()->supports_ble()) return false;
2125 
2126   p_lcb->ble_addr_type = addr_type;
2127   p_lcb->transport = BT_TRANSPORT_LE;
2128   p_lcb->initiating_phys = initiating_phys;
2129 
2130   return (l2cble_create_conn(p_lcb));
2131 }
2132 
2133 /* This function initiates an acl connection to a Classic device via HCI.
2134  * Returns true on success, false otherwise. */
l2cu_create_conn_br_edr(tL2C_LCB * p_lcb)2135 bool l2cu_create_conn_br_edr(tL2C_LCB* p_lcb) {
2136   int xx;
2137   tL2C_LCB* p_lcb_cur = &l2cb.lcb_pool[0];
2138   bool is_sco_active;
2139   const controller_t* controller = controller_get_interface();
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 (controller->supports_role_switch()) {
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   uint16_t num_acl = BTM_GetNumAclLinks();
2224   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_lcb->remote_bd_addr);
2225   uint8_t no_hi_prio_chs = l2cu_get_num_hi_priority();
2226   const controller_t* controller = controller_get_interface();
2227 
2228   L2CAP_TRACE_DEBUG(
2229       "l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d",
2230       l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding);
2231   /* FW team says that we can participant in 4 piconets
2232    * typically 3 piconet + 1 for scanning.
2233    * We can enhance the code to count the number of piconets later. */
2234   if (((!l2cb.disallow_switch && (num_acl < 3)) ||
2235        (p_lcb->is_bonding && (no_hi_prio_chs == 0))) &&
2236       controller->supports_role_switch())
2237     allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
2238   else
2239     allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
2240 
2241   p_lcb->link_state = LST_CONNECTING;
2242 
2243   /* Check with the BT manager if details about remote device are known */
2244   p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr);
2245   if ((p_inq_info != NULL) &&
2246       (p_inq_info->results.inq_result_type & BTM_INQ_RESULT_BR)) {
2247     page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
2248     page_scan_mode = p_inq_info->results.page_scan_mode;
2249     clock_offset = (uint16_t)(p_inq_info->results.clock_offset);
2250   } else {
2251     /* No info known. Use default settings */
2252     page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
2253     page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
2254 
2255     clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
2256   }
2257 
2258   btsnd_hcic_create_conn(
2259       p_lcb->remote_bd_addr, (HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1 |
2260                               HCI_PKT_TYPES_MASK_DM3 | HCI_PKT_TYPES_MASK_DH3 |
2261                               HCI_PKT_TYPES_MASK_DM5 | HCI_PKT_TYPES_MASK_DH5),
2262       page_scan_rep_mode, page_scan_mode, clock_offset, allow_switch);
2263 
2264   btm_acl_update_busy_level(BTM_BLI_PAGE_EVT);
2265 
2266   alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS,
2267                      l2c_lcb_timer_timeout, p_lcb);
2268 
2269   return (true);
2270 }
2271 
2272 /*******************************************************************************
2273  *
2274  * Function         l2cu_find_lcb_by_state
2275  *
2276  * Description      Look through all active LCBs for a match based on the
2277  *                  LCB state.
2278  *
2279  * Returns          pointer to first matched LCB, or NULL if no match
2280  *
2281  ******************************************************************************/
l2cu_find_lcb_by_state(tL2C_LINK_STATE state)2282 tL2C_LCB* l2cu_find_lcb_by_state(tL2C_LINK_STATE state) {
2283   uint16_t i;
2284   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
2285 
2286   for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
2287     if ((p_lcb->in_use) && (p_lcb->link_state == state)) {
2288       return (p_lcb);
2289     }
2290   }
2291 
2292   /* If here, no match found */
2293   return (NULL);
2294 }
2295 
2296 /*******************************************************************************
2297  *
2298  * Function         l2cu_lcb_disconnecting
2299  *
2300  * Description      On each active lcb, check if the lcb is in disconnecting
2301  *                  state, or if there are no ccb's on the lcb (implying
2302                     idle timeout is running), or if last ccb on the link
2303                     is in disconnecting state.
2304  *
2305  * Returns          true if any of above conditions met, false otherwise
2306  *
2307  ******************************************************************************/
l2cu_lcb_disconnecting(void)2308 bool l2cu_lcb_disconnecting(void) {
2309   tL2C_LCB* p_lcb;
2310   tL2C_CCB* p_ccb;
2311   uint16_t i;
2312   bool status = false;
2313 
2314   p_lcb = &l2cb.lcb_pool[0];
2315 
2316   for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
2317     if (p_lcb->in_use) {
2318       /* no ccbs on lcb, or lcb is in disconnecting state */
2319       if ((!p_lcb->ccb_queue.p_first_ccb) ||
2320           (p_lcb->link_state == LST_DISCONNECTING)) {
2321         status = true;
2322         break;
2323       }
2324       /* only one ccb left on lcb */
2325       else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb) {
2326         p_ccb = p_lcb->ccb_queue.p_first_ccb;
2327 
2328         if ((p_ccb->in_use) &&
2329             ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
2330              (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) {
2331           status = true;
2332           break;
2333         }
2334       }
2335     }
2336   }
2337   return status;
2338 }
2339 
2340 /*******************************************************************************
2341  *
2342  * Function         l2cu_set_acl_priority
2343  *
2344  * Description      Sets the transmission priority for a channel.
2345  *                  (For initial implementation only two values are valid.
2346  *                  L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
2347  *
2348  * Returns          true if a valid channel, else false
2349  *
2350  ******************************************************************************/
2351 
l2cu_set_acl_priority(const RawAddress & bd_addr,uint8_t priority,bool reset_after_rs)2352 bool l2cu_set_acl_priority(const RawAddress& bd_addr, uint8_t priority,
2353                            bool reset_after_rs) {
2354   tL2C_LCB* p_lcb;
2355   uint8_t* pp;
2356   uint8_t command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2357   uint8_t vs_param;
2358 
2359   APPL_TRACE_EVENT("SET ACL PRIORITY %d", priority);
2360 
2361   /* Find the link control block for the acl channel */
2362   p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
2363   if (p_lcb == NULL) {
2364     L2CAP_TRACE_WARNING("L2CAP - no LCB for L2CA_SetAclPriority");
2365     return (false);
2366   }
2367 
2368   if (BTM_IS_BRCM_CONTROLLER()) {
2369     /* Called from above L2CAP through API; send VSC if changed */
2370     if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
2371         /* Called because of a master/slave role switch; if high resend VSC */
2372         (reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) {
2373       pp = command;
2374 
2375       vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH
2376                                                    : HCI_BRCM_ACL_PRIORITY_LOW;
2377 
2378       UINT16_TO_STREAM(pp, p_lcb->handle);
2379       UINT8_TO_STREAM(pp, vs_param);
2380 
2381       BTM_VendorSpecificCommand(HCI_BRCM_SET_ACL_PRIORITY,
2382                                 HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command,
2383                                 NULL);
2384     }
2385   }
2386 
2387   /* Adjust lmp buffer allocation for this channel if priority changed */
2388   if (p_lcb->acl_priority != priority) {
2389     p_lcb->acl_priority = priority;
2390     l2c_link_adjust_allocation();
2391   }
2392   return (true);
2393 }
2394 
2395 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2396 /******************************************************************************
2397  *
2398  * Function         l2cu_set_non_flushable_pbf
2399  *
2400  * Description      set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
2401  *
2402  * Returns          void
2403  *
2404  ******************************************************************************/
l2cu_set_non_flushable_pbf(bool is_supported)2405 void l2cu_set_non_flushable_pbf(bool is_supported) {
2406   if (is_supported)
2407     l2cb.non_flushable_pbf =
2408         (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
2409   else
2410     l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
2411 }
2412 #endif
2413 
2414 /*******************************************************************************
2415  *
2416  * Function         l2cu_resubmit_pending_sec_req
2417  *
2418  * Description      This function is called when required security procedures
2419  *                  are completed and any pending requests can be re-submitted.
2420  *
2421  * Returns          void
2422  *
2423  ******************************************************************************/
l2cu_resubmit_pending_sec_req(const RawAddress * p_bda)2424 void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda) {
2425   tL2C_LCB* p_lcb;
2426   tL2C_CCB* p_ccb;
2427   tL2C_CCB* p_next_ccb;
2428   int xx;
2429 
2430   L2CAP_TRACE_DEBUG("l2cu_resubmit_pending_sec_req  p_bda: 0x%08x", p_bda);
2431 
2432   /* If we are called with a BDA, only resubmit for that BDA */
2433   if (p_bda) {
2434     p_lcb = l2cu_find_lcb_by_bd_addr(*p_bda, BT_TRANSPORT_BR_EDR);
2435 
2436     /* If we don't have one, this is an error */
2437     if (p_lcb) {
2438       /* For all channels, send the event through their FSMs */
2439       for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2440         p_next_ccb = p_ccb->p_next_ccb;
2441         l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2442       }
2443     } else {
2444       L2CAP_TRACE_WARNING("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
2445     }
2446   } else {
2447     /* No BDA pasesed in, so check all links */
2448     for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS;
2449          xx++, p_lcb++) {
2450       if (p_lcb->in_use) {
2451         /* For all channels, send the event through their FSMs */
2452         for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb) {
2453           p_next_ccb = p_ccb->p_next_ccb;
2454           l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2455         }
2456       }
2457     }
2458   }
2459 }
2460 
2461 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
2462 /*******************************************************************************
2463  *
2464  * Function         l2cu_set_info_rsp_mask
2465  *
2466  * Description      This function allows the script wrapper to change the
2467  *                  info resp mask for conformance testing.
2468  *
2469  * Returns          pointer to CCB, or NULL if none
2470  *
2471  ******************************************************************************/
l2cu_set_info_rsp_mask(uint32_t mask)2472 void l2cu_set_info_rsp_mask(uint32_t mask) { l2cb.test_info_resp = mask; }
2473 #endif /* L2CAP_CONFORMANCE_TESTING */
2474 
2475 /*******************************************************************************
2476  *
2477  * Function         l2cu_adjust_out_mps
2478  *
2479  * Description      Sets our MPS based on current controller capabilities
2480  *
2481  * Returns          void
2482  *
2483  ******************************************************************************/
l2cu_adjust_out_mps(tL2C_CCB * p_ccb)2484 void l2cu_adjust_out_mps(tL2C_CCB* p_ccb) {
2485   uint16_t packet_size;
2486 
2487   /* on the tx side MTU is selected based on packet size of the controller */
2488   packet_size = btm_get_max_packet_size(p_ccb->p_lcb->remote_bd_addr);
2489 
2490   if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD +
2491                       L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) {
2492     /* something is very wrong */
2493     L2CAP_TRACE_ERROR(
2494         "l2cu_adjust_out_mps bad packet size: %u  will use MPS: %u",
2495         packet_size, p_ccb->peer_cfg.fcr.mps);
2496     p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2497   } else {
2498     packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD +
2499                     L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
2500 
2501     /* We try to negotiate MTU that each packet can be split into whole
2502     number of max packets.  For example if link is 1.2 max packet size is 339
2503     bytes.
2504     At first calculate how many whole packets it is.  MAX L2CAP is 1691 + 4
2505     overhead.
2506     1695, that will be 5 Dh5 packets.  Now maximum L2CAP packet is
2507     5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
2508 
2509     For EDR 2.0 packet size is 1027.  So we better send RFCOMM packet as 1 3DH5
2510     packet
2511     1 * 1027 = 1027.  Minus 4 bytes L2CAP header 1023.  */
2512     if (p_ccb->peer_cfg.fcr.mps >= packet_size)
2513       p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
2514     else
2515       p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2516 
2517     L2CAP_TRACE_DEBUG(
2518         "l2cu_adjust_out_mps use %d   Based on peer_cfg.fcr.mps: %u  "
2519         "packet_size: %u",
2520         p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
2521   }
2522 }
2523 
2524 /*******************************************************************************
2525  *
2526  * Function         l2cu_initialize_fixed_ccb
2527  *
2528  * Description      Initialize a fixed channel's CCB
2529  *
2530  * Returns          true or false
2531  *
2532  ******************************************************************************/
l2cu_initialize_fixed_ccb(tL2C_LCB * p_lcb,uint16_t fixed_cid)2533 bool l2cu_initialize_fixed_ccb(tL2C_LCB* p_lcb, uint16_t fixed_cid) {
2534 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2535   tL2C_CCB* p_ccb;
2536 
2537   /* If we already have a CCB, then simply return */
2538   p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
2539   if ((p_ccb != NULL) && p_ccb->in_use) {
2540     /*
2541      * NOTE: The "in_use" check is needed to ignore leftover entries
2542      * that have been already released by l2cu_release_ccb().
2543      */
2544     return (true);
2545   }
2546 
2547   p_ccb = l2cu_allocate_ccb(NULL, 0);
2548   if (p_ccb == NULL) return (false);
2549 
2550   alarm_cancel(p_lcb->l2c_lcb_timer);
2551 
2552   /* Set CID for the connection */
2553   p_ccb->local_cid = fixed_cid;
2554   p_ccb->remote_cid = fixed_cid;
2555 
2556   p_ccb->is_flushable = false;
2557 
2558   /* Link ccb to lcb and lcb to ccb */
2559   p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
2560   p_ccb->p_lcb = p_lcb;
2561 
2562   /* There is no configuration, so if the link is up, the channel is up */
2563   if (p_lcb->link_state == LST_CONNECTED) p_ccb->chnl_state = CST_OPEN;
2564 
2565   /* Set the default idle timeout value to use */
2566   p_ccb->fixed_chnl_idle_tout =
2567       l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
2568 #endif
2569   return (true);
2570 }
2571 
2572 /*******************************************************************************
2573  *
2574  * Function         l2cu_no_dynamic_ccbs
2575  *
2576  * Description      Handles the case when there are no more dynamic CCBs. If
2577  *                  there are any fixed CCBs, start the longest of the fixed CCB
2578  *                  timeouts, otherwise start the default link idle timeout or
2579  *                  disconnect.
2580  *
2581  * Returns          void
2582  *
2583  ******************************************************************************/
l2cu_no_dynamic_ccbs(tL2C_LCB * p_lcb)2584 void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) {
2585   tBTM_STATUS rc;
2586   uint64_t timeout_ms = p_lcb->idle_timeout * 1000;
2587   bool start_timeout = true;
2588 
2589 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2590   int xx;
2591 
2592   for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2593     if ((p_lcb->p_fixed_ccbs[xx] != NULL) &&
2594         (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000 > timeout_ms)) {
2595 
2596       if (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout == L2CAP_NO_IDLE_TIMEOUT) {
2597          L2CAP_TRACE_DEBUG("%s NO IDLE timeout set for fixed cid 0x%04x", __func__,
2598             p_lcb->p_fixed_ccbs[xx]->local_cid);
2599          start_timeout = false;
2600       }
2601       timeout_ms = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000;
2602     }
2603   }
2604 #endif
2605 
2606   /* If the link is pairing, do not mess with the timeouts */
2607   if (p_lcb->is_bonding) return;
2608 
2609   if (timeout_ms == 0) {
2610     L2CAP_TRACE_DEBUG(
2611         "l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
2612 
2613     rc = btm_sec_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
2614     if (rc == BTM_CMD_STARTED) {
2615       l2cu_process_fixed_disc_cback(p_lcb);
2616       p_lcb->link_state = LST_DISCONNECTING;
2617       timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
2618     } else if (rc == BTM_SUCCESS) {
2619       l2cu_process_fixed_disc_cback(p_lcb);
2620       /* BTM SEC will make sure that link is release (probably after pairing is
2621        * done) */
2622       p_lcb->link_state = LST_DISCONNECTING;
2623       start_timeout = false;
2624     } else if (p_lcb->is_bonding) {
2625       btsnd_hcic_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
2626       l2cu_process_fixed_disc_cback(p_lcb);
2627       p_lcb->link_state = LST_DISCONNECTING;
2628       timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
2629     } else {
2630       /* probably no buffer to send disconnect */
2631       timeout_ms = BT_1SEC_TIMEOUT_MS;
2632     }
2633   }
2634 
2635   if (start_timeout) {
2636     L2CAP_TRACE_DEBUG("%s starting IDLE timeout: %d ms", __func__, timeout_ms);
2637     alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout,
2638                        p_lcb);
2639   } else {
2640     alarm_cancel(p_lcb->l2c_lcb_timer);
2641   }
2642 }
2643 
2644 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2645 /*******************************************************************************
2646  *
2647  * Function         l2cu_process_fixed_chnl_resp
2648  *
2649  * Description      handle a fixed channel response (or lack thereof)
2650  *                  if the link failed, or a fixed channel response was
2651  *                  not received, the bitfield is all zeros.
2652  *
2653  ******************************************************************************/
l2cu_process_fixed_chnl_resp(tL2C_LCB * p_lcb)2654 void l2cu_process_fixed_chnl_resp(tL2C_LCB* p_lcb) {
2655   if (p_lcb->transport == BT_TRANSPORT_BR_EDR) {
2656     /* ignore all not assigned BR/EDR channels */
2657     p_lcb->peer_chnl_mask[0] &=
2658         (L2CAP_FIXED_CHNL_SIG_BIT | L2CAP_FIXED_CHNL_CNCTLESS_BIT |
2659          L2CAP_FIXED_CHNL_SMP_BR_BIT);
2660   } else
2661     p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask;
2662 
2663   /* Tell all registered fixed channels about the connection */
2664   for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2665     uint16_t channel_id = xx + L2CAP_FIRST_FIXED_CHNL;
2666 
2667     /* See BT Spec Ver 5.0 | Vol 3, Part A 2.1 table 2.1 and 2.2 */
2668 
2669     /* skip sending LE fix channel callbacks on BR/EDR links */
2670     if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
2671         channel_id >= L2CAP_ATT_CID && channel_id <= L2CAP_SMP_CID)
2672       continue;
2673 
2674     /* skip sending BR fix channel callbacks on LE links */
2675     if (p_lcb->transport == BT_TRANSPORT_LE && channel_id == L2CAP_SMP_BR_CID)
2676       continue;
2677 
2678     if (!l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb) continue;
2679 
2680     if (p_lcb->peer_chnl_mask[(channel_id) / 8] & (1 << ((channel_id) % 8))) {
2681       if (p_lcb->p_fixed_ccbs[xx])
2682         p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
2683       (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2684           channel_id, p_lcb->remote_bd_addr, true, 0, p_lcb->transport);
2685     } else {
2686       (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2687           channel_id, p_lcb->remote_bd_addr, false, p_lcb->disc_reason,
2688           p_lcb->transport);
2689 
2690       if (p_lcb->p_fixed_ccbs[xx]) {
2691         l2cu_release_ccb(p_lcb->p_fixed_ccbs[xx]);
2692         p_lcb->p_fixed_ccbs[xx] = NULL;
2693       }
2694     }
2695   }
2696 }
2697 #endif
2698 
2699 /*******************************************************************************
2700  *
2701  * Function         l2cu_process_fixed_disc_cback
2702  *
2703  * Description      send l2cap fixed channel disconnection callback to the
2704  *                  application
2705  *
2706  * Returns          void
2707  *
2708  ******************************************************************************/
l2cu_process_fixed_disc_cback(tL2C_LCB * p_lcb)2709 void l2cu_process_fixed_disc_cback(tL2C_LCB* p_lcb) {
2710 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2711 
2712   /* Select peer channels mask to use depending on transport */
2713   uint8_t peer_channel_mask = p_lcb->peer_chnl_mask[0];
2714 
2715   // For LE, reset the stored peer channel mask
2716   if (p_lcb->transport == BT_TRANSPORT_LE) p_lcb->peer_chnl_mask[0] = 0;
2717 
2718   for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
2719     if (p_lcb->p_fixed_ccbs[xx]) {
2720       if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb) {
2721         tL2C_CCB* p_l2c_chnl_ctrl_block;
2722         p_l2c_chnl_ctrl_block = p_lcb->p_fixed_ccbs[xx];
2723         p_lcb->p_fixed_ccbs[xx] = NULL;
2724         l2cu_release_ccb(p_l2c_chnl_ctrl_block);
2725         (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2726             xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false,
2727             p_lcb->disc_reason, p_lcb->transport);
2728       }
2729     } else if ((peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL))) &&
2730                (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL))
2731       (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(
2732           xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false,
2733           p_lcb->disc_reason, p_lcb->transport);
2734   }
2735 #endif
2736 }
2737 
2738 /*******************************************************************************
2739  *
2740  * Function         l2cu_send_peer_ble_par_req
2741  *
2742  * Description      Build and send a BLE parameter update request message
2743  *                  to the peer.
2744  *
2745  * Returns          void
2746  *
2747  ******************************************************************************/
l2cu_send_peer_ble_par_req(tL2C_LCB * p_lcb,uint16_t min_int,uint16_t max_int,uint16_t latency,uint16_t timeout)2748 void l2cu_send_peer_ble_par_req(tL2C_LCB* p_lcb, uint16_t min_int,
2749                                 uint16_t max_int, uint16_t latency,
2750                                 uint16_t timeout) {
2751   BT_HDR* p_buf;
2752   uint8_t* p;
2753 
2754   /* Create an identifier for this packet */
2755   p_lcb->id++;
2756   l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
2757 
2758   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN,
2759                             L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id);
2760   if (p_buf == NULL) {
2761     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_par_req - no buffer");
2762     return;
2763   }
2764 
2765   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2766       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2767 
2768   UINT16_TO_STREAM(p, min_int);
2769   UINT16_TO_STREAM(p, max_int);
2770   UINT16_TO_STREAM(p, latency);
2771   UINT16_TO_STREAM(p, timeout);
2772 
2773   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2774 }
2775 
2776 /*******************************************************************************
2777  *
2778  * Function         l2cu_send_peer_ble_par_rsp
2779  *
2780  * Description      Build and send a BLE parameter update response message
2781  *                  to the peer.
2782  *
2783  * Returns          void
2784  *
2785  ******************************************************************************/
l2cu_send_peer_ble_par_rsp(tL2C_LCB * p_lcb,uint16_t reason,uint8_t rem_id)2786 void l2cu_send_peer_ble_par_rsp(tL2C_LCB* p_lcb, uint16_t reason,
2787                                 uint8_t rem_id) {
2788   BT_HDR* p_buf;
2789   uint8_t* p;
2790 
2791   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN,
2792                             L2CAP_CMD_BLE_UPDATE_RSP, rem_id);
2793   if (p_buf == NULL) {
2794     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_par_rsp - no buffer");
2795     return;
2796   }
2797 
2798   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2799       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2800 
2801   UINT16_TO_STREAM(p, reason);
2802 
2803   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2804 }
2805 
2806 /*******************************************************************************
2807  *
2808  * Function         l2cu_send_peer_ble_credit_based_conn_req
2809  *
2810  * Description      Build and send a BLE packet to establish LE connection
2811  *                  oriented L2CAP channel.
2812  *
2813  * Returns          void
2814  *
2815  ******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB * p_ccb)2816 void l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB* p_ccb) {
2817   BT_HDR* p_buf;
2818   uint8_t* p;
2819   tL2C_LCB* p_lcb = NULL;
2820   uint16_t mtu;
2821   uint16_t mps;
2822   uint16_t initial_credit;
2823 
2824   if (!p_ccb) return;
2825   p_lcb = p_ccb->p_lcb;
2826 
2827   /* Create an identifier for this packet */
2828   p_ccb->p_lcb->id++;
2829   l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
2830 
2831   p_ccb->local_id = p_ccb->p_lcb->id;
2832 
2833   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN,
2834                             L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ, p_lcb->id);
2835   if (p_buf == NULL) {
2836     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
2837     return;
2838   }
2839 
2840   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2841       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2842 
2843   mtu = p_ccb->local_conn_cfg.mtu;
2844   mps = p_ccb->local_conn_cfg.mps;
2845   initial_credit = p_ccb->local_conn_cfg.credits;
2846 
2847   L2CAP_TRACE_DEBUG(
2848       "l2cu_send_peer_ble_credit_based_conn_req PSM:0x%04x local_cid:%d\
2849                 mtu:%d mps:%d initial_credit:%d",
2850       p_ccb->p_rcb->real_psm, p_ccb->local_cid, mtu, mps, initial_credit);
2851 
2852   UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm);
2853   UINT16_TO_STREAM(p, p_ccb->local_cid);
2854   UINT16_TO_STREAM(p, mtu);
2855   UINT16_TO_STREAM(p, mps);
2856   UINT16_TO_STREAM(p, initial_credit);
2857 
2858   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2859 }
2860 
2861 /*******************************************************************************
2862  *
2863  * Function         l2cu_reject_ble_connection
2864  *
2865  * Description      Build and send an L2CAP "Credit based connection res"
2866  *                  message to the peer. This function is called for non-success
2867  *                  cases.
2868  *
2869  * Returns          void
2870  *
2871  ******************************************************************************/
l2cu_reject_ble_connection(tL2C_LCB * p_lcb,uint8_t rem_id,uint16_t result)2872 void l2cu_reject_ble_connection(tL2C_LCB* p_lcb, uint8_t rem_id,
2873                                 uint16_t result) {
2874   BT_HDR* p_buf;
2875   uint8_t* p;
2876 
2877   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
2878                             L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, rem_id);
2879   if (p_buf == NULL) {
2880     L2CAP_TRACE_WARNING("l2cu_reject_ble_connection - no buffer");
2881     return;
2882   }
2883 
2884   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2885       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2886 
2887   UINT16_TO_STREAM(p, 0); /* Local CID of 0   */
2888   UINT16_TO_STREAM(p, 0); /* MTU */
2889   UINT16_TO_STREAM(p, 0); /* MPS */
2890   UINT16_TO_STREAM(p, 0); /* initial credit */
2891   UINT16_TO_STREAM(p, result);
2892 
2893   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2894 }
2895 
2896 /*******************************************************************************
2897  *
2898  * Function         l2cu_send_peer_ble_credit_based_conn_res
2899  *
2900  * Description      Build and send an L2CAP "Credit based connection res"
2901  *                  message to the peer. This function is called in case of
2902  *                  success.
2903  *
2904  * Returns          void
2905  *
2906  ******************************************************************************/
l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB * p_ccb,uint16_t result)2907 void l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB* p_ccb,
2908                                               uint16_t result) {
2909   BT_HDR* p_buf;
2910   uint8_t* p;
2911 
2912   L2CAP_TRACE_DEBUG("l2cu_send_peer_ble_credit_based_conn_res");
2913   p_buf =
2914       l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
2915                         L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id);
2916   if (p_buf == NULL) {
2917     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_res - no buffer");
2918     return;
2919   }
2920 
2921   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2922       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2923 
2924   UINT16_TO_STREAM(p, p_ccb->local_cid);              /* Local CID */
2925   UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mtu);     /* MTU */
2926   UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.mps);     /* MPS */
2927   UINT16_TO_STREAM(p, p_ccb->local_conn_cfg.credits); /* initial credit */
2928   UINT16_TO_STREAM(p, result);
2929 
2930   l2c_link_check_send_pkts(p_ccb->p_lcb, NULL, p_buf);
2931 }
2932 
2933 /*******************************************************************************
2934  *
2935  * Function         l2cu_send_peer_ble_flow_control_credit
2936  *
2937  * Description      Build and send a BLE packet to give credits to peer device
2938  *                  for LE connection oriented L2CAP channel.
2939  *
2940  * Returns          void
2941  *
2942  ******************************************************************************/
l2cu_send_peer_ble_flow_control_credit(tL2C_CCB * p_ccb,uint16_t credit_value)2943 void l2cu_send_peer_ble_flow_control_credit(tL2C_CCB* p_ccb,
2944                                             uint16_t credit_value) {
2945   BT_HDR* p_buf;
2946   uint8_t* p;
2947   tL2C_LCB* p_lcb = NULL;
2948 
2949   if (!p_ccb) return;
2950   p_lcb = p_ccb->p_lcb;
2951 
2952   /* Create an identifier for this packet */
2953   p_ccb->p_lcb->id++;
2954   l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
2955 
2956   p_ccb->local_id = p_ccb->p_lcb->id;
2957 
2958   p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN,
2959                             L2CAP_CMD_BLE_FLOW_CTRL_CREDIT, p_lcb->id);
2960   if (p_buf == NULL) {
2961     L2CAP_TRACE_WARNING("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
2962     return;
2963   }
2964 
2965   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2966       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2967 
2968   UINT16_TO_STREAM(p, p_ccb->local_cid);
2969   UINT16_TO_STREAM(p, credit_value);
2970 
2971   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
2972 }
2973 
2974 /*******************************************************************************
2975  *
2976  * Function         l2cu_send_peer_ble_credit_based_conn_req
2977  *
2978  * Description      Build and send a BLE packet to disconnect LE connection
2979  *                  oriented L2CAP channel.
2980  *
2981  * Returns          void
2982  *
2983  ******************************************************************************/
l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB * p_ccb)2984 void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB* p_ccb) {
2985   BT_HDR* p_buf;
2986   uint8_t* p;
2987   tL2C_LCB* p_lcb = NULL;
2988   L2CAP_TRACE_DEBUG("%s", __func__);
2989 
2990   if (!p_ccb) return;
2991   p_lcb = p_ccb->p_lcb;
2992 
2993   /* Create an identifier for this packet */
2994   p_ccb->p_lcb->id++;
2995   l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
2996 
2997   p_ccb->local_id = p_ccb->p_lcb->id;
2998   p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ,
2999                             p_lcb->id);
3000   if (p_buf == NULL) {
3001     L2CAP_TRACE_WARNING(
3002         "l2cu_send_peer_ble_credit_based_disconn_req - no buffer");
3003     return;
3004   }
3005 
3006   p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3007       L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3008 
3009   UINT16_TO_STREAM(p, p_ccb->remote_cid);
3010   UINT16_TO_STREAM(p, p_ccb->local_cid);
3011 
3012   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
3013 }
3014 
3015 /*******************************************************************************
3016  * Functions used by both Full and Light Stack
3017  ******************************************************************************/
3018 
3019 /*******************************************************************************
3020  *
3021  * Function         l2cu_find_lcb_by_handle
3022  *
3023  * Description      Look through all active LCBs for a match based on the
3024  *                  HCI handle.
3025  *
3026  * Returns          pointer to matched LCB, or NULL if no match
3027  *
3028  ******************************************************************************/
l2cu_find_lcb_by_handle(uint16_t handle)3029 tL2C_LCB* l2cu_find_lcb_by_handle(uint16_t handle) {
3030   int xx;
3031   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
3032 
3033   for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
3034     if ((p_lcb->in_use) && (p_lcb->handle == handle)) {
3035       return (p_lcb);
3036     }
3037   }
3038 
3039   /* If here, no match found */
3040   return (NULL);
3041 }
3042 
3043 /*******************************************************************************
3044  *
3045  * Function         l2cu_find_ccb_by_cid
3046  *
3047  * Description      Look through all active CCBs on a link for a match based
3048  *                  on the local CID. If passed the link pointer is NULL, all
3049  *                  active links are searched.
3050  *
3051  * Returns          pointer to matched CCB, or NULL if no match
3052  *
3053  ******************************************************************************/
l2cu_find_ccb_by_cid(tL2C_LCB * p_lcb,uint16_t local_cid)3054 tL2C_CCB* l2cu_find_ccb_by_cid(tL2C_LCB* p_lcb, uint16_t local_cid) {
3055   tL2C_CCB* p_ccb = NULL;
3056   if (local_cid >= L2CAP_BASE_APPL_CID) {
3057     /* find the associated CCB by "index" */
3058     local_cid -= L2CAP_BASE_APPL_CID;
3059 
3060     if (local_cid >= MAX_L2CAP_CHANNELS) return NULL;
3061 
3062     p_ccb = l2cb.ccb_pool + local_cid;
3063 
3064     /* make sure the CCB is in use */
3065     if (!p_ccb->in_use) {
3066       p_ccb = NULL;
3067     }
3068     /* make sure it's for the same LCB */
3069     else if (p_lcb && p_lcb != p_ccb->p_lcb) {
3070       p_ccb = NULL;
3071     }
3072   }
3073   return (p_ccb);
3074 }
3075 
3076 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3077 
3078 /******************************************************************************
3079  *
3080  * Function         l2cu_get_next_channel_in_rr
3081  *
3082  * Description      get the next channel to send on a link. It also adjusts the
3083  *                  CCB queue to do a basic priority and round-robin scheduling.
3084  *
3085  * Returns          pointer to CCB or NULL
3086  *
3087  ******************************************************************************/
l2cu_get_next_channel_in_rr(tL2C_LCB * p_lcb)3088 static tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) {
3089   tL2C_CCB* p_serve_ccb = NULL;
3090   tL2C_CCB* p_ccb;
3091 
3092   int i, j;
3093 
3094   /* scan all of priority until finding a channel to serve */
3095   for (i = 0; (i < L2CAP_NUM_CHNL_PRIORITY) && (!p_serve_ccb); i++) {
3096     /* scan all channel within serving priority group until finding a channel to
3097      * serve */
3098     for (j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb) && (!p_serve_ccb);
3099          j++) {
3100       /* scaning from next serving channel */
3101       p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
3102 
3103       if (!p_ccb) {
3104         L2CAP_TRACE_ERROR("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
3105         return NULL;
3106       }
3107 
3108       L2CAP_TRACE_DEBUG("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
3109                         p_ccb->ccb_priority, p_ccb->local_cid,
3110                         fixed_queue_length(p_ccb->xmit_hold_q));
3111 
3112       /* store the next serving channel */
3113       /* this channel is the last channel of its priority group */
3114       if ((p_ccb->p_next_ccb == NULL) ||
3115           (p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority)) {
3116         /* next serving channel is set to the first channel in the group */
3117         p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb =
3118             p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb;
3119       } else {
3120         /* next serving channel is set to the next channel in the group */
3121         p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
3122       }
3123 
3124       if (p_ccb->chnl_state != CST_OPEN) continue;
3125 
3126       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3127         L2CAP_TRACE_DEBUG("%s : Connection oriented channel", __func__);
3128         if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3129 
3130       } else {
3131         /* eL2CAP option in use */
3132         if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3133           if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) continue;
3134 
3135           if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
3136             if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3137 
3138             /* If in eRTM mode, check for window closure */
3139             if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
3140                 (l2c_fcr_is_flow_controlled(p_ccb)))
3141               continue;
3142           }
3143         } else {
3144           if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3145         }
3146       }
3147 
3148       /* found a channel to serve */
3149       p_serve_ccb = p_ccb;
3150       /* decrease quota of its priority group */
3151       p_lcb->rr_serv[p_lcb->rr_pri].quota--;
3152     }
3153 
3154     /* if there is no more quota of the priority group or no channel to have
3155      * data to send */
3156     if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0) || (!p_serve_ccb)) {
3157       /* serve next priority group */
3158       p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
3159       /* initialize its quota */
3160       p_lcb->rr_serv[p_lcb->rr_pri].quota =
3161           L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
3162     }
3163   }
3164 
3165   if (p_serve_ccb) {
3166     L2CAP_TRACE_DEBUG("RR service pri=%d, quota=%d, lcid=0x%04x",
3167                       p_serve_ccb->ccb_priority,
3168                       p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
3169                       p_serve_ccb->local_cid);
3170   }
3171 
3172   return p_serve_ccb;
3173 }
3174 
3175 #else  /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3176 
3177 /******************************************************************************
3178  *
3179  * Function         l2cu_get_next_channel
3180  *
3181  * Description      get the next channel to send on a link bassed on priority
3182  *                  scheduling.
3183  *
3184  * Returns          pointer to CCB or NULL
3185  *
3186  ******************************************************************************/
l2cu_get_next_channel(tL2C_LCB * p_lcb)3187 static tL2C_CCB* l2cu_get_next_channel(tL2C_LCB* p_lcb) {
3188   tL2C_CCB* p_ccb;
3189 
3190   /* Get the first CCB with data to send.
3191   */
3192   for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
3193     if (p_ccb->chnl_state != CST_OPEN) continue;
3194 
3195     if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) continue;
3196 
3197     if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) return p_ccb;
3198 
3199     if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3200 
3201     /* If in eRTM mode, check for window closure */
3202     if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
3203         (l2c_fcr_is_flow_controlled(p_ccb)))
3204       continue;
3205 
3206     /* If here, we found someone */
3207     return p_ccb;
3208   }
3209 
3210   return NULL;
3211 }
3212 #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3213 
l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO * p_cbi)3214 void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
3215   if (p_cbi->cb != NULL) p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu);
3216 }
3217 
3218 /******************************************************************************
3219  *
3220  * Function         l2cu_get_next_buffer_to_send
3221  *
3222  * Description      get the next buffer to send on a link. It also adjusts the
3223  *                  CCB queue to do a basic priority and round-robin scheduling.
3224  *
3225  * Returns          pointer to buffer or NULL
3226  *
3227  ******************************************************************************/
l2cu_get_next_buffer_to_send(tL2C_LCB * p_lcb,tL2C_TX_COMPLETE_CB_INFO * p_cbi)3228 BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb,
3229                                      tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
3230   tL2C_CCB* p_ccb;
3231   BT_HDR* p_buf;
3232 
3233 /* Highest priority are fixed channels */
3234 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3235   int xx;
3236 
3237   p_cbi->cb = NULL;
3238 
3239   for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
3240     p_ccb = p_lcb->p_fixed_ccbs[xx];
3241     if (p_ccb == NULL) continue;
3242 
3243     /* eL2CAP option in use */
3244     if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3245       if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy) continue;
3246 
3247       /* No more checks needed if sending from the reatransmit queue */
3248       if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q)) {
3249         if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue;
3250 
3251         /* If in eRTM mode, check for window closure */
3252         if ((p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) &&
3253             (l2c_fcr_is_flow_controlled(p_ccb)))
3254           continue;
3255       }
3256 
3257       p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0);
3258       if (p_buf != NULL) {
3259         l2cu_check_channel_congestion(p_ccb);
3260         l2cu_set_acl_hci_header(p_buf, p_ccb);
3261         return (p_buf);
3262       }
3263     } else {
3264       if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) {
3265         p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
3266         if (NULL == p_buf) {
3267           L2CAP_TRACE_ERROR("%s: No data to be sent", __func__);
3268           return (NULL);
3269         }
3270 
3271         /* Prepare callback info for TX completion */
3272         p_cbi->cb = l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb;
3273         p_cbi->local_cid = p_ccb->local_cid;
3274         p_cbi->num_sdu = 1;
3275 
3276         l2cu_check_channel_congestion(p_ccb);
3277         l2cu_set_acl_hci_header(p_buf, p_ccb);
3278         return (p_buf);
3279       }
3280     }
3281   }
3282 #endif
3283 
3284 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3285   /* get next serving channel in round-robin */
3286   p_ccb = l2cu_get_next_channel_in_rr(p_lcb);
3287 #else
3288   p_ccb = l2cu_get_next_channel(p_lcb);
3289 #endif
3290 
3291   /* Return if no buffer */
3292   if (p_ccb == NULL) return (NULL);
3293 
3294   if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3295     /* Check credits */
3296     if (p_ccb->peer_conn_cfg.credits == 0) {
3297       L2CAP_TRACE_DEBUG("%s No credits to send packets", __func__);
3298       return NULL;
3299     }
3300 
3301     bool last_piece_of_sdu = false;
3302     p_buf = l2c_lcc_get_next_xmit_sdu_seg(p_ccb, &last_piece_of_sdu);
3303     p_ccb->peer_conn_cfg.credits--;
3304 
3305     if (last_piece_of_sdu) {
3306       // TODO: send callback up the stack. Investigate setting p_cbi->cb to
3307       // notify after controller ack send.
3308     }
3309 
3310   } else {
3311     if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
3312       p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0);
3313       if (p_buf == NULL) return (NULL);
3314     } else {
3315       p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
3316       if (NULL == p_buf) {
3317         L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send() #2: No data to be sent");
3318         return (NULL);
3319       }
3320     }
3321   }
3322 
3323   if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_TxComplete_Cb &&
3324       (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE))
3325     (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
3326 
3327   l2cu_check_channel_congestion(p_ccb);
3328 
3329   l2cu_set_acl_hci_header(p_buf, p_ccb);
3330 
3331   return (p_buf);
3332 }
3333 
3334 /******************************************************************************
3335  *
3336  * Function         l2cu_set_acl_hci_header
3337  *
3338  * Description      Set HCI handle for ACL packet
3339  *
3340  * Returns          None
3341  *
3342  ******************************************************************************/
l2cu_set_acl_hci_header(BT_HDR * p_buf,tL2C_CCB * p_ccb)3343 void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb) {
3344   uint8_t* p;
3345 
3346   /* Set the pointer to the beginning of the data minus 4 bytes for the packet
3347    * header */
3348   p = (uint8_t*)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
3349 
3350   if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
3351     UINT16_TO_STREAM(p, p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE
3352                                                 << L2CAP_PKT_TYPE_SHIFT));
3353 
3354     uint16_t acl_data_size =
3355         controller_get_interface()->get_acl_data_size_ble();
3356     /* The HCI transport will segment the buffers. */
3357     if (p_buf->len > acl_data_size) {
3358       UINT16_TO_STREAM(p, acl_data_size);
3359     } else {
3360       UINT16_TO_STREAM(p, p_buf->len);
3361     }
3362   } else {
3363 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3364     if ((((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) ==
3365           L2CAP_FLUSHABLE_CH_BASED) &&
3366          (p_ccb->is_flushable)) ||
3367         ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) ==
3368          L2CAP_FLUSHABLE_PKT)) {
3369       UINT16_TO_STREAM(
3370           p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3371     } else {
3372       UINT16_TO_STREAM(p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
3373     }
3374 #else
3375     UINT16_TO_STREAM(
3376         p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3377 #endif
3378 
3379     uint16_t acl_data_size =
3380         controller_get_interface()->get_acl_data_size_classic();
3381     /* The HCI transport will segment the buffers. */
3382     if (p_buf->len > acl_data_size) {
3383       UINT16_TO_STREAM(p, acl_data_size);
3384     } else {
3385       UINT16_TO_STREAM(p, p_buf->len);
3386     }
3387   }
3388   p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
3389   p_buf->len += HCI_DATA_PREAMBLE_SIZE;
3390 }
3391 
send_congestion_status_to_all_clients(tL2C_CCB * p_ccb,bool status)3392 static void send_congestion_status_to_all_clients(tL2C_CCB* p_ccb,
3393                                                   bool status) {
3394   p_ccb->cong_sent = status;
3395 
3396   if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) {
3397     L2CAP_TRACE_DEBUG(
3398         "L2CAP - Calling CongestionStatus_Cb (%d), CID: 0x%04x "
3399         "xmit_hold_q.count: %u  buff_quota: %u",
3400         status, p_ccb->local_cid, fixed_queue_length(p_ccb->xmit_hold_q),
3401         p_ccb->buff_quota);
3402 
3403     /* Prevent recursive calling */
3404     if (status == false) l2cb.is_cong_cback_context = true;
3405 
3406     (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, status);
3407 
3408     if (status == false) l2cb.is_cong_cback_context = false;
3409   }
3410 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3411   else {
3412     for (uint8_t xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) {
3413       if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb) {
3414         if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3415           (*l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr,
3416                                                    status);
3417         break;
3418       }
3419     }
3420   }
3421 #endif
3422 }
3423 
3424 /* check if any change in congestion status */
l2cu_check_channel_congestion(tL2C_CCB * p_ccb)3425 void l2cu_check_channel_congestion(tL2C_CCB* p_ccb) {
3426   /* If the CCB queue limit is subject to a quota, check for congestion if this
3427    * channel has outgoing traffic */
3428   if (p_ccb->buff_quota == 0) return;
3429 
3430   size_t q_count = fixed_queue_length(p_ccb->xmit_hold_q);
3431 
3432   if (p_ccb->cong_sent) {
3433     /* if channel was congested, but is not congested now, tell the app */
3434     if (q_count <= (p_ccb->buff_quota / 2))
3435       send_congestion_status_to_all_clients(p_ccb, false);
3436   } else {
3437     /* if channel was not congested, but is congested now, tell the app */
3438     if (q_count > p_ccb->buff_quota)
3439       send_congestion_status_to_all_clients(p_ccb, true);
3440   }
3441 }
3442 
3443 /*******************************************************************************
3444  *
3445  * Function         l2cu_is_ccb_active
3446  *
3447  * Description      Check if Channel Control Block is in use or released
3448  *
3449  * Returns          bool    - true if Channel Control Block is in use
3450  *                            false if p_ccb is null or is released.
3451  *
3452  ******************************************************************************/
l2cu_is_ccb_active(tL2C_CCB * p_ccb)3453 bool l2cu_is_ccb_active(tL2C_CCB* p_ccb) { return (p_ccb && p_ccb->in_use); }
3454