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