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