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         (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)
1719         (fixed_cid, p_lcb->remote_bd_addr, TRUE, 0, transport);
1720 
1721         return TRUE;
1722     }
1723 
1724     // No link. Get an LCB and start link establishment
1725     if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, transport)) == NULL) {
1726         L2CAP_TRACE_WARNING ("%s(0x%04x) - no LCB", __func__, fixed_cid);
1727         return FALSE;
1728     }
1729 
1730     // Get a CCB and link the lcb to it
1731     if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid,
1732                                     &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) {
1733         p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES;
1734         L2CAP_TRACE_WARNING ("%s(0x%04x) - no CCB", __func__, fixed_cid);
1735         l2cu_release_lcb (p_lcb);
1736         return FALSE;
1737     }
1738 #if (BLE_INCLUDED == TRUE)
1739     p_lcb->is_aux = is_aux;
1740     p_lcb->open_addr_type = bd_addr_type;
1741 #endif
1742     if (!l2cu_create_conn(p_lcb, transport)) {
1743         L2CAP_TRACE_WARNING ("%s() - create_conn failed", __func__);
1744         l2cu_release_lcb (p_lcb);
1745         return FALSE;
1746     }
1747     return TRUE;
1748 }
1749 
1750 /*******************************************************************************
1751 **
1752 **  Function        L2CA_SendFixedChnlData
1753 **
1754 **  Description     Write data on a fixed channel.
1755 **
1756 **  Parameters:     Fixed CID
1757 **                  BD Address of remote
1758 **                  Pointer to buffer of type BT_HDR
1759 **
1760 ** Return value     L2CAP_DW_SUCCESS, if data accepted
1761 **                  L2CAP_DW_FAILED,  if error
1762 **
1763 *******************************************************************************/
L2CA_SendFixedChnlData(UINT16 fixed_cid,BD_ADDR rem_bda,BT_HDR * p_buf)1764 UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
1765 {
1766     tL2C_LCB        *p_lcb;
1767     tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
1768 
1769     L2CAP_TRACE_API ("L2CA_SendFixedChnlData()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
1770                      (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], (rem_bda[4] << 8) + rem_bda[5]);
1771 
1772 #if BLE_INCLUDED == TRUE
1773     if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) {
1774         transport = BT_TRANSPORT_LE;
1775     }
1776 #endif
1777 
1778     // Check CID is valid and registered
1779     if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
1780             ||  (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) ) {
1781         L2CAP_TRACE_ERROR ("L2CA_SendFixedChnlData()  Invalid CID: 0x%04x", fixed_cid);
1782         osi_free (p_buf);
1783         return (L2CAP_DW_FAILED);
1784     }
1785 
1786     // Fail if BT is not yet up
1787     if (!BTM_IsDeviceUp()) {
1788         L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData(0x%04x) - BTU not ready", fixed_cid);
1789         osi_free (p_buf);
1790         return (L2CAP_DW_FAILED);
1791     }
1792 
1793     // We need to have a link up
1794     if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) == NULL ||
1795             /* if link is disconnecting, also report data sending failure */
1796             p_lcb->link_state == LST_DISCONNECTING) {
1797         L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid);
1798         osi_free (p_buf);
1799         return (L2CAP_DW_FAILED);
1800     }
1801 
1802     tL2C_BLE_FIXED_CHNLS_MASK peer_channel_mask;
1803 
1804     // Select peer channels mask to use depending on transport
1805 #if BLE_INCLUDED == TRUE
1806     if (transport == BT_TRANSPORT_LE) {
1807         peer_channel_mask = l2cb.l2c_ble_fixed_chnls_mask;
1808     } else
1809 #endif
1810     {
1811         peer_channel_mask = p_lcb->peer_chnl_mask[0];
1812     }
1813 
1814     if ((peer_channel_mask & (1 << fixed_cid)) == 0) {
1815         L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData() - peer does not support fixed chnl: 0x%04x", fixed_cid);
1816         osi_free (p_buf);
1817         return (L2CAP_DW_FAILED);
1818     }
1819 
1820     p_buf->event = 0;
1821     p_buf->layer_specific = L2CAP_FLUSHABLE_CH_BASED;
1822 
1823     if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) {
1824         if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) {
1825             L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData() - no CCB for chnl: 0x%4x", fixed_cid);
1826             osi_free (p_buf);
1827             return (L2CAP_DW_FAILED);
1828         }
1829     }
1830 
1831     // If already congested, do not accept any more packets
1832     if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent && fixed_cid != L2CAP_SMP_CID) {
1833         L2CAP_TRACE_DEBUG ("L2CAP - CID: 0x%04x cannot send, already congested\
1834             xmit_hold_q.count: %u buff_quota: %u", fixed_cid,
1835             fixed_queue_length(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q),
1836             p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota);
1837         osi_free(p_buf);
1838         return (L2CAP_DW_CONGESTED);
1839     }
1840 
1841     l2c_enqueue_peer_data (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL], p_buf);
1842 
1843     l2c_link_check_send_pkts (p_lcb, NULL, NULL);
1844 
1845     // If there is no dynamic CCB on the link, restart the idle timer each time something is sent
1846     if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED && !p_lcb->ccb_queue.p_first_ccb) {
1847         l2cu_no_dynamic_ccbs (p_lcb);
1848     }
1849 
1850     if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
1851         return (L2CAP_DW_CONGESTED);
1852     }
1853 
1854     return (L2CAP_DW_SUCCESS);
1855 }
1856 
L2CA_CheckIsCongest(UINT16 fixed_cid,BD_ADDR addr)1857 BOOLEAN L2CA_CheckIsCongest(UINT16 fixed_cid, BD_ADDR addr)
1858 {
1859     tL2C_LCB *p_lcb;
1860     p_lcb = l2cu_find_lcb_by_bd_addr(addr, BT_TRANSPORT_LE);
1861 
1862     if (p_lcb != NULL && p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL) {
1863         return p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent;
1864     }
1865 
1866     return TRUE;
1867 }
1868 
1869 #if (BLE_INCLUDED == TRUE)
L2CA_GetFreePktBufferNum_LE(void)1870 UINT16 L2CA_GetFreePktBufferNum_LE(void)
1871 {
1872     return l2cb.controller_le_xmit_window;
1873 }
L2CA_GetCurFreePktBufferNum_LE(UINT16 conn_id)1874 UINT16 L2CA_GetCurFreePktBufferNum_LE(UINT16 conn_id)
1875 {
1876     uint16_t num = 0;
1877     tl2c_buff_param_t param;
1878     param.conn_id = conn_id;
1879     param.get_num = &num;
1880     l2ble_update_att_acl_pkt_num(L2CA_GET_ATT_NUM, &param);
1881     return num;
1882 }
1883 #endif
1884 
1885 /*******************************************************************************
1886 **
1887 **  Function        L2CA_RemoveFixedChnl
1888 **
1889 **  Description     Remove a fixed channel to a remote device.
1890 **
1891 **  Parameters:     Fixed CID
1892 **                  BD Address of remote
1893 **                  Idle timeout to use (or 0xFFFF if don't care)
1894 **
1895 **  Return value:   TRUE if channel removed
1896 **
1897 *******************************************************************************/
L2CA_RemoveFixedChnl(UINT16 fixed_cid,BD_ADDR rem_bda)1898 BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
1899 {
1900     tL2C_LCB    *p_lcb;
1901     tL2C_CCB    *p_ccb;
1902     tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
1903 
1904     /* Check CID is valid and registered */
1905     if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
1906             ||  (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) ) {
1907         L2CAP_TRACE_ERROR ("L2CA_RemoveFixedChnl()  Invalid CID: 0x%04x", fixed_cid);
1908         return (FALSE);
1909     }
1910 
1911 #if BLE_INCLUDED == TRUE
1912     if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) {
1913         transport = BT_TRANSPORT_LE;
1914     }
1915 #endif
1916 
1917     /* Is a fixed channel connected to the remote BDA ?*/
1918     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport);
1919 
1920     if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) ) {
1921         L2CAP_TRACE_DEBUG ("L2CA_RemoveFixedChnl()  CID: 0x%04x  BDA: %08x%04x not connected", fixed_cid,
1922                              (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], (rem_bda[4] << 8) + rem_bda[5]);
1923         return (FALSE);
1924     }
1925 
1926     L2CAP_TRACE_API ("L2CA_RemoveFixedChnl()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
1927                      (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], (rem_bda[4] << 8) + rem_bda[5]);
1928 
1929     /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs exist */
1930     p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
1931 
1932     p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL;
1933     p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST;
1934 
1935 #if BLE_INCLUDED == TRUE
1936     // Retain the link for a few more seconds after SMP pairing is done, since the Android
1937     // platform always does service discovery after pairing is complete. This will avoid
1938     // the link down (pairing is complete) and an immediate re-connection for service
1939     // discovery.
1940     // Some devices do not do auto advertising when link is dropped, thus fail the second
1941     // connection and service discovery.
1942     if ((fixed_cid == L2CAP_ATT_CID ) && !p_lcb->ccb_queue.p_first_ccb) {
1943         p_lcb->idle_timeout = 0;
1944     }
1945 #endif
1946 
1947     l2cu_release_ccb (p_ccb);
1948 
1949     return (TRUE);
1950 }
1951 
1952 /*******************************************************************************
1953 **
1954 ** Function         L2CA_SetFixedChannelTout
1955 **
1956 ** Description      Higher layers call this function to set the idle timeout for
1957 **                  a fixed channel. The "idle timeout" is the amount of time that
1958 **                  a connection can remain up with no L2CAP channels on it.
1959 **                  A timeout of zero means that the connection will be torn
1960 **                  down immediately when the last channel is removed.
1961 **                  A timeout of 0xFFFF means no timeout. Values are in seconds.
1962 **                  A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
1963 **                  then the idle timeouts for all active l2cap links will be
1964 **                  changed.
1965 **
1966 ** Returns          TRUE if command succeeded, FALSE if failed
1967 **
1968 *******************************************************************************/
L2CA_SetFixedChannelTout(BD_ADDR rem_bda,UINT16 fixed_cid,UINT16 idle_tout)1969 BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle_tout)
1970 {
1971     tL2C_LCB        *p_lcb;
1972     tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
1973 
1974 #if BLE_INCLUDED == TRUE
1975     if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) {
1976         transport = BT_TRANSPORT_LE;
1977     }
1978 #endif
1979     if (fixed_cid<L2CAP_FIRST_FIXED_CHNL) {
1980         return (FALSE);
1981     }
1982 
1983     /* Is a fixed channel connected to the remote BDA ?*/
1984     p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport);
1985     if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) ) {
1986         L2CAP_TRACE_WARNING ("L2CA_SetFixedChannelTout()  CID: 0x%04x  BDA: %08x%04x not connected", fixed_cid,
1987                              (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3], (rem_bda[4] << 8) + rem_bda[5]);
1988         return (FALSE);
1989     }
1990 
1991     p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->fixed_chnl_idle_tout = idle_tout;
1992 
1993     if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED && !p_lcb->ccb_queue.p_first_ccb) {
1994         /* If there are no dynamic CCBs, (re)start the idle timer in case we changed it */
1995         l2cu_no_dynamic_ccbs (p_lcb);
1996     }
1997 
1998     return TRUE;
1999 }
2000 
2001 #endif /* #if (L2CAP_NUM_FIXED_CHNLS > 0) */
2002 
2003 #if (CLASSIC_BT_INCLUDED == TRUE)
2004 /*******************************************************************************
2005 **
2006 ** Function     L2CA_GetCurrentConfig
2007 **
2008 ** Description  This function returns configurations of L2CAP channel
2009 **              pp_our_cfg : pointer of our saved configuration options
2010 **              p_our_cfg_bits : valid config in bitmap
2011 **              pp_peer_cfg: pointer of peer's saved configuration options
2012 **              p_peer_cfg_bits : valid config in bitmap
2013 **
2014 ** Returns      TRUE if successful
2015 **
2016 *******************************************************************************/
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)2017 BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid,
2018                                tL2CAP_CFG_INFO **pp_our_cfg,  tL2CAP_CH_CFG_BITS *p_our_cfg_bits,
2019                                tL2CAP_CFG_INFO **pp_peer_cfg, tL2CAP_CH_CFG_BITS *p_peer_cfg_bits)
2020 {
2021     tL2C_CCB    *p_ccb;
2022 
2023     L2CAP_TRACE_API ("L2CA_GetCurrentConfig()  CID: 0x%04x", lcid);
2024 
2025     p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
2026 
2027     if (p_ccb) {
2028         *pp_our_cfg  = &(p_ccb->our_cfg);
2029 
2030         /* convert valid config items into bitmap */
2031         *p_our_cfg_bits = 0;
2032         if (p_ccb->our_cfg.mtu_present) {
2033             *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
2034         }
2035         if (p_ccb->our_cfg.qos_present) {
2036             *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
2037         }
2038         if (p_ccb->our_cfg.flush_to_present) {
2039             *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
2040         }
2041         if (p_ccb->our_cfg.fcr_present) {
2042             *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCR;
2043         }
2044         if (p_ccb->our_cfg.fcs_present) {
2045             *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCS;
2046         }
2047         if (p_ccb->our_cfg.ext_flow_spec_present) {
2048             *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_EXT_FLOW_SPEC;
2049         }
2050 
2051         *pp_peer_cfg = &(p_ccb->peer_cfg);
2052         *p_peer_cfg_bits = p_ccb->peer_cfg_bits;
2053 
2054         return TRUE;
2055     } else {
2056         L2CAP_TRACE_ERROR ("No CCB for CID:0x%04x", lcid);
2057         return FALSE;
2058     }
2059 }
2060 
2061 /*******************************************************************************
2062 **
2063 ** Function         L2CA_RegForNoCPEvt
2064 **
2065 ** Description      Register callback for Number of Completed Packets event.
2066 **
2067 ** Input Param      p_cb - callback for Number of completed packets event
2068 **                  p_bda - BT address of remote device
2069 **
2070 ** Returns          TRUE if registered OK, else FALSE
2071 **
2072 *******************************************************************************/
L2CA_RegForNoCPEvt(tL2CA_NOCP_CB * p_cb,BD_ADDR p_bda)2073 BOOLEAN L2CA_RegForNoCPEvt(tL2CA_NOCP_CB *p_cb, BD_ADDR p_bda)
2074 {
2075     tL2C_LCB        *p_lcb;
2076 
2077     /* Find the link that is associated with this remote bdaddr */
2078     p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
2079 
2080     /* If no link for this handle, nothing to do. */
2081     if (!p_lcb) {
2082         return FALSE;
2083     }
2084 
2085     p_lcb->p_nocp_cb = p_cb;
2086 
2087     return TRUE;
2088 }
2089 #endif  ///CLASSIC_BT_INCLUDED == TRUE
2090 
2091 /*******************************************************************************
2092 **
2093 ** Function         L2CA_DataWrite
2094 **
2095 ** Description      Higher layers call this function to write data.
2096 **
2097 ** Returns          L2CAP_DW_SUCCESS, if data accepted, else FALSE
2098 **                  L2CAP_DW_CONGESTED, if data accepted and the channel is congested
2099 **                  L2CAP_DW_FAILED, if error
2100 **
2101 *******************************************************************************/
2102 #if (CLASSIC_BT_INCLUDED == TRUE)
L2CA_DataWrite(UINT16 cid,BT_HDR * p_data)2103 UINT8 L2CA_DataWrite (UINT16 cid, BT_HDR *p_data)
2104 {
2105     L2CAP_TRACE_API ("L2CA_DataWrite()  CID: 0x%04x  Len: %d", cid, p_data->len);
2106     return l2c_data_write (cid, p_data, L2CAP_FLUSHABLE_CH_BASED);
2107 }
2108 #endif  ///CLASSIC_BT_INCLUDED == TRUE
2109 
2110 /*******************************************************************************
2111 **
2112 ** Function         L2CA_SetChnlFlushability
2113 **
2114 ** Description      Higher layers call this function to set a channels
2115 **                  flushability flags
2116 **
2117 ** Returns          TRUE if CID found, else FALSE
2118 **
2119 *******************************************************************************/
L2CA_SetChnlFlushability(UINT16 cid,BOOLEAN is_flushable)2120 BOOLEAN L2CA_SetChnlFlushability (UINT16 cid, BOOLEAN is_flushable)
2121 {
2122 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2123 
2124     tL2C_CCB        *p_ccb;
2125 
2126     /* Find the channel control block. We don't know the link it is on. */
2127     if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) {
2128         L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_SetChnlFlushability, CID: %d", cid);
2129         return (FALSE);
2130     }
2131 
2132     p_ccb->is_flushable = is_flushable;
2133 
2134     L2CAP_TRACE_API ("L2CA_SetChnlFlushability()  CID: 0x%04x  is_flushable: %d", cid, is_flushable);
2135 
2136 #endif
2137 
2138     return (TRUE);
2139 }
2140 
2141 /*******************************************************************************
2142 **
2143 ** Function         L2CA_DataWriteEx
2144 **
2145 ** Description      Higher layers call this function to write data with extended
2146 **                  flags.
2147 **                  flags : L2CAP_FLUSHABLE_CH_BASED
2148 **                          L2CAP_FLUSHABLE_PKT
2149 **                          L2CAP_NON_FLUSHABLE_PKT
2150 **
2151 ** Returns          L2CAP_DW_SUCCESS, if data accepted, else FALSE
2152 **                  L2CAP_DW_CONGESTED, if data accepted and the channel is congested
2153 **                  L2CAP_DW_FAILED, if error
2154 **
2155 *******************************************************************************/
2156 #if (CLASSIC_BT_INCLUDED == TRUE)
L2CA_DataWriteEx(UINT16 cid,BT_HDR * p_data,UINT16 flags)2157 UINT8 L2CA_DataWriteEx (UINT16 cid, BT_HDR *p_data, UINT16 flags)
2158 {
2159     L2CAP_TRACE_API ("L2CA_DataWriteEx()  CID: 0x%04x  Len: %d Flags:0x%04X",
2160                      cid, p_data->len, flags);
2161     return l2c_data_write (cid, p_data, flags);
2162 }
2163 #endif  ///CLASSIC_BT_INCLUDED == TRUE
2164 
2165 /*******************************************************************************
2166 **
2167 ** Function     L2CA_FlushChannel
2168 **
2169 ** Description  This function flushes none, some or all buffers queued up
2170 **              for xmission for a particular CID. If called with
2171 **              L2CAP_FLUSH_CHANS_GET (0), it simply returns the number
2172 **              of buffers queued for that CID L2CAP_FLUSH_CHANS_ALL (0xffff)
2173 **              flushes all buffers.  All other values specifies the maximum
2174 **              buffers to flush.
2175 **
2176 ** Returns      Number of buffers left queued for that CID
2177 **
2178 *******************************************************************************/
L2CA_FlushChannel(UINT16 lcid,UINT16 num_to_flush)2179 UINT16 L2CA_FlushChannel (UINT16 lcid, UINT16 num_to_flush)
2180 {
2181     tL2C_CCB        *p_ccb;
2182     tL2C_LCB        *p_lcb;
2183     UINT16          num_left = 0,
2184                     num_flushed1 = 0,
2185                     num_flushed2 = 0;
2186 
2187     p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
2188 
2189     if ( !p_ccb || ((p_lcb = p_ccb->p_lcb) == NULL) ) {
2190         L2CAP_TRACE_WARNING ("L2CA_FlushChannel()  abnormally returning 0  CID: 0x%04x", lcid);
2191         return (0);
2192     }
2193 
2194     if (num_to_flush != L2CAP_FLUSH_CHANS_GET) {
2195         L2CAP_TRACE_API ("L2CA_FlushChannel (FLUSH)  CID: 0x%04x  NumToFlush: %d  QC: %u  pFirst: %p",
2196                          lcid, num_to_flush,
2197                          fixed_queue_length(p_ccb->xmit_hold_q),
2198                          fixed_queue_try_peek_first(p_ccb->xmit_hold_q));
2199     } else {
2200         L2CAP_TRACE_API ("L2CA_FlushChannel (QUERY)  CID: 0x%04x", lcid);
2201     }
2202 
2203     /* Cannot flush eRTM buffers once they have a sequence number */
2204     if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) {
2205 #if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE
2206         if (num_to_flush != L2CAP_FLUSH_CHANS_GET) {
2207             /* If the controller supports enhanced flush, flush the data queued at the controller */
2208             if ( (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ()))
2209                     && (BTM_GetNumScoLinks() == 0) ) {
2210                 if ( l2cb.is_flush_active == FALSE ) {
2211                     l2cb.is_flush_active = TRUE;
2212 
2213                     /* The only packet type defined - 0 - Automatically-Flushable Only */
2214                     btsnd_hcic_enhanced_flush (p_lcb->handle, 0);
2215                 }
2216             }
2217         }
2218 #endif
2219 
2220         // Iterate though list and flush the amount requested from
2221         // the transmit data queue that satisfy the layer and event conditions.
2222         for (const list_node_t *node = list_begin(p_lcb->link_xmit_data_q);
2223                 (num_to_flush > 0) && node != list_end(p_lcb->link_xmit_data_q);) {
2224             BT_HDR *p_buf = (BT_HDR *)list_node(node);
2225             node = list_next(node);
2226             if ((p_buf->layer_specific == 0) && (p_buf->event == lcid)) {
2227                 num_to_flush--;
2228                 num_flushed1++;
2229 
2230                 list_remove(p_lcb->link_xmit_data_q, p_buf);
2231                 osi_free(p_buf);
2232             }
2233         }
2234     }
2235 
2236     /* If needed, flush buffers in the CCB xmit hold queue */
2237     while ( (num_to_flush != 0) && (!fixed_queue_is_empty(p_ccb->xmit_hold_q))) {
2238         BT_HDR *p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->xmit_hold_q, 0);
2239         if (p_buf) {
2240             osi_free (p_buf);
2241         }
2242         num_to_flush--;
2243         num_flushed2++;
2244     }
2245 
2246     /* If app needs to track all packets, call him */
2247     if ( (p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_TxComplete_Cb) && (num_flushed2) ) {
2248         (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, num_flushed2);
2249     }
2250 
2251     /* Now count how many are left */
2252     for (const list_node_t *node = list_begin(p_lcb->link_xmit_data_q);
2253             node != list_end(p_lcb->link_xmit_data_q);
2254             node = list_next(node)) {
2255 
2256         BT_HDR *p_buf = (BT_HDR *)list_node(node);
2257         if (p_buf->event == lcid) {
2258             num_left++;
2259         }
2260     }
2261 
2262     /* Add in the number in the CCB xmit queue */
2263     num_left += fixed_queue_length(p_ccb->xmit_hold_q);
2264 
2265     /* Return the local number of buffers left for the CID */
2266     L2CAP_TRACE_DEBUG ("L2CA_FlushChannel()  flushed: %u + %u,  num_left: %u", num_flushed1, num_flushed2, num_left);
2267 
2268     /* If we were congested, and now we are not, tell the app */
2269     l2cu_check_channel_congestion (p_ccb);
2270 
2271     return (num_left);
2272 }
2273 
2274 /******************************************************************************
2275 **
2276 ** Function         update_acl_pkt_num
2277 **
2278 ** Description      Update the number of att acl packets to be sent in xmit_hold_q.
2279 **
2280 ** Returns          None
2281 **
2282 *******************************************************************************/
2283 #if BLE_INCLUDED == TRUE
l2ble_update_att_acl_pkt_num(UINT8 type,tl2c_buff_param_t * param)2284 void l2ble_update_att_acl_pkt_num(UINT8 type, tl2c_buff_param_t *param)
2285 {
2286     static SemaphoreHandle_t buff_semaphore = NULL ;
2287     static INT16 btc_buf;
2288     static INT16 btu_buf;
2289 
2290     if(buff_semaphore == NULL && type != L2CA_BUFF_INI){
2291         L2CAP_TRACE_ERROR("%s buff_semaphore not init", __func__);
2292         return;
2293     }
2294     switch (type)
2295     {
2296     case L2CA_ADD_BTC_NUM:{
2297         xSemaphoreTake(buff_semaphore, portMAX_DELAY);
2298         btc_buf ++;
2299         xSemaphoreGive(buff_semaphore);
2300         break;
2301     }
2302     case L2CA_DECREASE_BTC_NUM:{
2303         xSemaphoreTake(buff_semaphore, portMAX_DELAY);
2304         btc_buf --;
2305         xSemaphoreGive(buff_semaphore);
2306         break;
2307     }
2308     case L2CA_ADD_BTU_NUM:{
2309         xSemaphoreTake(buff_semaphore, portMAX_DELAY);
2310         btu_buf ++;
2311         xSemaphoreGive(buff_semaphore);
2312         break;
2313     }
2314     case L2CA_DECREASE_BTU_NUM:{
2315         xSemaphoreTake(buff_semaphore, portMAX_DELAY);
2316         btu_buf --;
2317         xSemaphoreGive(buff_semaphore);
2318         break;
2319     }
2320     case L2CA_GET_ATT_NUM:{
2321         xSemaphoreTake(buff_semaphore, portMAX_DELAY);
2322         INT16 att_acl_pkt_num = 0;
2323         INT16 att_max_num = 0;
2324         *(param->get_num) = 0;
2325         UINT8 tcb_idx = param->conn_id;
2326         tGATT_TCB * p_tcb = gatt_get_tcb_by_idx(tcb_idx);
2327         if (p_tcb == NULL){
2328             L2CAP_TRACE_ERROR("%s not found p_tcb", __func__);
2329             xSemaphoreGive(buff_semaphore);
2330             break;
2331         }
2332         tL2C_LCB * p_lcb = l2cu_find_lcb_by_bd_addr (p_tcb->peer_bda, BT_TRANSPORT_LE);
2333         if (p_lcb == NULL){
2334             L2CAP_TRACE_ERROR("%s not found p_lcb", __func__);
2335             xSemaphoreGive(buff_semaphore);
2336             break;
2337         }
2338         fixed_queue_t * queue = p_lcb->p_fixed_ccbs[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q;
2339         att_max_num = MIN(p_lcb->link_xmit_quota, L2CAP_CACHE_ATT_ACL_NUM);
2340         if (queue == NULL){
2341             L2CAP_TRACE_ERROR("%s not found queue", __func__);
2342             xSemaphoreGive(buff_semaphore);
2343             break;
2344         }
2345         att_acl_pkt_num = fixed_queue_length(queue);
2346         if(att_acl_pkt_num < att_max_num){
2347             if(btc_buf + btu_buf < att_max_num - att_acl_pkt_num){
2348                 *(param->get_num) = att_max_num - att_acl_pkt_num - (btc_buf + btu_buf);
2349             }
2350         }
2351         xSemaphoreGive(buff_semaphore);
2352         break;
2353     }
2354     case L2CA_BUFF_INI:{
2355         btc_buf = 0;
2356         btu_buf = 0;
2357         buff_semaphore = xSemaphoreCreateBinary();
2358         if (buff_semaphore == NULL) {
2359             L2CAP_TRACE_ERROR("%s NO MEMORY", __func__);
2360             break;
2361         }
2362         xSemaphoreGive(buff_semaphore);
2363         break;
2364     }
2365     case L2CA_BUFF_DEINIT:{
2366         xSemaphoreTake(buff_semaphore, portMAX_DELAY);
2367         btc_buf = 0;
2368         btu_buf = 0;
2369         xSemaphoreGive(buff_semaphore);
2370         vSemaphoreDelete(buff_semaphore);
2371         buff_semaphore = NULL;
2372         break;
2373     }
2374     default:
2375         break;
2376     }
2377 }
2378 #endif
2379