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 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28
29 #include "gki.h"
30 #include "bt_types.h"
31 #include "hcidefs.h"
32 #include "hcimsgs.h"
33 #include "l2cdefs.h"
34 #include "l2c_int.h"
35 #include "btu.h"
36 #include "btm_api.h"
37
38 /*******************************************************************************
39 **
40 ** Function L2CA_Register
41 **
42 ** Description Other layers call this function to register for L2CAP
43 ** services.
44 **
45 ** Returns PSM to use or zero if error. Typically, the PSM returned
46 ** is the same as was passed in, but for an outgoing-only
47 ** connection to a dynamic PSM, a "virtual" PSM is returned
48 ** and should be used in the calls to L2CA_ConnectReq(),
49 ** L2CA_ErtmConnectReq() and L2CA_Deregister()
50 **
51 *******************************************************************************/
L2CA_Register(UINT16 psm,tL2CAP_APPL_INFO * p_cb_info)52 UINT16 L2CA_Register (UINT16 psm, tL2CAP_APPL_INFO *p_cb_info)
53 {
54 tL2C_RCB *p_rcb;
55 UINT16 vpsm = psm;
56
57 L2CAP_TRACE_API1 ("L2CAP - L2CA_Register() called for PSM: 0x%04x", psm);
58
59 /* Verify that the required callback info has been filled in
60 ** Note: Connection callbacks are required but not checked
61 ** for here because it is possible to be only a client
62 ** or only a server.
63 */
64 if ((!p_cb_info->pL2CA_ConfigCfm_Cb)
65 || (!p_cb_info->pL2CA_ConfigInd_Cb)
66 || (!p_cb_info->pL2CA_DataInd_Cb)
67 || (!p_cb_info->pL2CA_DisconnectInd_Cb))
68 {
69 L2CAP_TRACE_ERROR1 ("L2CAP - no cb registering PSM: 0x%04x", psm);
70 return (0);
71 }
72
73 /* Verify PSM is valid */
74 if (L2C_INVALID_PSM(psm))
75 {
76 L2CAP_TRACE_ERROR1 ("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 {
84 for (vpsm = 0x1002; vpsm < 0x8000; vpsm += 2)
85 {
86 if ((p_rcb = l2cu_find_rcb_by_psm (vpsm)) == NULL)
87 break;
88 }
89
90 L2CAP_TRACE_API2 ("L2CA_Register - Real PSM: 0x%04x Virtual PSM: 0x%04x", psm, vpsm);
91 }
92
93 /* If registration block already there, just overwrite it */
94 if ((p_rcb = l2cu_find_rcb_by_psm (vpsm)) == NULL)
95 {
96 if ((p_rcb = l2cu_allocate_rcb (vpsm)) == NULL)
97 {
98 L2CAP_TRACE_WARNING2 ("L2CAP - no RCB available, PSM: 0x%04x vPSM: 0x%04x", psm, vpsm);
99 return (0);
100 }
101 }
102
103 p_rcb->api = *p_cb_info;
104 p_rcb->real_psm = psm;
105
106 return (vpsm);
107 }
108
109
110
111 /*******************************************************************************
112 **
113 ** Function L2CA_Deregister
114 **
115 ** Description Other layers call this function to de-register for L2CAP
116 ** services.
117 **
118 ** Returns void
119 **
120 *******************************************************************************/
L2CA_Deregister(UINT16 psm)121 void L2CA_Deregister (UINT16 psm)
122 {
123 tL2C_RCB *p_rcb;
124 tL2C_CCB *p_ccb;
125 tL2C_LCB *p_lcb;
126 int ii;
127
128 L2CAP_TRACE_API1 ("L2CAP - L2CA_Deregister() called for PSM: 0x%04x", psm);
129
130 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) != NULL)
131 {
132 p_lcb = &l2cb.lcb_pool[0];
133 for (ii = 0; ii < MAX_L2CAP_LINKS; ii++, p_lcb++)
134 {
135 if (p_lcb->in_use)
136 {
137 if (((p_ccb = p_lcb->ccb_queue.p_first_ccb) == NULL)
138 || (p_lcb->link_state == LST_DISCONNECTING))
139 continue;
140
141 if ((p_ccb->in_use) &&
142 ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
143 (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP)))
144 continue;
145
146 if (p_ccb->p_rcb == p_rcb)
147 l2c_csm_execute (p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
148 }
149 }
150 l2cu_release_rcb (p_rcb);
151 }
152 else
153 {
154 L2CAP_TRACE_WARNING1 ("L2CAP - PSM: 0x%04x not found for deregistration", psm);
155 }
156 }
157
158 /*******************************************************************************
159 **
160 ** Function L2CA_AllocatePSM
161 **
162 ** Description Other layers call this function to find an unused PSM for L2CAP
163 ** services.
164 **
165 ** Returns PSM to use.
166 **
167 *******************************************************************************/
L2CA_AllocatePSM(void)168 UINT16 L2CA_AllocatePSM(void)
169 {
170 BOOLEAN done = FALSE;
171 UINT16 psm = l2cb.dyn_psm;
172
173 L2CAP_TRACE_API0( "L2CA_AllocatePSM");
174 while (!done)
175 {
176 psm += 2;
177 if (psm > 0xfeff)
178 {
179 psm = 0x1001;
180 }
181 else if (psm & 0x0100)
182 {
183 /* the upper byte must be even */
184 psm += 0x0100;
185 }
186
187 /* if psm is in range of reserved BRCM Aware features */
188 if ((BRCM_RESERVED_PSM_START <= psm)&&(psm <= BRCM_RESERVED_PSM_END))
189 continue;
190
191 /* make sure the newlly allocated psm is not used right now */
192 if ((l2cu_find_rcb_by_psm (psm)) == NULL)
193 done = TRUE;
194 }
195 l2cb.dyn_psm = psm;
196
197 return(psm);
198 }
199
200 /*******************************************************************************
201 **
202 ** Function L2CA_ConnectReq
203 **
204 ** Description Higher layers call this function to create an L2CAP connection.
205 ** Note that the connection is not established at this time, but
206 ** connection establishment gets started. The callback function
207 ** will be invoked when connection establishes or fails.
208 **
209 ** Returns the CID of the connection, or 0 if it failed to start
210 **
211 *******************************************************************************/
L2CA_ConnectReq(UINT16 psm,BD_ADDR p_bd_addr)212 UINT16 L2CA_ConnectReq (UINT16 psm, BD_ADDR p_bd_addr)
213 {
214 return L2CA_ErtmConnectReq (psm, p_bd_addr, NULL);
215 }
216
217 /*******************************************************************************
218 **
219 ** Function L2CA_ErtmConnectReq
220 **
221 ** Description Higher layers call this function to create an L2CAP connection.
222 ** Note that the connection is not established at this time, but
223 ** connection establishment gets started. The callback function
224 ** will be invoked when connection establishes or fails.
225 **
226 ** Returns the CID of the connection, or 0 if it failed to start
227 **
228 *******************************************************************************/
L2CA_ErtmConnectReq(UINT16 psm,BD_ADDR p_bd_addr,tL2CAP_ERTM_INFO * p_ertm_info)229 UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_ertm_info)
230 {
231 tL2C_LCB *p_lcb;
232 tL2C_CCB *p_ccb;
233 tL2C_RCB *p_rcb;
234
235 L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info: 0x%08x allowed:0x%x preferred:%d", psm,
236 (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
237 (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info,
238 (p_ertm_info) ? p_ertm_info->allowed_modes : 0, (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
239
240 /* Fail if we have not established communications with the controller */
241 if (!BTM_IsDeviceUp())
242 {
243 L2CAP_TRACE_WARNING0 ("L2CAP connect req - BTU not ready");
244 return (0);
245 }
246 /* Fail if the PSM is not registered */
247 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
248 {
249 L2CAP_TRACE_WARNING1 ("L2CAP - no RCB for L2CA_conn_req, PSM: 0x%04x", psm);
250 return (0);
251 }
252
253 /* First, see if we already have a link to the remote */
254 if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
255 {
256 /* No link. Get an LCB and start link establishment */
257 if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
258 || (l2cu_create_conn(p_lcb) == FALSE) )
259 {
260 L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x p_lcb: 0x%08x", psm, p_lcb);
261 return (0);
262 }
263 }
264
265 /* Allocate a channel control block */
266 if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL)
267 {
268 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_conn_req, PSM: 0x%04x", psm);
269 return (0);
270 }
271
272 /* Save registration info */
273 p_ccb->p_rcb = p_rcb;
274
275 if (p_ertm_info)
276 {
277 p_ccb->ertm_info = *p_ertm_info;
278
279 /* Replace default indicators with the actual default pool */
280 if (p_ccb->ertm_info.fcr_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
281 p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_FCR_RX_POOL_ID;
282
283 if (p_ccb->ertm_info.fcr_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
284 p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_FCR_TX_POOL_ID;
285
286 if (p_ccb->ertm_info.user_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
287 p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
288
289 if (p_ccb->ertm_info.user_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
290 p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
291
292 p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
293 }
294
295 /* If link is up, start the L2CAP connection */
296 if (p_lcb->link_state == LST_CONNECTED)
297 {
298 l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_REQ, NULL);
299 }
300
301 /* If link is disconnecting, save link info to retry after disconnect
302 * Possible Race condition when a reconnect occurs
303 * on the channel during a disconnect of link. This
304 * ccb will be automatically retried after link disconnect
305 * arrives
306 */
307 else if (p_lcb->link_state == LST_DISCONNECTING)
308 {
309 L2CAP_TRACE_DEBUG0 ("L2CAP API - link disconnecting: RETRY LATER");
310
311 /* Save ccb so it can be started after disconnect is finished */
312 p_lcb->p_pending_ccb = p_ccb;
313 }
314
315 L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x", psm, p_ccb->local_cid);
316
317 /* Return the local CID as our handle */
318 return (p_ccb->local_cid);
319 }
320
321
322 /*******************************************************************************
323 **
324 ** Function L2CA_ConnectRsp
325 **
326 ** Description Higher layers call this function to accept an incoming
327 ** L2CAP connection, for which they had gotten an connect
328 ** indication callback.
329 **
330 ** Returns TRUE for success, FALSE for failure
331 **
332 *******************************************************************************/
L2CA_ConnectRsp(BD_ADDR p_bd_addr,UINT8 id,UINT16 lcid,UINT16 result,UINT16 status)333 BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, UINT16 status)
334 {
335 return L2CA_ErtmConnectRsp (p_bd_addr, id, lcid, result, status, NULL);
336 }
337
338
339 /*******************************************************************************
340 **
341 ** Function L2CA_ErtmConnectRsp
342 **
343 ** Description Higher layers call this function to accept an incoming
344 ** L2CAP connection, for which they had gotten an connect
345 ** indication callback.
346 **
347 ** Returns TRUE for success, FALSE for failure
348 **
349 *******************************************************************************/
L2CA_ErtmConnectRsp(BD_ADDR p_bd_addr,UINT8 id,UINT16 lcid,UINT16 result,UINT16 status,tL2CAP_ERTM_INFO * p_ertm_info)350 BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result,
351 UINT16 status, tL2CAP_ERTM_INFO *p_ertm_info)
352 {
353 tL2C_LCB *p_lcb;
354 tL2C_CCB *p_ccb;
355
356 L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x p_ertm_info:0x%08x",
357 lcid, result, status,
358 (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
359 (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info);
360
361 /* First, find the link control block */
362 if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
363 {
364 /* No link. Get an LCB and start link establishment */
365 L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_rsp");
366 return (FALSE);
367 }
368
369 /* Now, find the channel control block */
370 if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) == NULL)
371 {
372 L2CAP_TRACE_WARNING0 ("L2CAP - no CCB for L2CA_conn_rsp");
373 return (FALSE);
374 }
375
376 /* The IDs must match */
377 if (p_ccb->remote_id != id)
378 {
379 L2CAP_TRACE_WARNING2 ("L2CAP - bad id in L2CA_conn_rsp. Exp: %d Got: %d", p_ccb->remote_id, id);
380 return (FALSE);
381 }
382
383 if (p_ertm_info)
384 {
385 p_ccb->ertm_info = *p_ertm_info;
386
387 /* Replace default indicators with the actual default pool */
388 if (p_ccb->ertm_info.fcr_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
389 p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_FCR_RX_POOL_ID;
390
391 if (p_ccb->ertm_info.fcr_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
392 p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_FCR_TX_POOL_ID;
393
394 if (p_ccb->ertm_info.user_rx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
395 p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
396
397 if (p_ccb->ertm_info.user_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
398 p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
399
400 p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
401 }
402
403 if (result == L2CAP_CONN_OK)
404 {
405 l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
406 }
407 else
408 {
409 tL2C_CONN_INFO conn_info;
410
411 conn_info.l2cap_result = result;
412 conn_info.l2cap_status = status;
413
414 if (result == L2CAP_CONN_PENDING)
415 l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_RSP, &conn_info);
416 else
417 l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONNECT_RSP_NEG, &conn_info);
418 }
419
420 return (TRUE);
421 }
422
423
424 /*******************************************************************************
425 **
426 ** Function L2CA_ConfigReq
427 **
428 ** Description Higher layers call this function to send configuration.
429 **
430 ** Note: The FCR options of p_cfg are not used.
431 **
432 ** Returns TRUE if configuration sent, else FALSE
433 **
434 *******************************************************************************/
L2CA_ConfigReq(UINT16 cid,tL2CAP_CFG_INFO * p_cfg)435 BOOLEAN L2CA_ConfigReq (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
436 {
437 tL2C_CCB *p_ccb;
438
439 L2CAP_TRACE_API5 ("L2CA_ConfigReq() CID 0x%04x: fcr_present:%d (mode %d) mtu_present:%d (%d)",
440 cid, p_cfg->fcr_present, p_cfg->fcr.mode, p_cfg->mtu_present, p_cfg->mtu);
441
442 /* Find the channel control block. We don't know the link it is on. */
443 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
444 {
445 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_cfg_req, CID: %d", cid);
446 return (FALSE);
447 }
448
449 /* We need to have at least one mode type common with the peer */
450 if (!l2c_fcr_adj_our_req_options(p_ccb, p_cfg))
451 return (FALSE);
452
453 /* Don't adjust FCR options if not used */
454 if ((!p_cfg->fcr_present)||(p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE))
455 {
456 /* FCR and FCS options are not used in basic mode */
457 p_cfg->fcs_present = FALSE;
458 p_cfg->ext_flow_spec_present = FALSE;
459
460 if ( (p_cfg->mtu_present) && (p_cfg->mtu > L2CAP_MTU_SIZE) )
461 {
462 L2CAP_TRACE_WARNING1 ("L2CAP - adjust MTU: %u too large", p_cfg->mtu);
463 p_cfg->mtu = L2CAP_MTU_SIZE;
464 }
465 }
466
467 /* Save the adjusted configuration in case it needs to be used for renegotiation */
468 p_ccb->our_cfg = *p_cfg;
469
470 l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONFIG_REQ, p_cfg);
471
472 return (TRUE);
473 }
474
475
476 /*******************************************************************************
477 **
478 ** Function L2CA_ConfigRsp
479 **
480 ** Description Higher layers call this function to send a configuration
481 ** response.
482 **
483 ** Returns TRUE if configuration response sent, else FALSE
484 **
485 *******************************************************************************/
L2CA_ConfigRsp(UINT16 cid,tL2CAP_CFG_INFO * p_cfg)486 BOOLEAN L2CA_ConfigRsp (UINT16 cid, tL2CAP_CFG_INFO *p_cfg)
487 {
488 tL2C_CCB *p_ccb;
489
490 L2CAP_TRACE_API6 ("L2CA_ConfigRsp() CID: 0x%04x Result: %d MTU present:%d Flush TO:%d FCR:%d FCS:%d",
491 cid, p_cfg->result, p_cfg->mtu_present, p_cfg->flush_to_present, p_cfg->fcr_present, p_cfg->fcs_present);
492
493 /* Find the channel control block. We don't know the link it is on. */
494 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
495 {
496 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_cfg_rsp, CID: %d", cid);
497 return (FALSE);
498 }
499
500 if ( (p_cfg->result == L2CAP_CFG_OK) || (p_cfg->result == L2CAP_CFG_PENDING) )
501 l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONFIG_RSP, p_cfg);
502 else
503 {
504 p_cfg->fcr_present = FALSE; /* FCR options already negotiated before this point */
505
506 /* Clear out any cached options that are being returned as an error (excluding FCR) */
507 if (p_cfg->mtu_present)
508 p_ccb->peer_cfg.mtu_present = FALSE;
509 if (p_cfg->flush_to_present)
510 p_ccb->peer_cfg.flush_to_present = FALSE;
511 if (p_cfg->qos_present)
512 p_ccb->peer_cfg.qos_present = FALSE;
513
514 l2c_csm_execute (p_ccb, L2CEVT_L2CA_CONFIG_RSP_NEG, p_cfg);
515 }
516
517 return (TRUE);
518 }
519
520
521 /*******************************************************************************
522 **
523 ** Function L2CA_DisconnectReq
524 **
525 ** Description Higher layers call this function to disconnect a channel.
526 **
527 ** Returns TRUE if disconnect sent, else FALSE
528 **
529 *******************************************************************************/
L2CA_DisconnectReq(UINT16 cid)530 BOOLEAN L2CA_DisconnectReq (UINT16 cid)
531 {
532 tL2C_CCB *p_ccb;
533
534 L2CAP_TRACE_API1 ("L2CA_DisconnectReq() CID: 0x%04x", cid);
535
536 /* Find the channel control block. We don't know the link it is on. */
537 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
538 {
539 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_disc_req, CID: %d", cid);
540 return (FALSE);
541 }
542
543 l2c_csm_execute (p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
544
545 return (TRUE);
546 }
547
548 /*******************************************************************************
549 **
550 ** Function L2CA_DisconnectRsp
551 **
552 ** Description Higher layers call this function to acknowledge the
553 ** disconnection of a channel.
554 **
555 ** Returns void
556 **
557 *******************************************************************************/
L2CA_DisconnectRsp(UINT16 cid)558 BOOLEAN L2CA_DisconnectRsp (UINT16 cid)
559 {
560 tL2C_CCB *p_ccb;
561
562 L2CAP_TRACE_API1 ("L2CA_DisconnectRsp() CID: 0x%04x", cid);
563
564 /* Find the channel control block. We don't know the link it is on. */
565 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
566 {
567 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_disc_rsp, CID: %d", cid);
568 return (FALSE);
569 }
570
571 l2c_csm_execute (p_ccb, L2CEVT_L2CA_DISCONNECT_RSP, NULL);
572
573 return (TRUE);
574 }
575
576 /*******************************************************************************
577 **
578 ** Function L2CA_Ping
579 **
580 ** Description Higher layers call this function to send an echo request.
581 **
582 ** Returns TRUE if echo request sent, else FALSE.
583 **
584 *******************************************************************************/
L2CA_Ping(BD_ADDR p_bd_addr,tL2CA_ECHO_RSP_CB * p_callback)585 BOOLEAN L2CA_Ping (BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB *p_callback)
586 {
587 tL2C_LCB *p_lcb;
588
589 L2CAP_TRACE_API6 ("L2CA_Ping() BDA: %02x-%02x-%02x-%02x-%02x-%02x",
590 p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3], p_bd_addr[4], p_bd_addr[5]);
591
592 /* Fail if we have not established communications with the controller */
593 if (!BTM_IsDeviceUp())
594 return (FALSE);
595
596 /* First, see if we already have a link to the remote */
597 if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
598 {
599 /* No link. Get an LCB and start link establishment */
600 if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
601 {
602 L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_ping");
603 return (FALSE);
604 }
605 if (l2cu_create_conn(p_lcb) == FALSE)
606 {
607 return (FALSE);
608 }
609
610 p_lcb->p_echo_rsp_cb = p_callback;
611
612 return (TRUE);
613 }
614
615 /* We only allow 1 ping outstanding at a time */
616 if (p_lcb->p_echo_rsp_cb != NULL)
617 {
618 L2CAP_TRACE_WARNING0 ("L2CAP - rejected second L2CA_ping");
619 return (FALSE);
620 }
621
622 /* Have a link control block. If link is disconnecting, tell user to retry later */
623 if (p_lcb->link_state == LST_DISCONNECTING)
624 {
625 L2CAP_TRACE_WARNING0 ("L2CAP - L2CA_ping rejected - link disconnecting");
626 return (FALSE);
627 }
628
629 /* Save address of callback */
630 p_lcb->p_echo_rsp_cb = p_callback;
631
632 if (p_lcb->link_state == LST_CONNECTED)
633 {
634 l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */
635 l2cu_send_peer_echo_req (p_lcb, NULL, 0);
636 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_ECHO_RSP_TOUT);
637 }
638
639 return (TRUE);
640 }
641
642 /*******************************************************************************
643 **
644 ** Function L2CA_Echo
645 **
646 ** Description Higher layers call this function to send an echo request
647 ** with application-specific data.
648 **
649 ** Returns TRUE if echo request sent, else FALSE.
650 **
651 *******************************************************************************/
L2CA_Echo(BD_ADDR p_bd_addr,BT_HDR * p_data,tL2CA_ECHO_DATA_CB * p_callback)652 BOOLEAN L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_callback)
653 {
654 tL2C_LCB *p_lcb;
655 UINT8 *pp;
656
657 L2CAP_TRACE_API2 ("L2CA_Echo() BDA: %08X%04X",
658 ((p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) + (p_bd_addr[3])),
659 ((p_bd_addr[4] << 8) + (p_bd_addr[5])));
660
661 /* Fail if we have not established communications with the controller */
662 if (!BTM_IsDeviceUp())
663 return (FALSE);
664
665 if ((memcmp(BT_BD_ANY, p_bd_addr, BD_ADDR_LEN) == 0) && (p_data == NULL))
666 {
667 /* Only register callback without sending message. */
668 l2cb.p_echo_data_cb = p_callback;
669 return TRUE;
670 }
671
672 /* We assume the upper layer will call this function only when the link is established. */
673 if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
674 {
675 L2CAP_TRACE_ERROR0 ("L2CA_Echo ERROR : link not established");
676 return FALSE;
677 }
678
679 if (p_lcb->link_state != LST_CONNECTED)
680 {
681 L2CAP_TRACE_ERROR0 ("L2CA_Echo ERROR : link is not connected");
682 return FALSE;
683 }
684
685 /* Save address of callback */
686 l2cb.p_echo_data_cb = p_callback;
687
688 /* Set the pointer to the beginning of the data */
689 pp = (UINT8 *)(p_data + 1) + p_data->offset;
690 l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */
691 l2cu_send_peer_echo_req (p_lcb, pp, p_data->len);
692
693 return (TRUE);
694
695 }
696
697 /*******************************************************************************
698 **
699 ** Function L2CA_SetIdleTimeout
700 **
701 ** Description Higher layers call this function to set the idle timeout for
702 ** a connection, or for all future connections. The "idle timeout"
703 ** is the amount of time that a connection can remain up with
704 ** no L2CAP channels on it. A timeout of zero means that the
705 ** connection will be torn down immediately when the last channel
706 ** is removed. A timeout of 0xFFFF means no timeout. Values are
707 ** in seconds.
708 **
709 ** Returns TRUE if command succeeded, FALSE if failed
710 **
711 ** NOTE This timeout takes effect after at least 1 channel has been
712 ** established and removed. L2CAP maintains its own timer from
713 ** whan a connection is established till the first channel is
714 ** set up.
715 *******************************************************************************/
L2CA_SetIdleTimeout(UINT16 cid,UINT16 timeout,BOOLEAN is_global)716 BOOLEAN L2CA_SetIdleTimeout (UINT16 cid, UINT16 timeout, BOOLEAN is_global)
717 {
718 tL2C_CCB *p_ccb;
719 tL2C_LCB *p_lcb;
720
721 if (is_global)
722 {
723 l2cb.idle_timeout = timeout;
724 }
725 else
726 {
727 /* Find the channel control block. We don't know the link it is on. */
728 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
729 {
730 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetIdleTimeout, CID: %d", cid);
731 return (FALSE);
732 }
733
734 p_lcb = p_ccb->p_lcb;
735
736 if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
737 p_lcb->idle_timeout = timeout;
738 else
739 return (FALSE);
740 }
741
742 return (TRUE);
743 }
744
745 /*******************************************************************************
746 **
747 ** Function L2CA_SetIdleTimeoutByBdAddr
748 **
749 ** Description Higher layers call this function to set the idle timeout for
750 ** a connection. The "idle timeout" is the amount of time that
751 ** a connection can remain up with no L2CAP channels on it.
752 ** A timeout of zero means that the connection will be torn
753 ** down immediately when the last channel is removed.
754 ** A timeout of 0xFFFF means no timeout. Values are in seconds.
755 ** A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
756 ** then the idle timeouts for all active l2cap links will be
757 ** changed.
758 **
759 ** Returns TRUE if command succeeded, FALSE if failed
760 **
761 ** NOTE This timeout applies to all logical channels active on the
762 ** ACL link.
763 *******************************************************************************/
L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr,UINT16 timeout)764 BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout)
765 {
766 tL2C_LCB *p_lcb;
767
768 if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN))
769 {
770 p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr );
771 if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
772 p_lcb->idle_timeout = timeout;
773 else
774 return (FALSE);
775 }
776 else
777 {
778 int xx;
779 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
780
781 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
782 {
783 if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
784 {
785 p_lcb->idle_timeout = timeout;
786 }
787 }
788 }
789
790 return (TRUE);
791 }
792
793 /*******************************************************************************
794 **
795 ** Function L2CA_SetTraceLevel
796 **
797 ** Description This function sets the trace level for L2CAP. If called with
798 ** a value of 0xFF, it simply reads the current trace level.
799 **
800 ** Returns the new (current) trace level
801 **
802 *******************************************************************************/
L2CA_SetTraceLevel(UINT8 new_level)803 UINT8 L2CA_SetTraceLevel (UINT8 new_level)
804 {
805 if (new_level != 0xFF)
806 l2cb.l2cap_trace_level = new_level;
807
808 return (l2cb.l2cap_trace_level);
809 }
810
811
812 /*******************************************************************************
813 **
814 ** Function L2CA_SetDesireRole
815 **
816 ** Description This function sets the desire role for L2CAP.
817 ** If the new role is L2CAP_ROLE_ALLOW_SWITCH, allow switch on
818 ** HciCreateConnection.
819 ** If the new role is L2CAP_ROLE_DISALLOW_SWITCH, do not allow switch on
820 ** HciCreateConnection.
821 **
822 ** If the new role is a valid role (HCI_ROLE_MASTER or HCI_ROLE_SLAVE),
823 ** the desire role is set to the new value. Otherwise, it is not changed.
824 **
825 ** Returns the new (current) role
826 **
827 *******************************************************************************/
L2CA_SetDesireRole(UINT8 new_role)828 UINT8 L2CA_SetDesireRole (UINT8 new_role)
829 {
830 L2CAP_TRACE_API2 ("L2CA_SetDesireRole() new:x%x, disallow_switch:%d",
831 new_role, l2cb.disallow_switch);
832
833 if (L2CAP_ROLE_CHECK_SWITCH != (L2CAP_ROLE_CHECK_SWITCH & new_role))
834 {
835 /* do not process the allow_switch when both bits are set */
836 if (new_role & L2CAP_ROLE_ALLOW_SWITCH)
837 {
838 l2cb.disallow_switch = FALSE;
839 }
840 if (new_role & L2CAP_ROLE_DISALLOW_SWITCH)
841 {
842 l2cb.disallow_switch = TRUE;
843 }
844 }
845
846 if (new_role == HCI_ROLE_MASTER || new_role == HCI_ROLE_SLAVE)
847 l2cb.desire_role = new_role;
848
849 return (l2cb.desire_role);
850 }
851
852 /*******************************************************************************
853 **
854 ** Function L2CA_LocalLoopbackReq
855 **
856 ** Description This function sets up a CID for local loopback
857 **
858 ** Returns CID of 0 if none.
859 **
860 *******************************************************************************/
L2CA_LocalLoopbackReq(UINT16 psm,UINT16 handle,BD_ADDR p_bd_addr)861 UINT16 L2CA_LocalLoopbackReq (UINT16 psm, UINT16 handle, BD_ADDR p_bd_addr)
862 {
863 tL2C_LCB *p_lcb;
864 tL2C_CCB *p_ccb;
865 tL2C_RCB *p_rcb;
866
867 L2CAP_TRACE_API2 ("L2CA_LocalLoopbackReq() PSM: %d Handle: 0x%04x", psm, handle);
868
869 /* Fail if we have not established communications with the controller */
870 if (!BTM_IsDeviceUp())
871 {
872 L2CAP_TRACE_WARNING0 ("L2CAP loop req - BTU not ready");
873 return (0);
874 }
875
876 /* Fail if the PSM is not registered */
877 if ((p_rcb = l2cu_find_rcb_by_psm (psm)) == NULL)
878 {
879 L2CAP_TRACE_WARNING1 ("L2CAP - no RCB for L2CA_conn_req, PSM: %d", psm);
880 return (0);
881 }
882
883 if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
884 {
885 L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_req");
886 return (0);
887 }
888
889 p_lcb->link_state = LST_CONNECTED;
890 p_lcb->handle = handle;
891
892 /* Allocate a channel control block */
893 if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL)
894 {
895 L2CAP_TRACE_WARNING0 ("L2CAP - no CCB for L2CA_conn_req");
896 return (0);
897 }
898
899 /* Save registration info */
900 p_ccb->p_rcb = p_rcb;
901 p_ccb->chnl_state = CST_OPEN;
902 p_ccb->remote_cid = p_ccb->local_cid;
903 p_ccb->config_done = CFG_DONE_MASK;
904
905 /* Return the local CID as our handle */
906 return (p_ccb->local_cid);
907 }
908
909 /*******************************************************************************
910 **
911 ** Function L2CA_SetAclPriority
912 **
913 ** Description Sets the transmission priority for a channel.
914 ** (For initial implementation only two values are valid.
915 ** L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
916 **
917 ** Returns TRUE if a valid channel, else FALSE
918 **
919 *******************************************************************************/
L2CA_SetAclPriority(BD_ADDR bd_addr,UINT8 priority)920 BOOLEAN L2CA_SetAclPriority (BD_ADDR bd_addr, UINT8 priority)
921 {
922 L2CAP_TRACE_API6 ("L2CA_SetAclPriority() bdaddr: %02x%02x%02x%02x%04x, priority:%d",
923 bd_addr[0], bd_addr[1], bd_addr[2],
924 bd_addr[3], (bd_addr[4] << 8) + bd_addr[5], priority);
925
926 return (l2cu_set_acl_priority(bd_addr, priority, FALSE));
927 }
928
929 /*******************************************************************************
930 **
931 ** Function L2CA_FlowControl
932 **
933 ** Description Higher layers call this function to flow control a channel.
934 **
935 ** data_enabled - TRUE data flows, FALSE data is stopped
936 **
937 ** Returns TRUE if valid channel, else FALSE
938 **
939 *******************************************************************************/
L2CA_FlowControl(UINT16 cid,BOOLEAN data_enabled)940 BOOLEAN L2CA_FlowControl (UINT16 cid, BOOLEAN data_enabled)
941 {
942 tL2C_CCB *p_ccb;
943 BOOLEAN on_off = !data_enabled;
944
945 L2CAP_TRACE_API2 ("L2CA_FlowControl(%d) CID: 0x%04x", on_off, cid);
946
947 /* Find the channel control block. We don't know the link it is on. */
948 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
949 {
950 L2CAP_TRACE_WARNING2 ("L2CAP - no CCB for L2CA_FlowControl, CID: 0x%04x data_enabled: %d", cid, data_enabled);
951 return (FALSE);
952 }
953
954 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE)
955 {
956 L2CAP_TRACE_EVENT1 ("L2CA_FlowControl() invalid mode:%d", p_ccb->peer_cfg.fcr.mode);
957 return (FALSE);
958 }
959 if (p_ccb->fcrb.local_busy != on_off)
960 {
961 p_ccb->fcrb.local_busy = on_off;
962
963 if ( (p_ccb->chnl_state == CST_OPEN) && (!p_ccb->fcrb.wait_ack) )
964 {
965 if (on_off)
966 l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, 0);
967 else
968 l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_P_BIT);
969 }
970 }
971
972 return (TRUE);
973 }
974
975 /*******************************************************************************
976 **
977 ** Function L2CA_SendTestSFrame
978 **
979 ** Description Higher layers call this function to send a test S-frame.
980 **
981 ** Returns TRUE if valid Channel, else FALSE
982 **
983 *******************************************************************************/
L2CA_SendTestSFrame(UINT16 cid,UINT8 sup_type,UINT8 back_track)984 BOOLEAN L2CA_SendTestSFrame (UINT16 cid, UINT8 sup_type, UINT8 back_track)
985 {
986 tL2C_CCB *p_ccb;
987
988 L2CAP_TRACE_API3 ("L2CA_SendTestSFrame() CID: 0x%04x Type: 0x%02x back_track: %u", cid, sup_type, back_track);
989
990 /* Find the channel control block. We don't know the link it is on. */
991 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
992 {
993 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SendTestSFrame, CID: %d", cid);
994 return (FALSE);
995 }
996
997 if ( (p_ccb->chnl_state != CST_OPEN) || (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) )
998 return (FALSE);
999
1000 p_ccb->fcrb.next_seq_expected -= back_track;
1001
1002 l2c_fcr_send_S_frame (p_ccb, (UINT16)(sup_type & 3), (UINT16)(sup_type & (L2CAP_FCR_P_BIT | L2CAP_FCR_F_BIT)));
1003
1004 return (TRUE);
1005 }
1006
1007
1008 /*******************************************************************************
1009 **
1010 ** Function L2CA_SetTxPriority
1011 **
1012 ** Description Sets the transmission priority for a channel.
1013 **
1014 ** Returns TRUE if a valid channel, else FALSE
1015 **
1016 *******************************************************************************/
L2CA_SetTxPriority(UINT16 cid,tL2CAP_CHNL_PRIORITY priority)1017 BOOLEAN L2CA_SetTxPriority (UINT16 cid, tL2CAP_CHNL_PRIORITY priority)
1018 {
1019 tL2C_CCB *p_ccb;
1020
1021 L2CAP_TRACE_API2 ("L2CA_SetTxPriority() CID: 0x%04x, priority:%d", cid, priority);
1022
1023 /* Find the channel control block. We don't know the link it is on. */
1024 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
1025 {
1026 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetTxPriority, CID: %d", cid);
1027 return (FALSE);
1028 }
1029
1030 /* it will update the order of CCB in LCB by priority and update round robin service variables */
1031 l2cu_change_pri_ccb (p_ccb, priority);
1032
1033 return (TRUE);
1034 }
1035
1036 /*******************************************************************************
1037 **
1038 ** Function L2CA_SetChnlDataRate
1039 **
1040 ** Description Sets the tx/rx data rate for a channel.
1041 **
1042 ** Returns TRUE if a valid channel, else FALSE
1043 **
1044 *******************************************************************************/
L2CA_SetChnlDataRate(UINT16 cid,tL2CAP_CHNL_DATA_RATE tx,tL2CAP_CHNL_DATA_RATE rx)1045 BOOLEAN L2CA_SetChnlDataRate (UINT16 cid, tL2CAP_CHNL_DATA_RATE tx, tL2CAP_CHNL_DATA_RATE rx)
1046 {
1047 tL2C_CCB *p_ccb;
1048
1049 L2CAP_TRACE_API3 ("L2CA_SetChnlDataRate() CID: 0x%04x, tx:%d, rx:%d", cid, tx, rx);
1050
1051 /* Find the channel control block. We don't know the link it is on. */
1052 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
1053 {
1054 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetChnlDataRate, CID: %d", cid);
1055 return (FALSE);
1056 }
1057
1058 p_ccb->tx_data_rate = tx;
1059 p_ccb->rx_data_rate = rx;
1060
1061 /* Adjust channel buffer allocation */
1062 l2c_link_adjust_chnl_allocation ();
1063
1064 return(TRUE);
1065 }
1066
1067 /*******************************************************************************
1068 **
1069 ** Function L2CA_SetFlushTimeout
1070 **
1071 ** Description This function set the automatic flush time out in Baseband
1072 ** for ACL-U packets.
1073 ** BdAddr : the remote BD address of ACL link. If it is BT_DB_ANY
1074 ** then the flush time out will be applied to all ACL link.
1075 ** FlushTimeout: flush time out in ms
1076 ** 0x0000 : No automatic flush
1077 ** L2CAP_NO_RETRANSMISSION : No retransmission
1078 ** 0x0002 - 0xFFFE : flush time out, if (flush_tout*8)+3/5)
1079 ** <= HCI_MAX_AUTO_FLUSH_TOUT (in 625us slot).
1080 ** Otherwise, return FALSE.
1081 ** L2CAP_NO_AUTOMATIC_FLUSH : No automatic flush
1082 **
1083 ** Returns TRUE if command succeeded, FALSE if failed
1084 **
1085 ** NOTE This flush timeout applies to all logical channels active on the
1086 ** ACL link.
1087 *******************************************************************************/
L2CA_SetFlushTimeout(BD_ADDR bd_addr,UINT16 flush_tout)1088 BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
1089 {
1090 tL2C_LCB *p_lcb;
1091 UINT16 hci_flush_to;
1092 UINT32 temp;
1093
1094 /* no automatic flush (infinite timeout) */
1095 if (flush_tout == 0x0000)
1096 {
1097 hci_flush_to = flush_tout;
1098 flush_tout = L2CAP_NO_AUTOMATIC_FLUSH;
1099 }
1100 /* no retransmission */
1101 else if (flush_tout == L2CAP_NO_RETRANSMISSION)
1102 {
1103 /* not mandatory range for controller */
1104 /* Packet is flushed before getting any ACK/NACK */
1105 /* To do this, flush timeout should be 1 baseband slot */
1106 hci_flush_to = flush_tout;
1107 }
1108 /* no automatic flush (infinite timeout) */
1109 else if (flush_tout == L2CAP_NO_AUTOMATIC_FLUSH)
1110 {
1111 hci_flush_to = 0x0000;
1112 }
1113 else
1114 {
1115 /* convert L2CAP flush_to to 0.625 ms units, with round */
1116 temp = (((UINT32)flush_tout * 8) + 3) / 5;
1117
1118 /* if L2CAP flush_to within range of HCI, set HCI flush timeout */
1119 if (temp > HCI_MAX_AUTO_FLUSH_TOUT)
1120 {
1121 L2CAP_TRACE_WARNING1("WARNING L2CA_SetFlushTimeout timeout(0x%x) is out of range", flush_tout);
1122 return FALSE;
1123 }
1124 else
1125 {
1126 hci_flush_to = (UINT16)temp;
1127 }
1128 }
1129
1130 if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN))
1131 {
1132 p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
1133
1134 if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
1135 {
1136 if (p_lcb->link_flush_tout != flush_tout)
1137 {
1138 p_lcb->link_flush_tout = flush_tout;
1139
1140 L2CAP_TRACE_API4 ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
1141 flush_tout, bd_addr[3], bd_addr[4], bd_addr[5]);
1142
1143 if (!btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to))
1144 return (FALSE);
1145 }
1146 }
1147 else
1148 {
1149 L2CAP_TRACE_WARNING3 ("WARNING L2CA_SetFlushTimeout No lcb for bd_addr [...;%02x%02x%02x]",
1150 bd_addr[3], bd_addr[4], bd_addr[5]);
1151 return (FALSE);
1152 }
1153 }
1154 else
1155 {
1156 int xx;
1157 p_lcb = &l2cb.lcb_pool[0];
1158
1159 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
1160 {
1161 if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
1162 {
1163 if (p_lcb->link_flush_tout != flush_tout)
1164 {
1165 p_lcb->link_flush_tout = flush_tout;
1166
1167 L2CAP_TRACE_API4 ("L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
1168 flush_tout, p_lcb->remote_bd_addr[3],
1169 p_lcb->remote_bd_addr[4], p_lcb->remote_bd_addr[5]);
1170
1171 if (!btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to))
1172 return (FALSE);
1173 }
1174 }
1175 }
1176 }
1177
1178 return (TRUE);
1179 }
1180
1181 /*******************************************************************************
1182 **
1183 ** Function L2CA_GetPeerFeatures
1184 **
1185 ** Description Get a peers features and fixed channel map
1186 **
1187 ** Parameters: BD address of the peer
1188 ** Pointers to features and channel mask storage area
1189 **
1190 ** Return value: TRUE if peer is connected
1191 **
1192 *******************************************************************************/
L2CA_GetPeerFeatures(BD_ADDR bd_addr,UINT32 * p_ext_feat,UINT8 * p_chnl_mask)1193 BOOLEAN L2CA_GetPeerFeatures (BD_ADDR bd_addr, UINT32 *p_ext_feat, UINT8 *p_chnl_mask)
1194 {
1195 tL2C_LCB *p_lcb;
1196
1197 /* We must already have a link to the remote */
1198 if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) == NULL)
1199 {
1200 L2CAP_TRACE_WARNING2 ("L2CA_GetPeerFeatures() No BDA: %08x%04x",
1201 (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
1202 (bd_addr[4]<<8)+bd_addr[5]);
1203 return (FALSE);
1204 }
1205
1206 L2CAP_TRACE_API4 ("L2CA_GetPeerFeatures() BDA: %08x%04x ExtFea: 0x%08x Chnl_Mask[0]: 0x%02x",
1207 (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
1208 (bd_addr[4]<<8)+bd_addr[5], p_lcb->peer_ext_fea, p_lcb->peer_chnl_mask[0]);
1209
1210 *p_ext_feat = p_lcb->peer_ext_fea;
1211
1212 memcpy (p_chnl_mask, p_lcb->peer_chnl_mask, L2CAP_FIXED_CHNL_ARRAY_SIZE);
1213
1214 return (TRUE);
1215 }
1216
1217 /*******************************************************************************
1218 **
1219 ** Function L2CA_GetBDAddrbyHandle
1220 **
1221 ** Description Get BD address for the given HCI handle
1222 **
1223 ** Parameters: HCI handle
1224 ** BD address of the peer
1225 **
1226 ** Return value: TRUE if found lcb for the given handle, FALSE otherwise
1227 **
1228 *******************************************************************************/
L2CA_GetBDAddrbyHandle(UINT16 handle,BD_ADDR bd_addr)1229 BOOLEAN L2CA_GetBDAddrbyHandle (UINT16 handle, BD_ADDR bd_addr)
1230 {
1231 tL2C_LCB *p_lcb = NULL;
1232 BOOLEAN found_dev = FALSE;
1233
1234 p_lcb = l2cu_find_lcb_by_handle (handle);
1235 if (p_lcb)
1236 {
1237 found_dev = TRUE;
1238 memcpy (bd_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
1239 }
1240
1241 return found_dev;
1242 }
1243
1244 /*******************************************************************************
1245 **
1246 ** Function L2CA_GetChnlFcrMode
1247 **
1248 ** Description Get the channel FCR mode
1249 **
1250 ** Parameters: Local CID
1251 **
1252 ** Return value: Channel mode
1253 **
1254 *******************************************************************************/
L2CA_GetChnlFcrMode(UINT16 lcid)1255 UINT8 L2CA_GetChnlFcrMode (UINT16 lcid)
1256 {
1257 tL2C_CCB *p_ccb = l2cu_find_ccb_by_cid (NULL, lcid);
1258
1259 if (p_ccb)
1260 {
1261 L2CAP_TRACE_API1 ("L2CA_GetChnlFcrMode() returns mode %d", p_ccb->peer_cfg.fcr.mode);
1262 return (p_ccb->peer_cfg.fcr.mode);
1263 }
1264
1265 L2CAP_TRACE_API0 ("L2CA_GetChnlFcrMode() returns mode L2CAP_FCR_BASIC_MODE");
1266 return (L2CAP_FCR_BASIC_MODE);
1267 }
1268
1269 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1270 /*******************************************************************************
1271 **
1272 ** Function L2CA_RegisterFixedChannel
1273 **
1274 ** Description Register a fixed channel.
1275 **
1276 ** Parameters: Fixed Channel #
1277 ** Channel Callbacks and config
1278 **
1279 ** Return value: -
1280 **
1281 *******************************************************************************/
L2CA_RegisterFixedChannel(UINT16 fixed_cid,tL2CAP_FIXED_CHNL_REG * p_freg)1282 BOOLEAN L2CA_RegisterFixedChannel (UINT16 fixed_cid, tL2CAP_FIXED_CHNL_REG *p_freg)
1283 {
1284 if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) )
1285 {
1286 L2CAP_TRACE_ERROR1 ("L2CA_RegisterFixedChannel() Invalid CID: 0x%04x", fixed_cid);
1287
1288 return (FALSE);
1289 }
1290
1291 l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = *p_freg;
1292 return (TRUE);
1293 }
1294
1295 /*******************************************************************************
1296 **
1297 ** Function L2CA_ConnectFixedChnl
1298 **
1299 ** Description Connect an fixed signalling channel to a remote device.
1300 **
1301 ** Parameters: Fixed CID
1302 ** BD Address of remote
1303 **
1304 ** Return value: TRUE if connection started
1305 **
1306 *******************************************************************************/
L2CA_ConnectFixedChnl(UINT16 fixed_cid,BD_ADDR rem_bda)1307 BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
1308 {
1309 tL2C_LCB *p_lcb;
1310 #if BLE_INCLUDED == TRUE
1311 UINT16 reason;
1312 #endif
1313
1314 L2CAP_TRACE_API3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x", fixed_cid,
1315 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
1316
1317 /* Check CID is valid and registered */
1318 if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
1319 || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) )
1320 {
1321 L2CAP_TRACE_ERROR1 ("L2CA_ConnectFixedChnl() Invalid CID: 0x%04x", fixed_cid);
1322 return (FALSE);
1323 }
1324
1325 /* Fail if BT is not yet up */
1326 if (!BTM_IsDeviceUp())
1327 {
1328 L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - BTU not ready", fixed_cid);
1329 return (FALSE);
1330 }
1331
1332 /* If we already have a link to the remote, check if it supports that CID */
1333 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL)
1334 {
1335 if (!(p_lcb->peer_chnl_mask[0] & (1 << fixed_cid)))
1336 {
1337 L2CAP_TRACE_EVENT3 ("L2CA_ConnectFixedChnl() CID: 0x%04x BDA: %08x%04x not supported", fixed_cid,
1338 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
1339 return (FALSE);
1340 }
1341 /* Get a CCB and link the lcb to it */
1342 if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
1343 {
1344 L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - LCB but no CCB", fixed_cid);
1345 return (FALSE);
1346 }
1347 #if BLE_INCLUDED == TRUE
1348 reason = (p_lcb->is_ble_link) ? 1: 0;
1349 (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason);
1350 #else
1351 (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0);
1352 #endif
1353 return (TRUE);
1354 }
1355
1356 /* No link. Get an LCB and start link establishment */
1357 if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL)
1358 {
1359 L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no LCB", fixed_cid);
1360 return (FALSE);
1361 }
1362
1363 /* Get a CCB and link the lcb to it */
1364 if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
1365 {
1366 p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES;
1367 L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no CCB", fixed_cid);
1368 l2cu_release_lcb (p_lcb);
1369 return (FALSE);
1370 }
1371
1372 return (l2cu_create_conn(p_lcb));
1373 }
1374
1375 /*******************************************************************************
1376 **
1377 ** Function L2CA_SendFixedChnlData
1378 **
1379 ** Description Write data on a fixed channel.
1380 **
1381 ** Parameters: Fixed CID
1382 ** BD Address of remote
1383 ** Pointer to buffer of type BT_HDR
1384 **
1385 ** Return value L2CAP_DW_SUCCESS, if data accepted
1386 ** L2CAP_DW_FAILED, if error
1387 **
1388 *******************************************************************************/
L2CA_SendFixedChnlData(UINT16 fixed_cid,BD_ADDR rem_bda,BT_HDR * p_buf)1389 UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
1390 {
1391 tL2C_LCB *p_lcb;
1392
1393 L2CAP_TRACE_API3 ("L2CA_SendFixedChnlData() CID: 0x%04x BDA: %08x%04x", fixed_cid,
1394 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
1395
1396 /* Check CID is valid and registered */
1397 if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
1398 || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) )
1399 {
1400 L2CAP_TRACE_ERROR1 ("L2CA_SendFixedChnlData() Invalid CID: 0x%04x", fixed_cid);
1401 return (L2CAP_DW_FAILED);
1402 }
1403
1404 /* Fail if BT is not yet up */
1405 if (!BTM_IsDeviceUp())
1406 {
1407 L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData(0x%04x) - BTU not ready", fixed_cid);
1408 return (L2CAP_DW_FAILED);
1409 }
1410
1411 /* We need to have a link up */
1412 if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
1413 {
1414 L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid);
1415 return (L2CAP_DW_FAILED);
1416 }
1417
1418 if ((p_lcb->peer_chnl_mask[0] & (1 << fixed_cid)) == 0)
1419 {
1420 L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData() - peer does not support fixed chnl: 0x%04x", fixed_cid);
1421 return (L2CAP_DW_FAILED);
1422 }
1423
1424 p_buf->event = 0;
1425 p_buf->layer_specific = L2CAP_FLUSHABLE_CH_BASED;
1426
1427 if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])
1428 {
1429 if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
1430 {
1431 L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData() - no CCB for chnl: 0x%4x", fixed_cid);
1432 return (L2CAP_DW_FAILED);
1433 }
1434 }
1435
1436 l2c_enqueue_peer_data (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL], p_buf);
1437
1438 l2c_link_check_send_pkts (p_lcb, NULL, NULL);
1439
1440 /* If there is no dynamic CCB on the link, restart the idle timer each time something is sent */
1441 if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED && !p_lcb->ccb_queue.p_first_ccb)
1442 {
1443 l2cu_no_dynamic_ccbs (p_lcb);
1444 }
1445
1446 return (L2CAP_DW_SUCCESS);
1447 }
1448
1449 /*******************************************************************************
1450 **
1451 ** Function L2CA_RemoveFixedChnl
1452 **
1453 ** Description Remove a fixed channel to a remote device.
1454 **
1455 ** Parameters: Fixed CID
1456 ** BD Address of remote
1457 ** Idle timeout to use (or 0xFFFF if don't care)
1458 **
1459 ** Return value: TRUE if channel removed
1460 **
1461 *******************************************************************************/
L2CA_RemoveFixedChnl(UINT16 fixed_cid,BD_ADDR rem_bda)1462 BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
1463 {
1464 tL2C_LCB *p_lcb;
1465 tL2C_CCB *p_ccb;
1466
1467 /* Check CID is valid and registered */
1468 if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
1469 || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) )
1470 {
1471 L2CAP_TRACE_ERROR1 ("L2CA_RemoveFixedChnl() Invalid CID: 0x%04x", fixed_cid);
1472 return (FALSE);
1473 }
1474
1475 /* Is a fixed channel connected to the remote BDA ?*/
1476 p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
1477 if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) )
1478 {
1479 L2CAP_TRACE_WARNING3 ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid,
1480 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
1481 return (FALSE);
1482 }
1483
1484 L2CAP_TRACE_API3 ("L2CA_RemoveFixedChnl() CID: 0x%04x BDA: %08x%04x", fixed_cid,
1485 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
1486
1487 /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs exist */
1488 p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
1489
1490 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL;
1491 p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST;
1492
1493 #if BLE_INCLUDED == TRUE
1494 if (fixed_cid == L2CAP_ATT_CID && !p_lcb->ccb_queue.p_first_ccb)
1495 p_lcb->idle_timeout = 0;
1496 #endif
1497
1498 l2cu_release_ccb (p_ccb);
1499
1500 return (TRUE);
1501 }
1502
1503 /*******************************************************************************
1504 **
1505 ** Function L2CA_SetFixedChannelTout
1506 **
1507 ** Description Higher layers call this function to set the idle timeout for
1508 ** a fixed channel. The "idle timeout" is the amount of time that
1509 ** a connection can remain up with no L2CAP channels on it.
1510 ** A timeout of zero means that the connection will be torn
1511 ** down immediately when the last channel is removed.
1512 ** A timeout of 0xFFFF means no timeout. Values are in seconds.
1513 ** A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
1514 ** then the idle timeouts for all active l2cap links will be
1515 ** changed.
1516 **
1517 ** Returns TRUE if command succeeded, FALSE if failed
1518 **
1519 *******************************************************************************/
L2CA_SetFixedChannelTout(BD_ADDR rem_bda,UINT16 fixed_cid,UINT16 idle_tout)1520 BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle_tout)
1521 {
1522 tL2C_LCB *p_lcb;
1523
1524 /* Is a fixed channel connected to the remote BDA ?*/
1525 p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
1526 if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) )
1527 {
1528 L2CAP_TRACE_WARNING3 ("L2CA_SetFixedChannelTout() CID: 0x%04x BDA: %08x%04x not connected", fixed_cid,
1529 (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
1530 return (FALSE);
1531 }
1532
1533 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->fixed_chnl_idle_tout = idle_tout;
1534
1535 if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED && !p_lcb->ccb_queue.p_first_ccb)
1536 {
1537 /* If there are no dynamic CCBs, (re)start the idle timer in case we changed it */
1538 l2cu_no_dynamic_ccbs (p_lcb);
1539 }
1540
1541 return (TRUE);
1542 }
1543
1544 #endif /* #if (L2CAP_NUM_FIXED_CHNLS > 0) */
1545
1546 /*******************************************************************************
1547 **
1548 ** Function L2CA_GetCurrentConfig
1549 **
1550 ** Description This function returns configurations of L2CAP channel
1551 ** pp_our_cfg : pointer of our saved configuration options
1552 ** p_our_cfg_bits : valid config in bitmap
1553 ** pp_peer_cfg: pointer of peer's saved configuration options
1554 ** p_peer_cfg_bits : valid config in bitmap
1555 **
1556 ** Returns TRUE if successful
1557 **
1558 *******************************************************************************/
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)1559 BOOLEAN L2CA_GetCurrentConfig (UINT16 lcid,
1560 tL2CAP_CFG_INFO **pp_our_cfg, tL2CAP_CH_CFG_BITS *p_our_cfg_bits,
1561 tL2CAP_CFG_INFO **pp_peer_cfg, tL2CAP_CH_CFG_BITS *p_peer_cfg_bits)
1562 {
1563 tL2C_CCB *p_ccb;
1564
1565 L2CAP_TRACE_API1 ("L2CA_GetCurrentConfig() CID: 0x%04x", lcid);
1566
1567 p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
1568
1569 if (p_ccb)
1570 {
1571 *pp_our_cfg = &(p_ccb->our_cfg);
1572
1573 /* convert valid config items into bitmap */
1574 *p_our_cfg_bits = 0;
1575 if (p_ccb->our_cfg.mtu_present)
1576 *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
1577 if (p_ccb->our_cfg.qos_present)
1578 *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
1579 if (p_ccb->our_cfg.flush_to_present)
1580 *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
1581 if (p_ccb->our_cfg.fcr_present)
1582 *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCR;
1583 if (p_ccb->our_cfg.fcs_present)
1584 *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_FCS;
1585 if (p_ccb->our_cfg.ext_flow_spec_present)
1586 *p_our_cfg_bits |= L2CAP_CH_CFG_MASK_EXT_FLOW_SPEC;
1587
1588 *pp_peer_cfg = &(p_ccb->peer_cfg);
1589 *p_peer_cfg_bits = p_ccb->peer_cfg_bits;
1590
1591 return TRUE;
1592 }
1593 else
1594 {
1595 L2CAP_TRACE_ERROR1 ("No CCB for CID:0x%04x", lcid);
1596 return FALSE;
1597 }
1598 }
1599
1600 /*******************************************************************************
1601 **
1602 ** Function L2CA_RegForNoCPEvt
1603 **
1604 ** Description Register callback for Number of Completed Packets event.
1605 **
1606 ** Input Param p_cb - callback for Number of completed packets event
1607 ** p_bda - BT address of remote device
1608 **
1609 ** Returns TRUE if registered OK, else FALSE
1610 **
1611 *******************************************************************************/
L2CA_RegForNoCPEvt(tL2CA_NOCP_CB * p_cb,BD_ADDR p_bda)1612 BOOLEAN L2CA_RegForNoCPEvt(tL2CA_NOCP_CB *p_cb, BD_ADDR p_bda)
1613 {
1614 tL2C_LCB *p_lcb;
1615
1616 /* Find the link that is associated with this remote bdaddr */
1617 p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
1618
1619 /* If no link for this handle, nothing to do. */
1620 if (!p_lcb)
1621 return FALSE;
1622
1623 p_lcb->p_nocp_cb = p_cb;
1624
1625 return TRUE;
1626 }
1627
1628 /*******************************************************************************
1629 **
1630 ** Function L2CA_DataWrite
1631 **
1632 ** Description Higher layers call this function to write data.
1633 **
1634 ** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE
1635 ** L2CAP_DW_CONGESTED, if data accepted and the channel is congested
1636 ** L2CAP_DW_FAILED, if error
1637 **
1638 *******************************************************************************/
L2CA_DataWrite(UINT16 cid,BT_HDR * p_data)1639 UINT8 L2CA_DataWrite (UINT16 cid, BT_HDR *p_data)
1640 {
1641 L2CAP_TRACE_API2 ("L2CA_DataWrite() CID: 0x%04x Len: %d", cid, p_data->len);
1642 return l2c_data_write (cid, p_data, L2CAP_FLUSHABLE_CH_BASED);
1643 }
1644
1645 /*******************************************************************************
1646 **
1647 ** Function L2CA_SetChnlFlushability
1648 **
1649 ** Description Higher layers call this function to set a channels
1650 ** flushability flags
1651 **
1652 ** Returns TRUE if CID found, else FALSE
1653 **
1654 *******************************************************************************/
L2CA_SetChnlFlushability(UINT16 cid,BOOLEAN is_flushable)1655 BOOLEAN L2CA_SetChnlFlushability (UINT16 cid, BOOLEAN is_flushable)
1656 {
1657 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
1658
1659 tL2C_CCB *p_ccb;
1660
1661 /* Find the channel control block. We don't know the link it is on. */
1662 if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL)
1663 {
1664 L2CAP_TRACE_WARNING1 ("L2CAP - no CCB for L2CA_SetChnlFlushability, CID: %d", cid);
1665 return (FALSE);
1666 }
1667
1668 p_ccb->is_flushable = is_flushable;
1669
1670 L2CAP_TRACE_API2 ("L2CA_SetChnlFlushability() CID: 0x%04x is_flushable: %d", cid, is_flushable);
1671
1672 #endif
1673
1674 return (TRUE);
1675 }
1676
1677 /*******************************************************************************
1678 **
1679 ** Function L2CA_DataWriteEx
1680 **
1681 ** Description Higher layers call this function to write data with extended
1682 ** flags.
1683 ** flags : L2CAP_FLUSHABLE_CH_BASED
1684 ** L2CAP_FLUSHABLE_PKT
1685 ** L2CAP_NON_FLUSHABLE_PKT
1686 **
1687 ** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE
1688 ** L2CAP_DW_CONGESTED, if data accepted and the channel is congested
1689 ** L2CAP_DW_FAILED, if error
1690 **
1691 *******************************************************************************/
L2CA_DataWriteEx(UINT16 cid,BT_HDR * p_data,UINT16 flags)1692 UINT8 L2CA_DataWriteEx (UINT16 cid, BT_HDR *p_data, UINT16 flags)
1693 {
1694 L2CAP_TRACE_API3 ("L2CA_DataWriteEx() CID: 0x%04x Len: %d Flags:0x%04X",
1695 cid, p_data->len, flags);
1696 return l2c_data_write (cid, p_data, flags);
1697 }
1698
1699 /*******************************************************************************
1700 **
1701 ** Function L2CA_FlushChannel
1702 **
1703 ** Description This function flushes none, some or all buffers queued up
1704 ** for xmission for a particular CID. If called with
1705 ** L2CAP_FLUSH_CHANS_GET (0), it simply returns the number
1706 ** of buffers queued for that CID L2CAP_FLUSH_CHANS_ALL (0xffff)
1707 ** flushes all buffers. All other values specifies the maximum
1708 ** buffers to flush.
1709 **
1710 ** Returns Number of buffers left queued for that CID
1711 **
1712 *******************************************************************************/
L2CA_FlushChannel(UINT16 lcid,UINT16 num_to_flush)1713 UINT16 L2CA_FlushChannel (UINT16 lcid, UINT16 num_to_flush)
1714 {
1715 tL2C_CCB *p_ccb;
1716 tL2C_LCB *p_lcb;
1717 UINT16 num_left = 0,
1718 num_flushed1 = 0,
1719 num_flushed2 = 0;
1720 BT_HDR *p_buf1, *p_buf;
1721
1722 p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
1723
1724 if ( !p_ccb || ((p_lcb = p_ccb->p_lcb) == NULL) )
1725 {
1726 L2CAP_TRACE_WARNING1 ("L2CA_FlushChannel() abnormally returning 0 CID: 0x%04x", lcid);
1727 return (0);
1728 }
1729
1730 if (num_to_flush != L2CAP_FLUSH_CHANS_GET)
1731 {
1732 L2CAP_TRACE_API4 ("L2CA_FlushChannel (FLUSH) CID: 0x%04x NumToFlush: %d QC: %u pFirst: 0x%08x",
1733 lcid, num_to_flush, p_ccb->xmit_hold_q.count, p_ccb->xmit_hold_q.p_first);
1734 }
1735 else
1736 {
1737 L2CAP_TRACE_API1 ("L2CA_FlushChannel (QUERY) CID: 0x%04x", lcid);
1738 }
1739
1740 /* Cannot flush eRTM buffers once they have a sequence number */
1741 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE)
1742 {
1743 #if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE
1744 if (num_to_flush != L2CAP_FLUSH_CHANS_GET)
1745 {
1746 /* If the controller supports enhanced flush, flush the data queued at the controller */
1747 if ( (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ()))
1748 && (BTM_GetNumScoLinks() == 0) )
1749 {
1750 if ( l2cb.is_flush_active == FALSE )
1751 {
1752 l2cb.is_flush_active = TRUE;
1753
1754 /* The only packet type defined - 0 - Automatically-Flushable Only */
1755 btsnd_hcic_enhanced_flush (p_lcb->handle, 0);
1756 }
1757 }
1758 }
1759 #endif
1760
1761 p_buf = (BT_HDR *)p_lcb->link_xmit_data_q.p_first;
1762
1763 /* First flush the number we are asked to flush */
1764 while ((p_buf != NULL) && (num_to_flush != 0))
1765 {
1766 /* Do not flush other CIDs or partial segments */
1767 if ( (p_buf->layer_specific == 0) && (p_buf->event == lcid) )
1768 {
1769 p_buf1 = p_buf;
1770 p_buf = (BT_HDR *)GKI_getnext (p_buf);
1771 num_to_flush--;
1772 num_flushed1++;
1773
1774 GKI_remove_from_queue (&p_lcb->link_xmit_data_q, p_buf1);
1775 GKI_freebuf (p_buf1);
1776 }
1777 else
1778 p_buf = (BT_HDR *)GKI_getnext (p_buf);
1779 }
1780 }
1781
1782 /* If needed, flush buffers in the CCB xmit hold queue */
1783 while ( (num_to_flush != 0) && (p_ccb->xmit_hold_q.count != 0) )
1784 {
1785 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
1786 if (p_buf)
1787 GKI_freebuf (p_buf);
1788 num_to_flush--;
1789 num_flushed2++;
1790 }
1791
1792 /* If app needs to track all packets, call him */
1793 if ( (p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_TxComplete_Cb) && (num_flushed2) )
1794 (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, num_flushed2);
1795
1796 /* Now count how many are left */
1797 p_buf = (BT_HDR *)p_lcb->link_xmit_data_q.p_first;
1798
1799 while (p_buf != NULL)
1800 {
1801 if (p_buf->event == lcid)
1802 num_left++;
1803
1804 p_buf = (BT_HDR *)GKI_getnext (p_buf);
1805 }
1806
1807 /* Add in the number in the CCB xmit queue */
1808 num_left += p_ccb->xmit_hold_q.count;
1809
1810 /* Return the local number of buffers left for the CID */
1811 L2CAP_TRACE_DEBUG3 ("L2CA_FlushChannel() flushed: %u + %u, num_left: %u", num_flushed1, num_flushed2, num_left);
1812
1813 /* If we were congested, and now we are not, tell the app */
1814 l2cu_check_channel_congestion (p_ccb);
1815
1816 return (num_left);
1817 }
1818
1819