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