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 = #
1880 l2ble_update_att_acl_pkt_num(L2CA_GET_ATT_NUM, ¶m);
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