1 /******************************************************************************
2  *
3  *  Copyright (C) 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 the L2CAP API code
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bt_l2cap"
26 
27 #include <base/logging.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "bt_common.h"
33 #include "bt_types.h"
34 #include "btm_api.h"
35 #include "btu.h"
36 #include "device/include/controller.h"
37 #include "hcidefs.h"
38 #include "hcimsgs.h"
39 #include "l2c_int.h"
40 #include "l2cdefs.h"
41 #include "osi/include/allocator.h"
42 #include "osi/include/log.h"
43 
44 extern fixed_queue_t* btu_general_alarm_queue;
45 
46 /*******************************************************************************
47  *
48  * Function         L2CA_Register
49  *
50  * Description      Other layers call this function to register for L2CAP
51  *                  services.
52  *
53  * Returns          PSM to use or zero if error. Typically, the PSM returned
54  *                  is the same as was passed in, but for an outgoing-only
55  *                  connection to a dynamic PSM, a "virtual" PSM is returned
56  *                  and should be used in the calls to L2CA_ConnectReq(),
57  *                  L2CA_ErtmConnectReq() and L2CA_Deregister()
58  *
59  ******************************************************************************/
L2CA_Register(uint16_t psm,tL2CAP_APPL_INFO * p_cb_info)60 uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) {
61   tL2C_RCB* p_rcb;
62   uint16_t vpsm = psm;
63 
64   L2CAP_TRACE_API("L2CAP - L2CA_Register() called for PSM: 0x%04x", psm);
65 
66   /* Verify that the required callback info has been filled in
67   **      Note:  Connection callbacks are required but not checked
68   **             for here because it is possible to be only a client
69   **             or only a server.
70   */
71   if ((!p_cb_info->pL2CA_ConfigCfm_Cb) || (!p_cb_info->pL2CA_ConfigInd_Cb) ||
72       (!p_cb_info->pL2CA_DataInd_Cb) || (!p_cb_info->pL2CA_DisconnectInd_Cb)) {
73     L2CAP_TRACE_ERROR("L2CAP - no cb registering PSM: 0x%04x", psm);
74     return (0);
75   }
76 
77   /* Verify PSM is valid */
78   if (L2C_INVALID_PSM(psm)) {
79     L2CAP_TRACE_ERROR("L2CAP - invalid PSM value, PSM: 0x%04x", psm);
80     return (0);
81   }
82 
83   /* Check if this is a registration for an outgoing-only connection to */
84   /* a dynamic PSM. If so, allocate a "virtual" PSM for the app to use. */
85   if ((psm >= 0x1001) && (p_cb_info->pL2CA_ConnectInd_Cb == NULL)) {
86     for (vpsm = 0x1002; vpsm < 0x8000; vpsm += 2) {
87       p_rcb = l2cu_find_rcb_by_psm(vpsm);
88       if (p_rcb == NULL) break;
89     }
90 
91     L2CAP_TRACE_API("L2CA_Register - Real PSM: 0x%04x  Virtual PSM: 0x%04x",
92                     psm, vpsm);
93   }
94 
95   /* If registration block already there, just overwrite it */
96   p_rcb = l2cu_find_rcb_by_psm(vpsm);
97   if (p_rcb == NULL) {
98     p_rcb = l2cu_allocate_rcb(vpsm);
99     if (p_rcb == NULL) {
100       L2CAP_TRACE_WARNING("L2CAP - no RCB available, PSM: 0x%04x  vPSM: 0x%04x",
101                           psm, vpsm);
102       return (0);
103     }
104   }
105 
106   p_rcb->api = *p_cb_info;
107   p_rcb->real_psm = psm;
108 
109   return (vpsm);
110 }
111 
112 /*******************************************************************************
113  *
114  * Function         L2CA_Deregister
115  *
116  * Description      Other layers call this function to de-register for L2CAP
117  *                  services.
118  *
119  * Returns          void
120  *
121  ******************************************************************************/
L2CA_Deregister(uint16_t psm)122 void L2CA_Deregister(uint16_t psm) {
123   tL2C_RCB* p_rcb;
124   tL2C_CCB* p_ccb;
125   tL2C_LCB* p_lcb;
126   int ii;
127 
128   L2CAP_TRACE_API("L2CAP - L2CA_Deregister() called for PSM: 0x%04x", psm);
129 
130   p_rcb = l2cu_find_rcb_by_psm(psm);
131   if (p_rcb != NULL) {
132     p_lcb = &l2cb.lcb_pool[0];
133     for (ii = 0; ii < MAX_L2CAP_LINKS; ii++, p_lcb++) {
134       if (p_lcb->in_use) {
135         p_ccb = p_lcb->ccb_queue.p_first_ccb;
136         if ((p_ccb == NULL) || (p_lcb->link_state == LST_DISCONNECTING)) {
137           continue;
138         }
139 
140         if ((p_ccb->in_use) &&
141             ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
142              (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) {
143           continue;
144         }
145 
146         if (p_ccb->p_rcb == p_rcb) {
147           l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
148         }
149       }
150     }
151     l2cu_release_rcb(p_rcb);
152   } else {
153     L2CAP_TRACE_WARNING("L2CAP - PSM: 0x%04x not found for deregistration",
154                         psm);
155   }
156 }
157 
158 /*******************************************************************************
159  *
160  * Function         L2CA_AllocatePSM
161  *
162  * Description      Other layers call this function to find an unused PSM for
163  *                  L2CAP services.
164  *
165  * Returns          PSM to use.
166  *
167  ******************************************************************************/
L2CA_AllocatePSM(void)168 uint16_t L2CA_AllocatePSM(void) {
169   bool done = false;
170   uint16_t psm = l2cb.dyn_psm;
171 
172   L2CAP_TRACE_API("L2CA_AllocatePSM");
173   while (!done) {
174     psm += 2;
175     if (psm > 0xfeff) {
176       psm = 0x1001;
177     } else if (psm & 0x0100) {
178       /* the upper byte must be even */
179       psm += 0x0100;
180     }
181 
182     /* if psm is in range of reserved BRCM Aware features */
183     if ((BRCM_RESERVED_PSM_START <= psm) && (psm <= BRCM_RESERVED_PSM_END))
184       continue;
185 
186     /* make sure the newlly allocated psm is not used right now */
187     if ((l2cu_find_rcb_by_psm(psm)) == NULL) done = true;
188   }
189   l2cb.dyn_psm = psm;
190 
191   return (psm);
192 }
193 
194 /*******************************************************************************
195  *
196  * Function         L2CA_ConnectReq
197  *
198  * Description      Higher layers call this function to create an L2CAP
199  *                  connection. Note that the connection is not established at
200  *                  this time, but connection establishment gets started. The
201  *                  callback function will be invoked when connection
202  *                  establishes or fails.
203  *
204  * Returns          the CID of the connection, or 0 if it failed to start
205  *
206  ******************************************************************************/
L2CA_ConnectReq(uint16_t psm,BD_ADDR p_bd_addr)207 uint16_t L2CA_ConnectReq(uint16_t psm, BD_ADDR p_bd_addr) {
208   return L2CA_ErtmConnectReq(psm, p_bd_addr, NULL);
209 }
210 
211 /*******************************************************************************
212  *
213  * Function         L2CA_ErtmConnectReq
214  *
215  * Description      Higher layers call this function to create an L2CAP
216  *                  connection. Note that the connection is not established at
217  *                  this time, but connection establishment gets started. The
218  *                  callback function will be invoked when connection
219  *                  establishes or fails.
220  *
221  *  Parameters:       PSM: L2CAP PSM for the connection
222  *                    BD address of the peer
223  *                   Enhaced retransmission mode configurations
224 
225  * Returns          the CID of the connection, or 0 if it failed to start
226  *
227  ******************************************************************************/
L2CA_ErtmConnectReq(uint16_t psm,BD_ADDR p_bd_addr,tL2CAP_ERTM_INFO * p_ertm_info)228 uint16_t L2CA_ErtmConnectReq(uint16_t psm, BD_ADDR p_bd_addr,
229                              tL2CAP_ERTM_INFO* p_ertm_info) {
230   tL2C_LCB* p_lcb;
231   tL2C_CCB* p_ccb;
232   tL2C_RCB* p_rcb;
233 
234   L2CAP_TRACE_API(
235       "L2CA_ErtmConnectReq()  PSM: 0x%04x  BDA: %08x%04x  p_ertm_info: 0x%08x "
236       "allowed:0x%x preferred:%d",
237       psm, (p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) +
238                p_bd_addr[3],
239       (p_bd_addr[4] << 8) + p_bd_addr[5], p_ertm_info,
240       (p_ertm_info) ? p_ertm_info->allowed_modes : 0,
241       (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
242 
243   /* Fail if we have not established communications with the controller */
244   if (!BTM_IsDeviceUp()) {
245     L2CAP_TRACE_WARNING("L2CAP connect req - BTU not ready");
246     return (0);
247   }
248   /* Fail if the PSM is not registered */
249   p_rcb = l2cu_find_rcb_by_psm(psm);
250   if (p_rcb == NULL) {
251     L2CAP_TRACE_WARNING("L2CAP - no RCB for L2CA_conn_req, PSM: 0x%04x", psm);
252     return (0);
253   }
254 
255   /* First, see if we already have a link to the remote */
256   /* assume all ERTM l2cap connection is going over BR/EDR for now */
257   p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
258   if (p_lcb == NULL) {
259     /* No link. Get an LCB and start link establishment */
260     p_lcb = l2cu_allocate_lcb(p_bd_addr, false, BT_TRANSPORT_BR_EDR);
261     /* currently use BR/EDR for ERTM mode l2cap connection */
262     if ((p_lcb == NULL) ||
263         (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == false)) {
264       L2CAP_TRACE_WARNING(
265           "L2CAP - conn not started for PSM: 0x%04x  p_lcb: 0x%08x", psm,
266           p_lcb);
267       return (0);
268     }
269   }
270 
271   /* Allocate a channel control block */
272   p_ccb = l2cu_allocate_ccb(p_lcb, 0);
273   if (p_ccb == NULL) {
274     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_conn_req, PSM: 0x%04x", psm);
275     return (0);
276   }
277 
278   /* Save registration info */
279   p_ccb->p_rcb = p_rcb;
280 
281   if (p_ertm_info) {
282     p_ccb->ertm_info = *p_ertm_info;
283 
284     /* Replace default indicators with the actual default pool */
285     if (p_ccb->ertm_info.fcr_rx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
286       p_ccb->ertm_info.fcr_rx_buf_size = L2CAP_FCR_RX_BUF_SIZE;
287 
288     if (p_ccb->ertm_info.fcr_tx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
289       p_ccb->ertm_info.fcr_tx_buf_size = L2CAP_FCR_TX_BUF_SIZE;
290 
291     if (p_ccb->ertm_info.user_rx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
292       p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE;
293 
294     if (p_ccb->ertm_info.user_tx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
295       p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
296 
297     p_ccb->max_rx_mtu =
298         p_ertm_info->user_rx_buf_size -
299         (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
300   }
301 
302   /* If link is up, start the L2CAP connection */
303   if (p_lcb->link_state == LST_CONNECTED) {
304     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_REQ, NULL);
305   }
306 
307   /* If link is disconnecting, save link info to retry after disconnect
308    * Possible Race condition when a reconnect occurs
309    * on the channel during a disconnect of link. This
310    * ccb will be automatically retried after link disconnect
311    * arrives
312    */
313   else if (p_lcb->link_state == LST_DISCONNECTING) {
314     L2CAP_TRACE_DEBUG("L2CAP API - link disconnecting: RETRY LATER");
315 
316     /* Save ccb so it can be started after disconnect is finished */
317     p_lcb->p_pending_ccb = p_ccb;
318   }
319 
320   L2CAP_TRACE_API("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x",
321                   psm, p_ccb->local_cid);
322 
323   /* Return the local CID as our handle */
324   return (p_ccb->local_cid);
325 }
326 
327 /*******************************************************************************
328  *
329  * Function         L2CA_RegisterLECoc
330  *
331  * Description      Other layers call this function to register for L2CAP
332  *                  Connection Oriented Channel.
333  *
334  * Returns          PSM to use or zero if error. Typically, the PSM returned
335  *                  is the same as was passed in, but for an outgoing-only
336  *                  connection to a dynamic PSM, a "virtual" PSM is returned
337  *                  and should be used in the calls to L2CA_ConnectLECocReq()
338  *                  and L2CA_DeregisterLECoc()
339  *
340  ******************************************************************************/
L2CA_RegisterLECoc(uint16_t psm,tL2CAP_APPL_INFO * p_cb_info)341 uint16_t L2CA_RegisterLECoc(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) {
342   L2CAP_TRACE_API("%s called for LE PSM: 0x%04x", __func__, psm);
343 
344   /* Verify that the required callback info has been filled in
345   **      Note:  Connection callbacks are required but not checked
346   **             for here because it is possible to be only a client
347   **             or only a server.
348   */
349   if ((!p_cb_info->pL2CA_DataInd_Cb) || (!p_cb_info->pL2CA_DisconnectInd_Cb)) {
350     L2CAP_TRACE_ERROR("%s No cb registering BLE PSM: 0x%04x", __func__, psm);
351     return 0;
352   }
353 
354   /* Verify PSM is valid */
355   if (!L2C_IS_VALID_LE_PSM(psm)) {
356     L2CAP_TRACE_ERROR("%s Invalid BLE PSM value, PSM: 0x%04x", __func__, psm);
357     return 0;
358   }
359 
360   tL2C_RCB* p_rcb;
361   uint16_t vpsm = psm;
362 
363   /* Check if this is a registration for an outgoing-only connection to */
364   /* a dynamic PSM. If so, allocate a "virtual" PSM for the app to use. */
365   if ((psm >= 0x0080) && (p_cb_info->pL2CA_ConnectInd_Cb == NULL)) {
366     for (vpsm = 0x0080; vpsm < 0x0100; vpsm++) {
367       p_rcb = l2cu_find_ble_rcb_by_psm(vpsm);
368       if (p_rcb == NULL) break;
369     }
370 
371     L2CAP_TRACE_API("%s Real PSM: 0x%04x  Virtual PSM: 0x%04x", __func__, psm,
372                     vpsm);
373   }
374 
375   /* If registration block already there, just overwrite it */
376   p_rcb = l2cu_find_ble_rcb_by_psm(vpsm);
377   if (p_rcb == NULL) {
378     p_rcb = l2cu_allocate_ble_rcb(vpsm);
379     if (p_rcb == NULL) {
380       L2CAP_TRACE_WARNING("%s No BLE RCB available, PSM: 0x%04x  vPSM: 0x%04x",
381                           __func__, psm, vpsm);
382       return 0;
383     }
384   }
385 
386   p_rcb->api = *p_cb_info;
387   p_rcb->real_psm = psm;
388 
389   return vpsm;
390 }
391 
392 /*******************************************************************************
393  *
394  * Function         L2CA_DeregisterLECoc
395  *
396  * Description      Other layers call this function to de-register for L2CAP
397  *                  Connection Oriented Channel.
398  *
399  * Returns          void
400  *
401  ******************************************************************************/
L2CA_DeregisterLECoc(uint16_t psm)402 void L2CA_DeregisterLECoc(uint16_t psm) {
403   L2CAP_TRACE_API("%s called for PSM: 0x%04x", __func__, psm);
404 
405   tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm);
406   if (p_rcb == NULL) {
407     L2CAP_TRACE_WARNING("%s PSM: 0x%04x not found for deregistration", psm);
408     return;
409   }
410 
411   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
412   for (int i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
413     if (!p_lcb->in_use || p_lcb->transport != BT_TRANSPORT_LE) continue;
414 
415     tL2C_CCB* p_ccb = p_lcb->ccb_queue.p_first_ccb;
416     if ((p_ccb == NULL) || (p_lcb->link_state == LST_DISCONNECTING)) continue;
417 
418     if (p_ccb->in_use && (p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP ||
419                           p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))
420       continue;
421 
422     if (p_ccb->p_rcb == p_rcb)
423       l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
424   }
425 
426   l2cu_release_rcb(p_rcb);
427 }
428 
429 /*******************************************************************************
430  *
431  * Function         L2CA_ConnectLECocReq
432  *
433  * Description      Higher layers call this function to create an L2CAP
434  *                  connection. Note that the connection is not established at
435  *                  this time, but connection establishment gets started. The
436  *                  callback function will be invoked when connection
437  *                  establishes or fails.
438  *
439  *  Parameters:     PSM: L2CAP PSM for the connection
440  *                  BD address of the peer
441  *                  Local Coc configurations
442 
443  * Returns          the CID of the connection, or 0 if it failed to start
444  *
445  ******************************************************************************/
L2CA_ConnectLECocReq(uint16_t psm,BD_ADDR p_bd_addr,tL2CAP_LE_CFG_INFO * p_cfg)446 uint16_t L2CA_ConnectLECocReq(uint16_t psm, BD_ADDR p_bd_addr,
447                               tL2CAP_LE_CFG_INFO* p_cfg) {
448   L2CAP_TRACE_API("%s PSM: 0x%04x BDA: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
449                   psm, p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3],
450                   p_bd_addr[4], p_bd_addr[5]);
451 
452   /* Fail if we have not established communications with the controller */
453   if (!BTM_IsDeviceUp()) {
454     L2CAP_TRACE_WARNING("%s BTU not ready", __func__);
455     return 0;
456   }
457 
458   /* Fail if the PSM is not registered */
459   tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm);
460   if (p_rcb == NULL) {
461     L2CAP_TRACE_WARNING("%s No BLE RCB, PSM: 0x%04x", __func__, psm);
462     return 0;
463   }
464 
465   /* First, see if we already have a le link to the remote */
466   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE);
467   if (p_lcb == NULL) {
468     /* No link. Get an LCB and start link establishment */
469     p_lcb = l2cu_allocate_lcb(p_bd_addr, false, BT_TRANSPORT_LE);
470     if ((p_lcb == NULL)
471         /* currently use BR/EDR for ERTM mode l2cap connection */
472         || (l2cu_create_conn(p_lcb, BT_TRANSPORT_LE) == false)) {
473       L2CAP_TRACE_WARNING("%s conn not started for PSM: 0x%04x  p_lcb: 0x%08x",
474                           __func__, psm, p_lcb);
475       return 0;
476     }
477   }
478 
479   /* Allocate a channel control block */
480   tL2C_CCB* p_ccb = l2cu_allocate_ccb(p_lcb, 0);
481   if (p_ccb == NULL) {
482     L2CAP_TRACE_WARNING("%s no CCB, PSM: 0x%04x", __func__, psm);
483     return 0;
484   }
485 
486   /* Save registration info */
487   p_ccb->p_rcb = p_rcb;
488 
489   /* Save the configuration */
490   if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO));
491 
492   /* If link is up, start the L2CAP connection */
493   if (p_lcb->link_state == LST_CONNECTED) {
494     if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
495       L2CAP_TRACE_DEBUG("%s LE Link is up", __func__);
496       l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_REQ, NULL);
497     }
498   }
499 
500   /* If link is disconnecting, save link info to retry after disconnect
501    * Possible Race condition when a reconnect occurs
502    * on the channel during a disconnect of link. This
503    * ccb will be automatically retried after link disconnect
504    * arrives
505    */
506   else if (p_lcb->link_state == LST_DISCONNECTING) {
507     L2CAP_TRACE_DEBUG("%s link disconnecting: RETRY LATER", __func__);
508 
509     /* Save ccb so it can be started after disconnect is finished */
510     p_lcb->p_pending_ccb = p_ccb;
511   }
512 
513   L2CAP_TRACE_API("%s(psm: 0x%04x) returned CID: 0x%04x", __func__, psm,
514                   p_ccb->local_cid);
515 
516   /* Return the local CID as our handle */
517   return p_ccb->local_cid;
518 }
519 
520 /*******************************************************************************
521  *
522  * Function         L2CA_ConnectLECocRsp
523  *
524  * Description      Higher layers call this function to accept an incoming
525  *                  L2CAP COC connection, for which they had gotten an connect
526  *                  indication callback.
527  *
528  * Returns          true for success, false for failure
529  *
530  ******************************************************************************/
L2CA_ConnectLECocRsp(BD_ADDR p_bd_addr,uint8_t id,uint16_t lcid,uint16_t result,uint16_t status,tL2CAP_LE_CFG_INFO * p_cfg)531 bool L2CA_ConnectLECocRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
532                           uint16_t result, uint16_t status,
533                           tL2CAP_LE_CFG_INFO* p_cfg) {
534   L2CAP_TRACE_API(
535       "%s CID: 0x%04x Result: %d Status: %d BDA: %02x:%02x:%02x:%02x:%02x:%02x",
536       __func__, lcid, result, status, p_bd_addr[0], p_bd_addr[1], p_bd_addr[2],
537       p_bd_addr[3], p_bd_addr[4], p_bd_addr[5]);
538 
539   /* First, find the link control block */
540   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE);
541   if (p_lcb == NULL) {
542     /* No link. Get an LCB and start link establishment */
543     L2CAP_TRACE_WARNING("%s no LCB", __func__);
544     return false;
545   }
546 
547   /* Now, find the channel control block */
548   tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
549   if (p_ccb == NULL) {
550     L2CAP_TRACE_WARNING("%s no CCB", __func__);
551     return false;
552   }
553 
554   /* The IDs must match */
555   if (p_ccb->remote_id != id) {
556     L2CAP_TRACE_WARNING("%s bad id. Expected: %d  Got: %d", __func__,
557                         p_ccb->remote_id, id);
558     return false;
559   }
560 
561   if (p_cfg) memcpy(&p_ccb->local_conn_cfg, p_cfg, sizeof(tL2CAP_LE_CFG_INFO));
562 
563   if (result == L2CAP_CONN_OK)
564     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
565   else {
566     tL2C_CONN_INFO conn_info;
567     memcpy(conn_info.bd_addr, p_bd_addr, BD_ADDR_LEN);
568     conn_info.l2cap_result = result;
569     conn_info.l2cap_status = status;
570     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP_NEG, &conn_info);
571   }
572 
573   return true;
574 }
575 
576 /*******************************************************************************
577  *
578  *  Function         L2CA_GetPeerLECocConfig
579  *
580  *  Description      Get a peers configuration for LE Connection Oriented
581  *                   Channel.
582  *
583  *  Parameters:      local channel id
584  *                   Pointers to peers configuration storage area
585  *
586  *  Return value:    true if peer is connected
587  *
588  ******************************************************************************/
L2CA_GetPeerLECocConfig(uint16_t lcid,tL2CAP_LE_CFG_INFO * peer_cfg)589 bool L2CA_GetPeerLECocConfig(uint16_t lcid, tL2CAP_LE_CFG_INFO* peer_cfg) {
590   L2CAP_TRACE_API("%s CID: 0x%04x", __func__, lcid);
591 
592   tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
593   if (p_ccb == NULL) {
594     L2CAP_TRACE_ERROR("%s No CCB for CID:0x%04x", __func__, lcid);
595     return false;
596   }
597 
598   if (peer_cfg != NULL)
599     memcpy(peer_cfg, &p_ccb->peer_conn_cfg, sizeof(tL2CAP_LE_CFG_INFO));
600 
601   return true;
602 }
603 
L2CA_SetConnectionCallbacks(uint16_t local_cid,const tL2CAP_APPL_INFO * callbacks)604 bool L2CA_SetConnectionCallbacks(uint16_t local_cid,
605                                  const tL2CAP_APPL_INFO* callbacks) {
606   CHECK(callbacks != NULL);
607   CHECK(callbacks->pL2CA_ConnectInd_Cb == NULL);
608   CHECK(callbacks->pL2CA_ConnectCfm_Cb != NULL);
609   CHECK(callbacks->pL2CA_ConfigInd_Cb != NULL);
610   CHECK(callbacks->pL2CA_ConfigCfm_Cb != NULL);
611   CHECK(callbacks->pL2CA_DisconnectInd_Cb != NULL);
612   CHECK(callbacks->pL2CA_DisconnectCfm_Cb != NULL);
613   CHECK(callbacks->pL2CA_CongestionStatus_Cb != NULL);
614   CHECK(callbacks->pL2CA_DataInd_Cb != NULL);
615   CHECK(callbacks->pL2CA_TxComplete_Cb != NULL);
616 
617   tL2C_CCB* channel_control_block = l2cu_find_ccb_by_cid(NULL, local_cid);
618   if (!channel_control_block) {
619     LOG_ERROR(LOG_TAG,
620               "%s no channel control block found for L2CAP LCID=0x%04x.",
621               __func__, local_cid);
622     return false;
623   }
624 
625   // We're making a connection-specific registration control block so we check
626   // if we already have a private one allocated to us on the heap. If not, we
627   // make a new allocation, mark it as heap-allocated, and inherit the fields
628   // from the old control block.
629   tL2C_RCB* registration_control_block = channel_control_block->p_rcb;
630   if (!channel_control_block->should_free_rcb) {
631     registration_control_block = (tL2C_RCB*)osi_calloc(sizeof(tL2C_RCB));
632 
633     *registration_control_block = *channel_control_block->p_rcb;
634     channel_control_block->p_rcb = registration_control_block;
635     channel_control_block->should_free_rcb = true;
636   }
637 
638   registration_control_block->api = *callbacks;
639   return true;
640 }
641 
642 /*******************************************************************************
643  *
644  * Function         L2CA_ConnectRsp
645  *
646  * Description      Higher layers call this function to accept an incoming
647  *                  L2CAP connection, for which they had gotten an connect
648  *                  indication callback.
649  *
650  * Returns          true for success, false for failure
651  *
652  ******************************************************************************/
L2CA_ConnectRsp(BD_ADDR p_bd_addr,uint8_t id,uint16_t lcid,uint16_t result,uint16_t status)653 bool L2CA_ConnectRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
654                      uint16_t result, uint16_t status) {
655   return L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result, status, NULL);
656 }
657 
658 /*******************************************************************************
659  *
660  * Function         L2CA_ErtmConnectRsp
661  *
662  * Description      Higher layers call this function to accept an incoming
663  *                  L2CAP connection, for which they had gotten an connect
664  *                  indication callback.
665  *
666  * Returns          true for success, false for failure
667  *
668  ******************************************************************************/
L2CA_ErtmConnectRsp(BD_ADDR p_bd_addr,uint8_t id,uint16_t lcid,uint16_t result,uint16_t status,tL2CAP_ERTM_INFO * p_ertm_info)669 bool L2CA_ErtmConnectRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
670                          uint16_t result, uint16_t status,
671                          tL2CAP_ERTM_INFO* p_ertm_info) {
672   tL2C_LCB* p_lcb;
673   tL2C_CCB* p_ccb;
674 
675   L2CAP_TRACE_API(
676       "L2CA_ErtmConnectRsp()  CID: 0x%04x  Result: %d  Status: %d  BDA: "
677       "%08x%04x  p_ertm_info:0x%08x",
678       lcid, result, status, (p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) +
679                                 (p_bd_addr[2] << 8) + p_bd_addr[3],
680       (p_bd_addr[4] << 8) + p_bd_addr[5], p_ertm_info);
681 
682   /* First, find the link control block */
683   p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
684   if (p_lcb == NULL) {
685     /* No link. Get an LCB and start link establishment */
686     L2CAP_TRACE_WARNING("L2CAP - no LCB for L2CA_conn_rsp");
687     return (false);
688   }
689 
690   /* Now, find the channel control block */
691   p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
692   if (p_ccb == NULL) {
693     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_conn_rsp");
694     return (false);
695   }
696 
697   /* The IDs must match */
698   if (p_ccb->remote_id != id) {
699     L2CAP_TRACE_WARNING("L2CAP - bad id in L2CA_conn_rsp. Exp: %d  Got: %d",
700                         p_ccb->remote_id, id);
701     return (false);
702   }
703 
704   if (p_ertm_info) {
705     p_ccb->ertm_info = *p_ertm_info;
706 
707     /* Replace default indicators with the actual default pool */
708     if (p_ccb->ertm_info.fcr_rx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
709       p_ccb->ertm_info.fcr_rx_buf_size = L2CAP_FCR_RX_BUF_SIZE;
710 
711     if (p_ccb->ertm_info.fcr_tx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
712       p_ccb->ertm_info.fcr_tx_buf_size = L2CAP_FCR_TX_BUF_SIZE;
713 
714     if (p_ccb->ertm_info.user_rx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
715       p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE;
716 
717     if (p_ccb->ertm_info.user_tx_buf_size == L2CAP_INVALID_ERM_BUF_SIZE)
718       p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
719 
720     p_ccb->max_rx_mtu =
721         p_ertm_info->user_rx_buf_size -
722         (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
723   }
724 
725   if (result == L2CAP_CONN_OK) {
726     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
727   } else {
728     tL2C_CONN_INFO conn_info;
729 
730     conn_info.l2cap_result = result;
731     conn_info.l2cap_status = status;
732 
733     if (result == L2CAP_CONN_PENDING)
734       l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, &conn_info);
735     else
736       l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP_NEG, &conn_info);
737   }
738 
739   return (true);
740 }
741 
742 /*******************************************************************************
743  *
744  * Function         L2CA_ConfigReq
745  *
746  * Description      Higher layers call this function to send configuration.
747  *
748  *                  Note:  The FCR options of p_cfg are not used.
749  *
750  * Returns          true if configuration sent, else false
751  *
752  ******************************************************************************/
L2CA_ConfigReq(uint16_t cid,tL2CAP_CFG_INFO * p_cfg)753 bool L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
754   tL2C_CCB* p_ccb;
755 
756   L2CAP_TRACE_API(
757       "L2CA_ConfigReq()  CID 0x%04x: fcr_present:%d (mode %d) mtu_present:%d "
758       "(%d)",
759       cid, p_cfg->fcr_present, p_cfg->fcr.mode, p_cfg->mtu_present, p_cfg->mtu);
760 
761   /* Find the channel control block. We don't know the link it is on. */
762   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
763   if (p_ccb == NULL) {
764     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_cfg_req, CID: %d", cid);
765     return (false);
766   }
767 
768   /* We need to have at least one mode type common with the peer */
769   if (!l2c_fcr_adj_our_req_options(p_ccb, p_cfg)) return (false);
770 
771   /* Don't adjust FCR options if not used */
772   if ((!p_cfg->fcr_present) || (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)) {
773     /* FCR and FCS options are not used in basic mode */
774     p_cfg->fcs_present = false;
775     p_cfg->ext_flow_spec_present = false;
776 
777     if ((p_cfg->mtu_present) && (p_cfg->mtu > L2CAP_MTU_SIZE)) {
778       L2CAP_TRACE_WARNING("L2CAP - adjust MTU: %u too large", p_cfg->mtu);
779       p_cfg->mtu = L2CAP_MTU_SIZE;
780     }
781   }
782 
783   /* Save the adjusted configuration in case it needs to be used for
784    * renegotiation */
785   p_ccb->our_cfg = *p_cfg;
786 
787   l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_REQ, p_cfg);
788 
789   return (true);
790 }
791 
792 /*******************************************************************************
793  *
794  * Function         L2CA_ConfigRsp
795  *
796  * Description      Higher layers call this function to send a configuration
797  *                  response.
798  *
799  * Returns          true if configuration response sent, else false
800  *
801  ******************************************************************************/
L2CA_ConfigRsp(uint16_t cid,tL2CAP_CFG_INFO * p_cfg)802 bool L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) {
803   tL2C_CCB* p_ccb;
804 
805   L2CAP_TRACE_API(
806       "L2CA_ConfigRsp()  CID: 0x%04x  Result: %d MTU present:%d Flush TO:%d "
807       "FCR:%d FCS:%d",
808       cid, p_cfg->result, p_cfg->mtu_present, p_cfg->flush_to_present,
809       p_cfg->fcr_present, p_cfg->fcs_present);
810 
811   /* Find the channel control block. We don't know the link it is on. */
812   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
813   if (p_ccb == NULL) {
814     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_cfg_rsp, CID: %d", cid);
815     return (false);
816   }
817 
818   if ((p_cfg->result == L2CAP_CFG_OK) || (p_cfg->result == L2CAP_CFG_PENDING))
819     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_RSP, p_cfg);
820   else {
821     p_cfg->fcr_present =
822         false; /* FCR options already negotiated before this point */
823 
824     /* Clear out any cached options that are being returned as an error
825      * (excluding FCR) */
826     if (p_cfg->mtu_present) p_ccb->peer_cfg.mtu_present = false;
827     if (p_cfg->flush_to_present) p_ccb->peer_cfg.flush_to_present = false;
828     if (p_cfg->qos_present) p_ccb->peer_cfg.qos_present = false;
829 
830     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONFIG_RSP_NEG, p_cfg);
831   }
832 
833   return (true);
834 }
835 
836 /*******************************************************************************
837  *
838  * Function         L2CA_DisconnectReq
839  *
840  * Description      Higher layers call this function to disconnect a channel.
841  *
842  * Returns          true if disconnect sent, else false
843  *
844  ******************************************************************************/
L2CA_DisconnectReq(uint16_t cid)845 bool L2CA_DisconnectReq(uint16_t cid) {
846   tL2C_CCB* p_ccb;
847 
848   L2CAP_TRACE_API("L2CA_DisconnectReq()  CID: 0x%04x", cid);
849 
850   /* Find the channel control block. We don't know the link it is on. */
851   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
852   if (p_ccb == NULL) {
853     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_disc_req, CID: %d", cid);
854     return (false);
855   }
856 
857   l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
858 
859   return (true);
860 }
861 
862 /*******************************************************************************
863  *
864  * Function         L2CA_DisconnectRsp
865  *
866  * Description      Higher layers call this function to acknowledge the
867  *                  disconnection of a channel.
868  *
869  * Returns          void
870  *
871  ******************************************************************************/
L2CA_DisconnectRsp(uint16_t cid)872 bool L2CA_DisconnectRsp(uint16_t cid) {
873   tL2C_CCB* p_ccb;
874 
875   L2CAP_TRACE_API("L2CA_DisconnectRsp()  CID: 0x%04x", cid);
876 
877   /* Find the channel control block. We don't know the link it is on. */
878   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
879   if (p_ccb == NULL) {
880     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_disc_rsp, CID: %d", cid);
881     return (false);
882   }
883 
884   l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_RSP, NULL);
885 
886   return (true);
887 }
888 
889 /*******************************************************************************
890  *
891  * Function         L2CA_Ping
892  *
893  * Description      Higher layers call this function to send an echo request.
894  *
895  * Returns          true if echo request sent, else false.
896  *
897  ******************************************************************************/
L2CA_Ping(BD_ADDR p_bd_addr,tL2CA_ECHO_RSP_CB * p_callback)898 bool L2CA_Ping(BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB* p_callback) {
899   tL2C_LCB* p_lcb;
900 
901   L2CAP_TRACE_API("L2CA_Ping()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
902                   p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3],
903                   p_bd_addr[4], p_bd_addr[5]);
904 
905   /* Fail if we have not established communications with the controller */
906   if (!BTM_IsDeviceUp()) return (false);
907 
908   /* First, see if we already have a link to the remote */
909   p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
910   if (p_lcb == NULL) {
911     /* No link. Get an LCB and start link establishment */
912     p_lcb = l2cu_allocate_lcb(p_bd_addr, false, BT_TRANSPORT_BR_EDR);
913     if (p_lcb == NULL) {
914       L2CAP_TRACE_WARNING("L2CAP - no LCB for L2CA_ping");
915       return (false);
916     }
917     if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == false) {
918       return (false);
919     }
920 
921     p_lcb->p_echo_rsp_cb = p_callback;
922 
923     return (true);
924   }
925 
926   /* We only allow 1 ping outstanding at a time */
927   if (p_lcb->p_echo_rsp_cb != NULL) {
928     L2CAP_TRACE_WARNING("L2CAP - rejected second L2CA_ping");
929     return (false);
930   }
931 
932   /* Have a link control block. If link is disconnecting, tell user to retry
933    * later */
934   if (p_lcb->link_state == LST_DISCONNECTING) {
935     L2CAP_TRACE_WARNING("L2CAP - L2CA_ping rejected - link disconnecting");
936     return (false);
937   }
938 
939   /* Save address of callback */
940   p_lcb->p_echo_rsp_cb = p_callback;
941 
942   if (p_lcb->link_state == LST_CONNECTED) {
943     l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */
944     l2cu_send_peer_echo_req(p_lcb, NULL, 0);
945     alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_ECHO_RSP_TIMEOUT_MS,
946                        l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
947   }
948 
949   return (true);
950 }
951 
952 /*******************************************************************************
953  *
954  * Function         L2CA_Echo
955  *
956  * Description      Higher layers call this function to send an echo request
957  *                  with application-specific data.
958  *
959  * Returns          true if echo request sent, else false.
960  *
961  ******************************************************************************/
L2CA_Echo(BD_ADDR p_bd_addr,BT_HDR * p_data,tL2CA_ECHO_DATA_CB * p_callback)962 bool L2CA_Echo(BD_ADDR p_bd_addr, BT_HDR* p_data,
963                tL2CA_ECHO_DATA_CB* p_callback) {
964   tL2C_LCB* p_lcb;
965   uint8_t* pp;
966 
967   L2CAP_TRACE_API("L2CA_Echo() BDA: %08X%04X",
968                   ((p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) +
969                    (p_bd_addr[2] << 8) + (p_bd_addr[3])),
970                   ((p_bd_addr[4] << 8) + (p_bd_addr[5])));
971 
972   /* Fail if we have not established communications with the controller */
973   if (!BTM_IsDeviceUp()) return (false);
974 
975   if ((memcmp(BT_BD_ANY, p_bd_addr, BD_ADDR_LEN) == 0) && (p_data == NULL)) {
976     /* Only register callback without sending message. */
977     l2cb.p_echo_data_cb = p_callback;
978     return true;
979   }
980 
981   /* We assume the upper layer will call this function only when the link is
982    * established. */
983   p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
984   if (p_lcb == NULL) {
985     L2CAP_TRACE_ERROR("L2CA_Echo ERROR : link not established");
986     return false;
987   }
988 
989   if (p_lcb->link_state != LST_CONNECTED) {
990     L2CAP_TRACE_ERROR("L2CA_Echo ERROR : link is not connected");
991     return false;
992   }
993 
994   /* Save address of callback */
995   l2cb.p_echo_data_cb = p_callback;
996 
997   /* Set the pointer to the beginning of the data */
998   pp = (uint8_t*)(p_data + 1) + p_data->offset;
999   l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */
1000   l2cu_send_peer_echo_req(p_lcb, pp, p_data->len);
1001 
1002   return (true);
1003 }
1004 
L2CA_GetIdentifiers(uint16_t lcid,uint16_t * rcid,uint16_t * handle)1005 bool L2CA_GetIdentifiers(uint16_t lcid, uint16_t* rcid, uint16_t* handle) {
1006   tL2C_CCB* control_block = l2cu_find_ccb_by_cid(NULL, lcid);
1007   if (!control_block) return false;
1008 
1009   if (rcid) *rcid = control_block->remote_cid;
1010   if (handle) *handle = control_block->p_lcb->handle;
1011 
1012   return true;
1013 }
1014 
1015 /*******************************************************************************
1016  *
1017  * Function         L2CA_SetIdleTimeout
1018  *
1019  * Description      Higher layers call this function to set the idle timeout for
1020  *                  a connection, or for all future connections. The "idle
1021  *                  timeout" is the amount of time that a connection can remain
1022  *                  up with no L2CAP channels on it. A timeout of zero means
1023  *                  that the connection will be torn down immediately when the
1024  *                  last channel is removed. A timeout of 0xFFFF means no
1025  *                  timeout. Values are in seconds.
1026  *
1027  * Returns          true if command succeeded, false if failed
1028  *
1029  * NOTE             This timeout takes effect after at least 1 channel has been
1030  *                  established and removed. L2CAP maintains its own timer from
1031  *                  whan a connection is established till the first channel is
1032  *                  set up.
1033  ******************************************************************************/
L2CA_SetIdleTimeout(uint16_t cid,uint16_t timeout,bool is_global)1034 bool L2CA_SetIdleTimeout(uint16_t cid, uint16_t timeout, bool is_global) {
1035   tL2C_CCB* p_ccb;
1036   tL2C_LCB* p_lcb;
1037 
1038   if (is_global) {
1039     l2cb.idle_timeout = timeout;
1040   } else {
1041     /* Find the channel control block. We don't know the link it is on. */
1042     p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
1043     if (p_ccb == NULL) {
1044       L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_SetIdleTimeout, CID: %d",
1045                           cid);
1046       return (false);
1047     }
1048 
1049     p_lcb = p_ccb->p_lcb;
1050 
1051     if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
1052       p_lcb->idle_timeout = timeout;
1053     else
1054       return (false);
1055   }
1056 
1057   return (true);
1058 }
1059 
1060 /*******************************************************************************
1061  *
1062  * Function         L2CA_SetIdleTimeoutByBdAddr
1063  *
1064  * Description      Higher layers call this function to set the idle timeout for
1065  *                  a connection. The "idle timeout" is the amount of time that
1066  *                  a connection can remain up with no L2CAP channels on it.
1067  *                  A timeout of zero means that the connection will be torn
1068  *                  down immediately when the last channel is removed.
1069  *                  A timeout of 0xFFFF means no timeout. Values are in seconds.
1070  *                  A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
1071  *                  then the idle timeouts for all active l2cap links will be
1072  *                  changed.
1073  *
1074  * Returns          true if command succeeded, false if failed
1075  *
1076  * NOTE             This timeout applies to all logical channels active on the
1077  *                  ACL link.
1078  ******************************************************************************/
L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr,uint16_t timeout,tBT_TRANSPORT transport)1079 bool L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, uint16_t timeout,
1080                                  tBT_TRANSPORT transport) {
1081   tL2C_LCB* p_lcb;
1082 
1083   if (memcmp(BT_BD_ANY, bd_addr, BD_ADDR_LEN)) {
1084     p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, transport);
1085     if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
1086       p_lcb->idle_timeout = timeout;
1087 
1088       if (!p_lcb->ccb_queue.p_first_ccb) l2cu_no_dynamic_ccbs(p_lcb);
1089     } else
1090       return false;
1091   } else {
1092     int xx;
1093     tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
1094 
1095     for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
1096       if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
1097         p_lcb->idle_timeout = timeout;
1098 
1099         if (!p_lcb->ccb_queue.p_first_ccb) l2cu_no_dynamic_ccbs(p_lcb);
1100       }
1101     }
1102   }
1103 
1104   return true;
1105 }
1106 
1107 /*******************************************************************************
1108  *
1109  * Function         L2CA_SetTraceLevel
1110  *
1111  * Description      This function sets the trace level for L2CAP. If called with
1112  *                  a value of 0xFF, it simply reads the current trace level.
1113  *
1114  * Returns          the new (current) trace level
1115  *
1116  ******************************************************************************/
L2CA_SetTraceLevel(uint8_t new_level)1117 uint8_t L2CA_SetTraceLevel(uint8_t new_level) {
1118   if (new_level != 0xFF) l2cb.l2cap_trace_level = new_level;
1119 
1120   return (l2cb.l2cap_trace_level);
1121 }
1122 
1123 /*******************************************************************************
1124  *
1125  * Function     L2CA_SetDesireRole
1126  *
1127  * Description  This function sets the desire role for L2CAP.
1128  *              If the new role is L2CAP_ROLE_ALLOW_SWITCH, allow switch on
1129  *              HciCreateConnection.
1130  *              If the new role is L2CAP_ROLE_DISALLOW_SWITCH, do not allow
1131  *              switch on HciCreateConnection.
1132  *
1133  *              If the new role is a valid role (HCI_ROLE_MASTER or
1134  *              HCI_ROLE_SLAVE), the desire role is set to the new value.
1135  *              Otherwise, it is not changed.
1136  *
1137  * Returns      the new (current) role
1138  *
1139  ******************************************************************************/
L2CA_SetDesireRole(uint8_t new_role)1140 uint8_t L2CA_SetDesireRole(uint8_t new_role) {
1141   L2CAP_TRACE_API("L2CA_SetDesireRole() new:x%x, disallow_switch:%d", new_role,
1142                   l2cb.disallow_switch);
1143 
1144   if (L2CAP_ROLE_CHECK_SWITCH != (L2CAP_ROLE_CHECK_SWITCH & new_role)) {
1145     /* do not process the allow_switch when both bits are set */
1146     if (new_role & L2CAP_ROLE_ALLOW_SWITCH) {
1147       l2cb.disallow_switch = false;
1148     }
1149     if (new_role & L2CAP_ROLE_DISALLOW_SWITCH) {
1150       l2cb.disallow_switch = true;
1151     }
1152   }
1153 
1154   if (new_role == HCI_ROLE_MASTER || new_role == HCI_ROLE_SLAVE)
1155     l2cb.desire_role = new_role;
1156 
1157   return (l2cb.desire_role);
1158 }
1159 
1160 /*******************************************************************************
1161  *
1162  * Function     L2CA_LocalLoopbackReq
1163  *
1164  * Description  This function sets up a CID for local loopback
1165  *
1166  * Returns      CID of 0 if none.
1167  *
1168  ******************************************************************************/
L2CA_LocalLoopbackReq(uint16_t psm,uint16_t handle,BD_ADDR p_bd_addr)1169 uint16_t L2CA_LocalLoopbackReq(uint16_t psm, uint16_t handle,
1170                                BD_ADDR p_bd_addr) {
1171   tL2C_LCB* p_lcb;
1172   tL2C_CCB* p_ccb;
1173   tL2C_RCB* p_rcb;
1174 
1175   L2CAP_TRACE_API("L2CA_LocalLoopbackReq()  PSM: %d  Handle: 0x%04x", psm,
1176                   handle);
1177 
1178   /* Fail if we have not established communications with the controller */
1179   if (!BTM_IsDeviceUp()) {
1180     L2CAP_TRACE_WARNING("L2CAP loop req - BTU not ready");
1181     return (0);
1182   }
1183 
1184   /* Fail if the PSM is not registered */
1185   p_rcb = l2cu_find_rcb_by_psm(psm);
1186   if (p_rcb == NULL) {
1187     L2CAP_TRACE_WARNING("L2CAP - no RCB for L2CA_conn_req, PSM: %d", psm);
1188     return (0);
1189   }
1190 
1191   p_lcb = l2cu_allocate_lcb(p_bd_addr, false, BT_TRANSPORT_BR_EDR);
1192   if (p_lcb == NULL) {
1193     L2CAP_TRACE_WARNING("L2CAP - no LCB for L2CA_conn_req");
1194     return (0);
1195   }
1196 
1197   p_lcb->link_state = LST_CONNECTED;
1198   p_lcb->handle = handle;
1199 
1200   /* Allocate a channel control block */
1201   p_ccb = l2cu_allocate_ccb(p_lcb, 0);
1202   if (p_ccb == NULL) {
1203     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_conn_req");
1204     return (0);
1205   }
1206 
1207   /* Save registration info */
1208   p_ccb->p_rcb = p_rcb;
1209   p_ccb->chnl_state = CST_OPEN;
1210   p_ccb->remote_cid = p_ccb->local_cid;
1211   p_ccb->config_done = CFG_DONE_MASK;
1212 
1213   /* Return the local CID as our handle */
1214   return (p_ccb->local_cid);
1215 }
1216 
1217 /*******************************************************************************
1218  *
1219  * Function         L2CA_SetAclPriority
1220  *
1221  * Description      Sets the transmission priority for a channel.
1222  *                  (For initial implementation only two values are valid.
1223  *                  L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
1224  *
1225  * Returns          true if a valid channel, else false
1226  *
1227  ******************************************************************************/
L2CA_SetAclPriority(BD_ADDR bd_addr,uint8_t priority)1228 bool L2CA_SetAclPriority(BD_ADDR bd_addr, uint8_t priority) {
1229   L2CAP_TRACE_API(
1230       "L2CA_SetAclPriority()  bdaddr: %02x%02x%02x%02x%04x, priority:%d",
1231       bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3],
1232       (bd_addr[4] << 8) + bd_addr[5], priority);
1233 
1234   return (l2cu_set_acl_priority(bd_addr, priority, false));
1235 }
1236 
1237 /*******************************************************************************
1238  *
1239  * Function         L2CA_FlowControl
1240  *
1241  * Description      Higher layers call this function to flow control a channel.
1242  *
1243  *                  data_enabled - true data flows, false data is stopped
1244  *
1245  * Returns          true if valid channel, else false
1246  *
1247  ******************************************************************************/
L2CA_FlowControl(uint16_t cid,bool data_enabled)1248 bool L2CA_FlowControl(uint16_t cid, bool data_enabled) {
1249   tL2C_CCB* p_ccb;
1250   bool on_off = !data_enabled;
1251 
1252   L2CAP_TRACE_API("L2CA_FlowControl(%d)  CID: 0x%04x", on_off, cid);
1253 
1254   /* Find the channel control block. We don't know the link it is on. */
1255   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
1256   if (p_ccb == NULL) {
1257     L2CAP_TRACE_WARNING(
1258         "L2CAP - no CCB for L2CA_FlowControl, CID: 0x%04x  data_enabled: %d",
1259         cid, data_enabled);
1260     return (false);
1261   }
1262 
1263   if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) {
1264     L2CAP_TRACE_EVENT("L2CA_FlowControl()  invalid mode:%d",
1265                       p_ccb->peer_cfg.fcr.mode);
1266     return (false);
1267   }
1268   if (p_ccb->fcrb.local_busy != on_off) {
1269     p_ccb->fcrb.local_busy = on_off;
1270 
1271     if ((p_ccb->chnl_state == CST_OPEN) && (!p_ccb->fcrb.wait_ack)) {
1272       if (on_off)
1273         l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RNR, 0);
1274       else
1275         l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_P_BIT);
1276     }
1277   }
1278 
1279   return (true);
1280 }
1281 
1282 /*******************************************************************************
1283  *
1284  * Function         L2CA_SendTestSFrame
1285  *
1286  * Description      Higher layers call this function to send a test S-frame.
1287  *
1288  * Returns          true if valid Channel, else false
1289  *
1290  ******************************************************************************/
L2CA_SendTestSFrame(uint16_t cid,uint8_t sup_type,uint8_t back_track)1291 bool L2CA_SendTestSFrame(uint16_t cid, uint8_t sup_type, uint8_t back_track) {
1292   tL2C_CCB* p_ccb;
1293 
1294   L2CAP_TRACE_API(
1295       "L2CA_SendTestSFrame()  CID: 0x%04x  Type: 0x%02x  back_track: %u", cid,
1296       sup_type, back_track);
1297 
1298   /* Find the channel control block. We don't know the link it is on. */
1299   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
1300   if (p_ccb == NULL) {
1301     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_SendTestSFrame, CID: %d", cid);
1302     return (false);
1303   }
1304 
1305   if ((p_ccb->chnl_state != CST_OPEN) ||
1306       (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE))
1307     return (false);
1308 
1309   p_ccb->fcrb.next_seq_expected -= back_track;
1310 
1311   l2c_fcr_send_S_frame(
1312       p_ccb, (uint16_t)(sup_type & 3),
1313       (uint16_t)(sup_type & (L2CAP_FCR_P_BIT | L2CAP_FCR_F_BIT)));
1314 
1315   return (true);
1316 }
1317 
1318 /*******************************************************************************
1319  *
1320  * Function         L2CA_SetTxPriority
1321  *
1322  * Description      Sets the transmission priority for a channel.
1323  *
1324  * Returns          true if a valid channel, else false
1325  *
1326  ******************************************************************************/
L2CA_SetTxPriority(uint16_t cid,tL2CAP_CHNL_PRIORITY priority)1327 bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) {
1328   tL2C_CCB* p_ccb;
1329 
1330   L2CAP_TRACE_API("L2CA_SetTxPriority()  CID: 0x%04x, priority:%d", cid,
1331                   priority);
1332 
1333   /* Find the channel control block. We don't know the link it is on. */
1334   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
1335   if (p_ccb == NULL) {
1336     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_SetTxPriority, CID: %d", cid);
1337     return (false);
1338   }
1339 
1340   /* it will update the order of CCB in LCB by priority and update round robin
1341    * service variables */
1342   l2cu_change_pri_ccb(p_ccb, priority);
1343 
1344   return (true);
1345 }
1346 
1347 /*******************************************************************************
1348  *
1349  * Function         L2CA_SetChnlDataRate
1350  *
1351  * Description      Sets the tx/rx data rate for a channel.
1352  *
1353  * Returns          true if a valid channel, else false
1354  *
1355  ******************************************************************************/
L2CA_SetChnlDataRate(uint16_t cid,tL2CAP_CHNL_DATA_RATE tx,tL2CAP_CHNL_DATA_RATE rx)1356 bool L2CA_SetChnlDataRate(uint16_t cid, tL2CAP_CHNL_DATA_RATE tx,
1357                           tL2CAP_CHNL_DATA_RATE rx) {
1358   tL2C_CCB* p_ccb;
1359 
1360   L2CAP_TRACE_API("L2CA_SetChnlDataRate()  CID: 0x%04x, tx:%d, rx:%d", cid, tx,
1361                   rx);
1362 
1363   /* Find the channel control block. We don't know the link it is on. */
1364   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
1365   if (p_ccb == NULL) {
1366     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_SetChnlDataRate, CID: %d",
1367                         cid);
1368     return (false);
1369   }
1370 
1371   p_ccb->tx_data_rate = tx;
1372   p_ccb->rx_data_rate = rx;
1373 
1374   /* Adjust channel buffer allocation */
1375   l2c_link_adjust_chnl_allocation();
1376 
1377   return (true);
1378 }
1379 
1380 /*******************************************************************************
1381  *
1382  * Function         L2CA_SetFlushTimeout
1383  *
1384  * Description      This function set the automatic flush time out in Baseband
1385  *                  for ACL-U packets.
1386  *                  BdAddr : the remote BD address of ACL link. If it is
1387  *                          BT_DB_ANY then the flush time out will be applied to
1388  *                          all ACL links.
1389  *                  FlushTimeout: flush time out in ms
1390  *                           0x0000 : No automatic flush
1391  *                           L2CAP_NO_RETRANSMISSION : No retransmission
1392  *                           0x0002 - 0xFFFE : flush time out, if
1393  *                                            (flush_tout * 8) + 3 / 5) <=
1394  *                                             HCI_MAX_AUTO_FLUSH_TOUT
1395  *                                            (in 625us slot).
1396  *                                    Otherwise, return false.
1397  *                           L2CAP_NO_AUTOMATIC_FLUSH : No automatic flush
1398  *
1399  * Returns          true if command succeeded, false if failed
1400  *
1401  * NOTE             This flush timeout applies to all logical channels active on
1402  *                  the ACL link.
1403  ******************************************************************************/
L2CA_SetFlushTimeout(BD_ADDR bd_addr,uint16_t flush_tout)1404 bool L2CA_SetFlushTimeout(BD_ADDR bd_addr, uint16_t flush_tout) {
1405   tL2C_LCB* p_lcb;
1406   uint16_t hci_flush_to;
1407   uint32_t temp;
1408 
1409   /* no automatic flush (infinite timeout) */
1410   if (flush_tout == 0x0000) {
1411     hci_flush_to = flush_tout;
1412     flush_tout = L2CAP_NO_AUTOMATIC_FLUSH;
1413   }
1414   /* no retransmission */
1415   else if (flush_tout == L2CAP_NO_RETRANSMISSION) {
1416     /* not mandatory range for controller */
1417     /* Packet is flushed before getting any ACK/NACK */
1418     /* To do this, flush timeout should be 1 baseband slot */
1419     hci_flush_to = flush_tout;
1420   }
1421   /* no automatic flush (infinite timeout) */
1422   else if (flush_tout == L2CAP_NO_AUTOMATIC_FLUSH) {
1423     hci_flush_to = 0x0000;
1424   } else {
1425     /* convert L2CAP flush_to to 0.625 ms units, with round */
1426     temp = (((uint32_t)flush_tout * 8) + 3) / 5;
1427 
1428     /* if L2CAP flush_to within range of HCI, set HCI flush timeout */
1429     if (temp > HCI_MAX_AUTO_FLUSH_TOUT) {
1430       L2CAP_TRACE_WARNING(
1431           "WARNING L2CA_SetFlushTimeout timeout(0x%x) is out of range",
1432           flush_tout);
1433       return false;
1434     } else {
1435       hci_flush_to = (uint16_t)temp;
1436     }
1437   }
1438 
1439   if (memcmp(BT_BD_ANY, bd_addr, BD_ADDR_LEN)) {
1440     p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
1441 
1442     if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
1443       if (p_lcb->link_flush_tout != flush_tout) {
1444         p_lcb->link_flush_tout = flush_tout;
1445 
1446         L2CAP_TRACE_API(
1447             "L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
1448             flush_tout, bd_addr[3], bd_addr[4], bd_addr[5]);
1449 
1450         btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to);
1451       }
1452     } else {
1453       L2CAP_TRACE_WARNING(
1454           "WARNING L2CA_SetFlushTimeout No lcb for bd_addr [...;%02x%02x%02x]",
1455           bd_addr[3], bd_addr[4], bd_addr[5]);
1456       return (false);
1457     }
1458   } else {
1459     int xx;
1460     p_lcb = &l2cb.lcb_pool[0];
1461 
1462     for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
1463       if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
1464         if (p_lcb->link_flush_tout != flush_tout) {
1465           p_lcb->link_flush_tout = flush_tout;
1466 
1467           L2CAP_TRACE_API(
1468               "L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
1469               flush_tout, p_lcb->remote_bd_addr[3], p_lcb->remote_bd_addr[4],
1470               p_lcb->remote_bd_addr[5]);
1471 
1472           btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to);
1473         }
1474       }
1475     }
1476   }
1477 
1478   return (true);
1479 }
1480 
1481 /*******************************************************************************
1482  *
1483  *  Function         L2CA_GetPeerFeatures
1484  *
1485  *  Description      Get a peers features and fixed channel map
1486  *
1487  *  Parameters:      BD address of the peer
1488  *                   Pointers to features and channel mask storage area
1489  *
1490  *  Return value:    true if peer is connected
1491  *
1492  ******************************************************************************/
L2CA_GetPeerFeatures(BD_ADDR bd_addr,uint32_t * p_ext_feat,uint8_t * p_chnl_mask)1493 bool L2CA_GetPeerFeatures(BD_ADDR bd_addr, uint32_t* p_ext_feat,
1494                           uint8_t* p_chnl_mask) {
1495   tL2C_LCB* p_lcb;
1496 
1497   /* We must already have a link to the remote */
1498   p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
1499   if (p_lcb == NULL) {
1500     L2CAP_TRACE_WARNING("L2CA_GetPeerFeatures() No BDA: %08x%04x",
1501                         (bd_addr[0] << 24) + (bd_addr[1] << 16) +
1502                             (bd_addr[2] << 8) + bd_addr[3],
1503                         (bd_addr[4] << 8) + bd_addr[5]);
1504     return (false);
1505   }
1506 
1507   L2CAP_TRACE_API(
1508       "L2CA_GetPeerFeatures() BDA: %08x%04x  ExtFea: 0x%08x  Chnl_Mask[0]: "
1509       "0x%02x",
1510       (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
1511       (bd_addr[4] << 8) + bd_addr[5], p_lcb->peer_ext_fea,
1512       p_lcb->peer_chnl_mask[0]);
1513 
1514   *p_ext_feat = p_lcb->peer_ext_fea;
1515 
1516   memcpy(p_chnl_mask, p_lcb->peer_chnl_mask, L2CAP_FIXED_CHNL_ARRAY_SIZE);
1517 
1518   return (true);
1519 }
1520 
1521 /*******************************************************************************
1522  *
1523  *  Function         L2CA_GetBDAddrbyHandle
1524  *
1525  *  Description      Get BD address for the given HCI handle
1526  *
1527  *  Parameters:      HCI handle
1528  *                   BD address of the peer
1529  *
1530  *  Return value:    true if found lcb for the given handle, false otherwise
1531  *
1532  ******************************************************************************/
L2CA_GetBDAddrbyHandle(uint16_t handle,BD_ADDR bd_addr)1533 bool L2CA_GetBDAddrbyHandle(uint16_t handle, BD_ADDR bd_addr) {
1534   tL2C_LCB* p_lcb = NULL;
1535   bool found_dev = false;
1536 
1537   p_lcb = l2cu_find_lcb_by_handle(handle);
1538   if (p_lcb) {
1539     found_dev = true;
1540     memcpy(bd_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
1541   }
1542 
1543   return found_dev;
1544 }
1545 
1546 /*******************************************************************************
1547  *
1548  *  Function         L2CA_GetChnlFcrMode
1549  *
1550  *  Description      Get the channel FCR mode
1551  *
1552  *  Parameters:      Local CID
1553  *
1554  *  Return value:    Channel mode
1555  *
1556  ******************************************************************************/
L2CA_GetChnlFcrMode(uint16_t lcid)1557 uint8_t L2CA_GetChnlFcrMode(uint16_t lcid) {
1558   tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
1559 
1560   if (p_ccb) {
1561     L2CAP_TRACE_API("L2CA_GetChnlFcrMode() returns mode %d",
1562                     p_ccb->peer_cfg.fcr.mode);
1563     return (p_ccb->peer_cfg.fcr.mode);
1564   }
1565 
1566   L2CAP_TRACE_API("L2CA_GetChnlFcrMode() returns mode L2CAP_FCR_BASIC_MODE");
1567   return (L2CAP_FCR_BASIC_MODE);
1568 }
1569 
1570 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1571 /*******************************************************************************
1572  *
1573  *  Function        L2CA_RegisterFixedChannel
1574  *
1575  *  Description     Register a fixed channel.
1576  *
1577  *  Parameters:     Fixed Channel #
1578  *                  Channel Callbacks and config
1579  *
1580  *  Return value:   -
1581  *
1582  ******************************************************************************/
L2CA_RegisterFixedChannel(uint16_t fixed_cid,tL2CAP_FIXED_CHNL_REG * p_freg)1583 bool L2CA_RegisterFixedChannel(uint16_t fixed_cid,
1584                                tL2CAP_FIXED_CHNL_REG* p_freg) {
1585   if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1586       (fixed_cid > L2CAP_LAST_FIXED_CHNL)) {
1587     L2CAP_TRACE_ERROR("L2CA_RegisterFixedChannel()  Invalid CID: 0x%04x",
1588                       fixed_cid);
1589 
1590     return (false);
1591   }
1592 
1593   l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = *p_freg;
1594   return (true);
1595 }
1596 
1597 /*******************************************************************************
1598  *
1599  *  Function        L2CA_ConnectFixedChnl
1600  *
1601  *  Description     Connect an fixed signalling channel to a remote device.
1602  *
1603  *  Parameters:     Fixed CID
1604  *                  BD Address of remote
1605  *
1606  *  Return value:   true if connection started
1607  *
1608  ******************************************************************************/
L2CA_ConnectFixedChnl(uint16_t fixed_cid,BD_ADDR rem_bda)1609 bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda) {
1610   uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
1611   return L2CA_ConnectFixedChnl(fixed_cid, rem_bda, phy);
1612 }
1613 
L2CA_ConnectFixedChnl(uint16_t fixed_cid,BD_ADDR rem_bda,uint8_t initiating_phys)1614 bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda,
1615                            uint8_t initiating_phys) {
1616   tL2C_LCB* p_lcb;
1617   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1618 
1619   L2CAP_TRACE_API(
1620       "%s() CID: 0x%04x  BDA: %08x%04x", __func__, fixed_cid,
1621       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
1622       (rem_bda[4] << 8) + rem_bda[5]);
1623 
1624   // Check CID is valid and registered
1625   if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1626       (fixed_cid > L2CAP_LAST_FIXED_CHNL) ||
1627       (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb ==
1628        NULL)) {
1629     L2CAP_TRACE_ERROR("%s() Invalid CID: 0x%04x", __func__, fixed_cid);
1630     return (false);
1631   }
1632 
1633   // Fail if BT is not yet up
1634   if (!BTM_IsDeviceUp()) {
1635     L2CAP_TRACE_WARNING("%s(0x%04x) - BTU not ready", __func__, fixed_cid);
1636     return (false);
1637   }
1638 
1639   if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
1640     transport = BT_TRANSPORT_LE;
1641 
1642   tL2C_BLE_FIXED_CHNLS_MASK peer_channel_mask;
1643 
1644   // If we already have a link to the remote, check if it supports that CID
1645   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
1646   if (p_lcb != NULL) {
1647     // Fixed channels are mandatory on LE transports so ignore the received
1648     // channel mask and use the locally cached LE channel mask.
1649 
1650     if (transport == BT_TRANSPORT_LE)
1651       peer_channel_mask = l2cb.l2c_ble_fixed_chnls_mask;
1652     else
1653       peer_channel_mask = p_lcb->peer_chnl_mask[0];
1654 
1655     // Check for supported channel
1656     if (!(peer_channel_mask & (1 << fixed_cid))) {
1657       L2CAP_TRACE_EVENT("%s() CID:0x%04x  BDA: %08x%04x not supported",
1658                         __func__, fixed_cid,
1659                         (rem_bda[0] << 24) + (rem_bda[1] << 16) +
1660                             (rem_bda[2] << 8) + rem_bda[3],
1661                         (rem_bda[4] << 8) + rem_bda[5]);
1662       return false;
1663     }
1664 
1665     // Get a CCB and link the lcb to it
1666     if (!l2cu_initialize_fixed_ccb(
1667             p_lcb, fixed_cid,
1668             &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL]
1669                  .fixed_chnl_opts)) {
1670       L2CAP_TRACE_WARNING("%s(0x%04x) - LCB but no CCB", __func__, fixed_cid);
1671       return false;
1672     }
1673 
1674     // racing with disconnecting, queue the connection request
1675     if (p_lcb->link_state == LST_DISCONNECTING) {
1676       L2CAP_TRACE_DEBUG("$s() - link disconnecting: RETRY LATER", __func__);
1677       /* Save ccb so it can be started after disconnect is finished */
1678       p_lcb->p_pending_ccb =
1679           p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
1680       return true;
1681     }
1682 
1683     (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(
1684         fixed_cid, p_lcb->remote_bd_addr, true, 0, p_lcb->transport);
1685     return true;
1686   }
1687 
1688   // No link. Get an LCB and start link establishment
1689   p_lcb = l2cu_allocate_lcb(rem_bda, false, transport);
1690   if (p_lcb == NULL) {
1691     L2CAP_TRACE_WARNING("%s(0x%04x) - no LCB", __func__, fixed_cid);
1692     return false;
1693   }
1694 
1695   // Get a CCB and link the lcb to it
1696   if (!l2cu_initialize_fixed_ccb(
1697           p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL]
1698                                  .fixed_chnl_opts)) {
1699     p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES;
1700     L2CAP_TRACE_WARNING("%s(0x%04x) - no CCB", __func__, fixed_cid);
1701     l2cu_release_lcb(p_lcb);
1702     return false;
1703   }
1704 
1705   if (!l2cu_create_conn(p_lcb, transport, initiating_phys)) {
1706     L2CAP_TRACE_WARNING("%s() - create_conn failed", __func__);
1707     l2cu_release_lcb(p_lcb);
1708     return false;
1709   }
1710   return true;
1711 }
1712 
1713 /*******************************************************************************
1714  *
1715  *  Function        L2CA_SendFixedChnlData
1716  *
1717  *  Description     Write data on a fixed channel.
1718  *
1719  *  Parameters:     Fixed CID
1720  *                  BD Address of remote
1721  *                  Pointer to buffer of type BT_HDR
1722  *
1723  * Return value     L2CAP_DW_SUCCESS, if data accepted
1724  *                  L2CAP_DW_FAILED,  if error
1725  *
1726  ******************************************************************************/
L2CA_SendFixedChnlData(uint16_t fixed_cid,BD_ADDR rem_bda,BT_HDR * p_buf)1727 uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, BD_ADDR rem_bda,
1728                                 BT_HDR* p_buf) {
1729   tL2C_LCB* p_lcb;
1730   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1731 
1732   L2CAP_TRACE_API(
1733       "L2CA_SendFixedChnlData()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
1734       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
1735       (rem_bda[4] << 8) + rem_bda[5]);
1736 
1737   if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
1738     transport = BT_TRANSPORT_LE;
1739 
1740   // Check CID is valid and registered
1741   if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1742       (fixed_cid > L2CAP_LAST_FIXED_CHNL) ||
1743       (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb ==
1744        NULL)) {
1745     L2CAP_TRACE_ERROR("L2CA_SendFixedChnlData()  Invalid CID: 0x%04x",
1746                       fixed_cid);
1747     osi_free(p_buf);
1748     return (L2CAP_DW_FAILED);
1749   }
1750 
1751   // Fail if BT is not yet up
1752   if (!BTM_IsDeviceUp()) {
1753     L2CAP_TRACE_WARNING("L2CA_SendFixedChnlData(0x%04x) - BTU not ready",
1754                         fixed_cid);
1755     osi_free(p_buf);
1756     return (L2CAP_DW_FAILED);
1757   }
1758 
1759   // We need to have a link up
1760   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
1761   if (p_lcb == NULL || p_lcb->link_state == LST_DISCONNECTING) {
1762     /* if link is disconnecting, also report data sending failure */
1763     L2CAP_TRACE_WARNING("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid);
1764     osi_free(p_buf);
1765     return (L2CAP_DW_FAILED);
1766   }
1767 
1768   tL2C_BLE_FIXED_CHNLS_MASK peer_channel_mask;
1769 
1770   // Select peer channels mask to use depending on transport
1771   if (transport == BT_TRANSPORT_LE)
1772     peer_channel_mask = l2cb.l2c_ble_fixed_chnls_mask;
1773   else
1774     peer_channel_mask = p_lcb->peer_chnl_mask[0];
1775 
1776   if ((peer_channel_mask & (1 << fixed_cid)) == 0) {
1777     L2CAP_TRACE_WARNING(
1778         "L2CA_SendFixedChnlData() - peer does not support fixed chnl: 0x%04x",
1779         fixed_cid);
1780     osi_free(p_buf);
1781     return (L2CAP_DW_FAILED);
1782   }
1783 
1784   p_buf->event = 0;
1785   p_buf->layer_specific = L2CAP_FLUSHABLE_CH_BASED;
1786 
1787   if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) {
1788     if (!l2cu_initialize_fixed_ccb(
1789             p_lcb, fixed_cid,
1790             &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL]
1791                  .fixed_chnl_opts)) {
1792       L2CAP_TRACE_WARNING("L2CA_SendFixedChnlData() - no CCB for chnl: 0x%4x",
1793                           fixed_cid);
1794       osi_free(p_buf);
1795       return (L2CAP_DW_FAILED);
1796     }
1797   }
1798 
1799   // If already congested, do not accept any more packets
1800   if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
1801     L2CAP_TRACE_ERROR(
1802         "L2CAP - CID: 0x%04x cannot send, already congested \
1803             xmit_hold_q.count: %u buff_quota: %u",
1804         fixed_cid, fixed_queue_length(
1805                        p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]
1806                            ->xmit_hold_q),
1807         p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota);
1808     osi_free(p_buf);
1809     return (L2CAP_DW_FAILED);
1810   }
1811 
1812   l2c_enqueue_peer_data(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL],
1813                         p_buf);
1814 
1815   l2c_link_check_send_pkts(p_lcb, NULL, NULL);
1816 
1817   // If there is no dynamic CCB on the link, restart the idle timer each time
1818   // something is sent
1819   if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED &&
1820       !p_lcb->ccb_queue.p_first_ccb) {
1821     l2cu_no_dynamic_ccbs(p_lcb);
1822   }
1823 
1824   if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent)
1825     return (L2CAP_DW_CONGESTED);
1826 
1827   return (L2CAP_DW_SUCCESS);
1828 }
1829 
1830 /*******************************************************************************
1831  *
1832  *  Function        L2CA_RemoveFixedChnl
1833  *
1834  *  Description     Remove a fixed channel to a remote device.
1835  *
1836  *  Parameters:     Fixed CID
1837  *                  BD Address of remote
1838  *                  Idle timeout to use (or 0xFFFF if don't care)
1839  *
1840  *  Return value:   true if channel removed
1841  *
1842  ******************************************************************************/
L2CA_RemoveFixedChnl(uint16_t fixed_cid,BD_ADDR rem_bda)1843 bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda) {
1844   tL2C_LCB* p_lcb;
1845   tL2C_CCB* p_ccb;
1846   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1847 
1848   /* Check CID is valid and registered */
1849   if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1850       (fixed_cid > L2CAP_LAST_FIXED_CHNL) ||
1851       (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb ==
1852        NULL)) {
1853     L2CAP_TRACE_ERROR("L2CA_RemoveFixedChnl()  Invalid CID: 0x%04x", fixed_cid);
1854     return (false);
1855   }
1856 
1857   if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
1858     transport = BT_TRANSPORT_LE;
1859 
1860   /* Is a fixed channel connected to the remote BDA ?*/
1861   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
1862 
1863   if (((p_lcb) == NULL) ||
1864       (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])) {
1865     L2CAP_TRACE_WARNING(
1866         "L2CA_RemoveFixedChnl()  CID: 0x%04x  BDA: %08x%04x not connected",
1867         fixed_cid, (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) +
1868                        rem_bda[3],
1869         (rem_bda[4] << 8) + rem_bda[5]);
1870     return (false);
1871   }
1872 
1873   L2CAP_TRACE_API(
1874       "L2CA_RemoveFixedChnl()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
1875       (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
1876       (rem_bda[4] << 8) + rem_bda[5]);
1877 
1878   /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs
1879    * exist */
1880   p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
1881 
1882   p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL;
1883   p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST;
1884 
1885   // Retain the link for a few more seconds after SMP pairing is done, since
1886   // the Android platform always does service discovery after pairing is
1887   // complete. This will avoid the link down (pairing is complete) and an
1888   // immediate re-connection for service discovery.
1889   // Some devices do not do auto advertising when link is dropped, thus fail
1890   // the second connection and service discovery.
1891   if ((fixed_cid == L2CAP_ATT_CID) && !p_lcb->ccb_queue.p_first_ccb)
1892     p_lcb->idle_timeout = 0;
1893 
1894   l2cu_release_ccb(p_ccb);
1895 
1896   return (true);
1897 }
1898 
1899 /*******************************************************************************
1900  *
1901  * Function         L2CA_SetFixedChannelTout
1902  *
1903  * Description      Higher layers call this function to set the idle timeout for
1904  *                  a fixed channel. The "idle timeout" is the amount of time
1905  *                  that a connection can remain up with no L2CAP channels on
1906  *                  it. A timeout of zero means that the connection will be torn
1907  *                  down immediately when the last channel is removed.
1908  *                  A timeout of 0xFFFF means no timeout. Values are in seconds.
1909  *                  A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
1910  *                  then the idle timeouts for all active l2cap links will be
1911  *                  changed.
1912  *
1913  * Returns          true if command succeeded, false if failed
1914  *
1915  ******************************************************************************/
L2CA_SetFixedChannelTout(BD_ADDR rem_bda,uint16_t fixed_cid,uint16_t idle_tout)1916 bool L2CA_SetFixedChannelTout(BD_ADDR rem_bda, uint16_t fixed_cid,
1917                               uint16_t idle_tout) {
1918   tL2C_LCB* p_lcb;
1919   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1920 
1921   if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
1922     transport = BT_TRANSPORT_LE;
1923 
1924   /* Is a fixed channel connected to the remote BDA ?*/
1925   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
1926   if (((p_lcb) == NULL) ||
1927       (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])) {
1928     L2CAP_TRACE_WARNING(
1929         "L2CA_SetFixedChannelTout()  CID: 0x%04x  BDA: %08x%04x not connected",
1930         fixed_cid, (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) +
1931                        rem_bda[3],
1932         (rem_bda[4] << 8) + rem_bda[5]);
1933     return (false);
1934   }
1935 
1936   p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]
1937       ->fixed_chnl_idle_tout = idle_tout;
1938 
1939   if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED &&
1940       !p_lcb->ccb_queue.p_first_ccb) {
1941     /* If there are no dynamic CCBs, (re)start the idle timer in case we changed
1942      * it */
1943     l2cu_no_dynamic_ccbs(p_lcb);
1944   }
1945 
1946   return true;
1947 }
1948 
1949 #endif /* #if (L2CAP_NUM_FIXED_CHNLS > 0) */
1950 
1951 /*******************************************************************************
1952  *
1953  * Function     L2CA_GetCurrentConfig
1954  *
1955  * Description  This function returns configurations of L2CAP channel
1956  *              pp_our_cfg : pointer of our saved configuration options
1957  *              p_our_cfg_bits : valid config in bitmap
1958  *              pp_peer_cfg: pointer of peer's saved configuration options
1959  *              p_peer_cfg_bits : valid config in bitmap
1960  *
1961  * Returns      true if successful
1962  *
1963  ******************************************************************************/
L2CA_GetCurrentConfig(uint16_t lcid,tL2CAP_CFG_INFO ** pp_our_cfg,tL2CAP_CH_CFG_BITS * p_our_cfg_bits,tL2CAP_CFG_INFO ** pp_peer_cfg,tL2CAP_CH_CFG_BITS * p_peer_cfg_bits)1964 bool L2CA_GetCurrentConfig(uint16_t lcid, tL2CAP_CFG_INFO** pp_our_cfg,
1965                            tL2CAP_CH_CFG_BITS* p_our_cfg_bits,
1966                            tL2CAP_CFG_INFO** pp_peer_cfg,
1967                            tL2CAP_CH_CFG_BITS* p_peer_cfg_bits) {
1968   tL2C_CCB* p_ccb;
1969 
1970   L2CAP_TRACE_API("L2CA_GetCurrentConfig()  CID: 0x%04x", lcid);
1971 
1972   p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
1973 
1974   if (p_ccb) {
1975     *pp_our_cfg = &(p_ccb->our_cfg);
1976 
1977     /* convert valid config items into bitmap */
1978     *p_our_cfg_bits = 0;
1979     if (p_ccb->our_cfg.mtu_present) *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
1980     if (p_ccb->our_cfg.qos_present) *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
1981     if (p_ccb->our_cfg.flush_to_present)
1982       *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
1983     if (p_ccb->our_cfg.fcr_present) *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCR;
1984     if (p_ccb->our_cfg.fcs_present) *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCS;
1985     if (p_ccb->our_cfg.ext_flow_spec_present)
1986       *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_EXT_FLOW_SPEC;
1987 
1988     *pp_peer_cfg = &(p_ccb->peer_cfg);
1989     *p_peer_cfg_bits = p_ccb->peer_cfg_bits;
1990 
1991     return true;
1992   } else {
1993     L2CAP_TRACE_ERROR("No CCB for CID:0x%04x", lcid);
1994     return false;
1995   }
1996 }
1997 
1998 /*******************************************************************************
1999  *
2000  * Function      L2CA_GetConnectionConfig
2001  *
2002  * Description  This function returns configurations of L2CAP channel
2003  *              pp_l2c_ccb : pointer to this channels L2CAP ccb data.
2004  *
2005  * Returns      true if successful
2006  *
2007  ******************************************************************************/
L2CA_GetConnectionConfig(uint16_t lcid,uint16_t * mtu,uint16_t * rcid,uint16_t * handle)2008 bool L2CA_GetConnectionConfig(uint16_t lcid, uint16_t* mtu, uint16_t* rcid,
2009                               uint16_t* handle) {
2010   tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
2011   ;
2012 
2013   L2CAP_TRACE_API("%s CID: 0x%04x", __func__, lcid);
2014 
2015   if (p_ccb) {
2016     *mtu = L2CAP_MTU_SIZE;
2017     if (p_ccb->our_cfg.mtu_present) *mtu = p_ccb->our_cfg.mtu;
2018 
2019     *rcid = p_ccb->remote_cid;
2020     *handle = p_ccb->p_lcb->handle;
2021     return true;
2022   }
2023 
2024   L2CAP_TRACE_ERROR("%s No CCB for CID:0x%04x", __func__, lcid);
2025   return false;
2026 }
2027 
2028 /*******************************************************************************
2029  *
2030  * Function         L2CA_RegForNoCPEvt
2031  *
2032  * Description      Register callback for Number of Completed Packets event.
2033  *
2034  * Input Param      p_cb - callback for Number of completed packets event
2035  *                  p_bda - BT address of remote device
2036  *
2037  * Returns          true if registered OK, else false
2038  *
2039  ******************************************************************************/
L2CA_RegForNoCPEvt(tL2CA_NOCP_CB * p_cb,BD_ADDR p_bda)2040 bool L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, BD_ADDR p_bda) {
2041   tL2C_LCB* p_lcb;
2042 
2043   /* Find the link that is associated with this remote bdaddr */
2044   p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, BT_TRANSPORT_BR_EDR);
2045 
2046   /* If no link for this handle, nothing to do. */
2047   if (!p_lcb) return false;
2048 
2049   p_lcb->p_nocp_cb = p_cb;
2050 
2051   return true;
2052 }
2053 
2054 /*******************************************************************************
2055  *
2056  * Function         L2CA_DataWrite
2057  *
2058  * Description      Higher layers call this function to write data.
2059  *
2060  * Returns          L2CAP_DW_SUCCESS, if data accepted, else false
2061  *                  L2CAP_DW_CONGESTED, if data accepted and the channel is
2062  *                                      congested
2063  *                  L2CAP_DW_FAILED, if error
2064  *
2065  ******************************************************************************/
L2CA_DataWrite(uint16_t cid,BT_HDR * p_data)2066 uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
2067   L2CAP_TRACE_API("L2CA_DataWrite()  CID: 0x%04x  Len: %d", cid, p_data->len);
2068   return l2c_data_write(cid, p_data, L2CAP_FLUSHABLE_CH_BASED);
2069 }
2070 
2071 /*******************************************************************************
2072  *
2073  * Function         L2CA_SetChnlFlushability
2074  *
2075  * Description      Higher layers call this function to set a channels
2076  *                  flushability flags
2077  *
2078  * Returns          true if CID found, else false
2079  *
2080  ******************************************************************************/
L2CA_SetChnlFlushability(uint16_t cid,bool is_flushable)2081 bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) {
2082 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2083 
2084   tL2C_CCB* p_ccb;
2085 
2086   /* Find the channel control block. We don't know the link it is on. */
2087   p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
2088   if (p_ccb == NULL) {
2089     L2CAP_TRACE_WARNING("L2CAP - no CCB for L2CA_SetChnlFlushability, CID: %d",
2090                         cid);
2091     return (false);
2092   }
2093 
2094   p_ccb->is_flushable = is_flushable;
2095 
2096   L2CAP_TRACE_API("L2CA_SetChnlFlushability()  CID: 0x%04x  is_flushable: %d",
2097                   cid, is_flushable);
2098 
2099 #endif
2100 
2101   return (true);
2102 }
2103 
2104 /*******************************************************************************
2105  *
2106  * Function         L2CA_DataWriteEx
2107  *
2108  * Description      Higher layers call this function to write data with extended
2109  *                  flags.
2110  *                  flags : L2CAP_FLUSHABLE_CH_BASED
2111  *                          L2CAP_FLUSHABLE_PKT
2112  *                          L2CAP_NON_FLUSHABLE_PKT
2113  *
2114  * Returns          L2CAP_DW_SUCCESS, if data accepted, else false
2115  *                  L2CAP_DW_CONGESTED, if data accepted and the channel is
2116  *                                      congested
2117  *                  L2CAP_DW_FAILED, if error
2118  *
2119  ******************************************************************************/
L2CA_DataWriteEx(uint16_t cid,BT_HDR * p_data,uint16_t flags)2120 uint8_t L2CA_DataWriteEx(uint16_t cid, BT_HDR* p_data, uint16_t flags) {
2121   L2CAP_TRACE_API("L2CA_DataWriteEx()  CID: 0x%04x  Len: %d Flags:0x%04X", cid,
2122                   p_data->len, flags);
2123   return l2c_data_write(cid, p_data, flags);
2124 }
2125 
2126 /*******************************************************************************
2127  *
2128  * Function     L2CA_FlushChannel
2129  *
2130  * Description  This function flushes none, some or all buffers queued up
2131  *              for xmission for a particular CID. If called with
2132  *              L2CAP_FLUSH_CHANS_GET (0), it simply returns the number
2133  *              of buffers queued for that CID L2CAP_FLUSH_CHANS_ALL (0xffff)
2134  *              flushes all buffers.  All other values specifies the maximum
2135  *              buffers to flush.
2136  *
2137  * Returns      Number of buffers left queued for that CID
2138  *
2139  ******************************************************************************/
L2CA_FlushChannel(uint16_t lcid,uint16_t num_to_flush)2140 uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) {
2141   tL2C_CCB* p_ccb;
2142   tL2C_LCB* p_lcb;
2143   uint16_t num_left = 0, num_flushed1 = 0, num_flushed2 = 0;
2144 
2145   p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
2146 
2147   if (!p_ccb || (p_ccb->p_lcb == NULL)) {
2148     L2CAP_TRACE_WARNING(
2149         "L2CA_FlushChannel()  abnormally returning 0  CID: 0x%04x", lcid);
2150     return (0);
2151   }
2152   p_lcb = p_ccb->p_lcb;
2153 
2154   if (num_to_flush != L2CAP_FLUSH_CHANS_GET) {
2155     L2CAP_TRACE_API(
2156         "L2CA_FlushChannel (FLUSH)  CID: 0x%04x  NumToFlush: %d  QC: %u  "
2157         "pFirst: 0x%08x",
2158         lcid, num_to_flush, fixed_queue_length(p_ccb->xmit_hold_q),
2159         fixed_queue_try_peek_first(p_ccb->xmit_hold_q));
2160   } else {
2161     L2CAP_TRACE_API("L2CA_FlushChannel (QUERY)  CID: 0x%04x", lcid);
2162   }
2163 
2164   /* Cannot flush eRTM buffers once they have a sequence number */
2165   if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) {
2166 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2167     if (num_to_flush != L2CAP_FLUSH_CHANS_GET) {
2168       /* If the controller supports enhanced flush, flush the data queued at the
2169        * controller */
2170       if ((HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures())) &&
2171           (BTM_GetNumScoLinks() == 0)) {
2172         if (l2cb.is_flush_active == false) {
2173           l2cb.is_flush_active = true;
2174 
2175           /* The only packet type defined - 0 - Automatically-Flushable Only */
2176           btsnd_hcic_enhanced_flush(p_lcb->handle, 0);
2177         }
2178       }
2179     }
2180 #endif
2181 
2182     // Iterate though list and flush the amount requested from
2183     // the transmit data queue that satisfy the layer and event conditions.
2184     for (const list_node_t* node = list_begin(p_lcb->link_xmit_data_q);
2185          (num_to_flush > 0) && node != list_end(p_lcb->link_xmit_data_q);) {
2186       BT_HDR* p_buf = (BT_HDR*)list_node(node);
2187       node = list_next(node);
2188       if ((p_buf->layer_specific == 0) && (p_buf->event == lcid)) {
2189         num_to_flush--;
2190         num_flushed1++;
2191 
2192         list_remove(p_lcb->link_xmit_data_q, p_buf);
2193         osi_free(p_buf);
2194       }
2195     }
2196   }
2197 
2198   /* If needed, flush buffers in the CCB xmit hold queue */
2199   while ((num_to_flush != 0) && (!fixed_queue_is_empty(p_ccb->xmit_hold_q))) {
2200     BT_HDR* p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
2201     osi_free(p_buf);
2202     num_to_flush--;
2203     num_flushed2++;
2204   }
2205 
2206   /* If app needs to track all packets, call him */
2207   if ((p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_TxComplete_Cb) &&
2208       (num_flushed2))
2209     (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, num_flushed2);
2210 
2211   /* Now count how many are left */
2212   for (const list_node_t* node = list_begin(p_lcb->link_xmit_data_q);
2213        node != list_end(p_lcb->link_xmit_data_q); node = list_next(node)) {
2214     BT_HDR* p_buf = (BT_HDR*)list_node(node);
2215     if (p_buf->event == lcid) num_left++;
2216   }
2217 
2218   /* Add in the number in the CCB xmit queue */
2219   num_left += fixed_queue_length(p_ccb->xmit_hold_q);
2220 
2221   /* Return the local number of buffers left for the CID */
2222   L2CAP_TRACE_DEBUG("L2CA_FlushChannel()  flushed: %u + %u,  num_left: %u",
2223                     num_flushed1, num_flushed2, num_left);
2224 
2225   /* If we were congested, and now we are not, tell the app */
2226   l2cu_check_channel_congestion(p_ccb);
2227 
2228   return (num_left);
2229 }
2230