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