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