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