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