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 L2CAP utility functions
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 "hcimsgs.h"
32 #include "l2cdefs.h"
33 #include "l2c_int.h"
34 #include "hcidefs.h"
35 #include "btu.h"
36 #include "btm_api.h"
37 #include "btm_int.h"
38 #include "hcidefs.h"
39
40 /*******************************************************************************
41 **
42 ** Function l2cu_allocate_lcb
43 **
44 ** Description Look for an unused LCB
45 **
46 ** Returns LCB address or NULL if none found
47 **
48 *******************************************************************************/
l2cu_allocate_lcb(BD_ADDR p_bd_addr,BOOLEAN is_bonding)49 tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
50 {
51 int xx;
52 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
53
54 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
55 {
56 if (!p_lcb->in_use)
57 {
58 memset (p_lcb, 0, sizeof (tL2C_LCB));
59
60 memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
61
62 p_lcb->in_use = TRUE;
63 p_lcb->link_state = LST_DISCONNECTED;
64 p_lcb->handle = HCI_INVALID_HANDLE;
65 p_lcb->link_flush_tout = 0xFFFF;
66 p_lcb->timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
67 p_lcb->info_timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
68 p_lcb->idle_timeout = l2cb.idle_timeout;
69 p_lcb->id = 1; /* spec does not allow '0' */
70 p_lcb->is_bonding = is_bonding;
71
72 l2cb.num_links_active++;
73
74 l2c_link_adjust_allocation();
75 return (p_lcb);
76 }
77 }
78
79 /* If here, no free LCB found */
80 return (NULL);
81 }
82
83 /*******************************************************************************
84 **
85 ** Function l2cu_update_lcb_4_bonding
86 **
87 ** Description Mark the lcb for bonding. Used when bonding takes place on
88 ** an existing ACL connection. (Pre-Lisbon devices)
89 **
90 ** Returns Nothing
91 **
92 *******************************************************************************/
l2cu_update_lcb_4_bonding(BD_ADDR p_bd_addr,BOOLEAN is_bonding)93 void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
94 {
95 tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr);
96
97 if (p_lcb)
98 {
99 L2CAP_TRACE_DEBUG3 ("l2cu_update_lcb_4_bonding BDA: %08x%04x is_bonding: %d",
100 (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
101 (p_bd_addr[4]<<8)+p_bd_addr[5], is_bonding);
102 p_lcb->is_bonding = is_bonding;
103 }
104 }
105
106 /*******************************************************************************
107 **
108 ** Function l2cu_release_lcb
109 **
110 ** Description Release an LCB. All timers will be stopped, channels
111 ** dropped, buffers returned etc.
112 **
113 ** Returns void
114 **
115 *******************************************************************************/
l2cu_release_lcb(tL2C_LCB * p_lcb)116 void l2cu_release_lcb (tL2C_LCB *p_lcb)
117 {
118 tL2C_CCB *p_ccb;
119
120 p_lcb->in_use = FALSE;
121 p_lcb->is_bonding = FALSE;
122
123 /* Stop timers */
124 btu_stop_timer (&p_lcb->timer_entry);
125 btu_stop_timer (&p_lcb->info_timer_entry);
126
127 /* Release any unfinished L2CAP packet on this link */
128 if (p_lcb->p_hcit_rcv_acl)
129 {
130 GKI_freebuf(p_lcb->p_hcit_rcv_acl);
131 p_lcb->p_hcit_rcv_acl = NULL;
132 }
133
134 #if BTM_SCO_INCLUDED == TRUE
135 /* Release all SCO links */
136 btm_remove_sco_links(p_lcb->remote_bd_addr);
137 #endif
138
139 #if (BLE_INCLUDED == TRUE)
140 p_lcb->is_ble_link = FALSE;
141 l2cb.is_ble_connecting = FALSE;
142 #endif
143
144 #if (L2CAP_NUM_FIXED_CHNLS > 0)
145 {
146 int xx;
147
148 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
149 {
150 if (p_lcb->p_fixed_ccbs[xx])
151 {
152 l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
153 p_lcb->p_fixed_ccbs[xx] = NULL;
154 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
155 }
156 else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
157 && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
158 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
159 }
160 }
161 #endif
162
163 /* Ensure no CCBs left on this LCB */
164 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_lcb->ccb_queue.p_first_ccb)
165 {
166 l2cu_release_ccb (p_ccb);
167 }
168
169 /* Tell BTM Acl management the link was removed */
170 if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING))
171 btm_acl_removed (p_lcb->remote_bd_addr);
172
173 /* Release any held buffers */
174 while (p_lcb->link_xmit_data_q.p_first)
175 GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q));
176
177 #if (L2CAP_UCD_INCLUDED == TRUE)
178 /* clean up any security pending UCD */
179 l2c_ucd_delete_sec_pending_q(p_lcb);
180 #endif
181
182 /* Re-adjust flow control windows make sure it does not go negative */
183 if (l2cb.num_links_active >= 1)
184 l2cb.num_links_active--;
185
186 if (p_lcb->sent_not_acked > 0)
187 {
188 l2cb.controller_xmit_window += p_lcb->sent_not_acked;
189 if (l2cb.controller_xmit_window > l2cb.num_lm_acl_bufs)
190 {
191 l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
192 }
193 }
194
195 l2c_link_adjust_allocation();
196
197 /* Check for ping outstanding */
198 if (p_lcb->p_echo_rsp_cb)
199 {
200 tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb;
201
202 /* Zero out the callback in case app immediately calls us again */
203 p_lcb->p_echo_rsp_cb = NULL;
204
205 (*p_cb) (L2CAP_PING_RESULT_NO_LINK);
206 }
207 }
208
209
210 /*******************************************************************************
211 **
212 ** Function l2cu_find_lcb_by_bd_addr
213 **
214 ** Description Look through all active LCBs for a match based on the
215 ** remote BD address.
216 **
217 ** Returns pointer to matched LCB, or NULL if no match
218 **
219 *******************************************************************************/
l2cu_find_lcb_by_bd_addr(BD_ADDR p_bd_addr)220 tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr)
221 {
222 int xx;
223 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
224
225 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
226 {
227 if ((p_lcb->in_use) && (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
228 {
229 return (p_lcb);
230 }
231 }
232
233 /* If here, no match found */
234 return (NULL);
235 }
236
237 /*******************************************************************************
238 **
239 ** Function l2cu_get_conn_role
240 **
241 ** Description Determine the desired role (master or slave) of a link.
242 ** If already got a slave link, this one must be a master. If
243 ** already got at least 1 link where we are the master, make this
244 ** also a master.
245 **
246 ** Returns HCI_ROLE_MASTER or HCI_ROLE_SLAVE
247 **
248 *******************************************************************************/
l2cu_get_conn_role(tL2C_LCB * p_this_lcb)249 UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb)
250 {
251 return l2cb.desire_role;
252 }
253
254 /*******************************************************************************
255 **
256 ** Function l2cu_build_header
257 **
258 ** Description Builds the L2CAP command packet header
259 **
260 ** Returns Pointer to allocated packet or NULL if no resources
261 **
262 *******************************************************************************/
l2cu_build_header(tL2C_LCB * p_lcb,UINT16 len,UINT8 cmd,UINT8 id)263 BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id)
264 {
265 BT_HDR *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
266 UINT8 *p;
267
268 if (!p_buf)
269 {
270 L2CAP_TRACE_ERROR0 ("l2cu_build_header - no buffer");
271 return (NULL);
272 }
273
274 p_buf->offset = L2CAP_SEND_CMD_OFFSET;
275 p_buf->len = len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
276 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
277
278 /* Put in HCI header - handle + pkt boundary */
279 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
280 UINT16_TO_STREAM (p, p_lcb->handle | l2cb.non_flushable_pbf);
281 #else
282 UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
283 #endif
284
285 UINT16_TO_STREAM (p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD);
286 UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD);
287
288 #if (BLE_INCLUDED == TRUE)
289 if (p_lcb->is_ble_link)
290 {
291 UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID);
292 }
293 else
294 #endif
295 {
296 UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
297 }
298
299 /* Put in L2CAP command header */
300 UINT8_TO_STREAM (p, cmd);
301 UINT8_TO_STREAM (p, id);
302 UINT16_TO_STREAM (p, len);
303
304 return (p_buf);
305 }
306
307 /*******************************************************************************
308 **
309 ** Function l2cu_adj_id
310 **
311 ** Description Checks for valid ID based on specified mask
312 ** and adjusts the id if invalid.
313 **
314 ** Returns void
315 **
316 *******************************************************************************/
l2cu_adj_id(tL2C_LCB * p_lcb,UINT8 adj_mask)317 void l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask)
318 {
319 if ((adj_mask & L2CAP_ADJ_ZERO_ID) && !p_lcb->id)
320 {
321 p_lcb->id++;
322 }
323 }
324
325 /*******************************************************************************
326 **
327 ** Function l2cu_send_peer_cmd_reject
328 **
329 ** Description Build and send an L2CAP "command reject" message
330 ** to the peer.
331 **
332 ** Returns void
333 **
334 *******************************************************************************/
l2cu_send_peer_cmd_reject(tL2C_LCB * p_lcb,UINT16 reason,UINT8 rem_id,UINT16 p1,UINT16 p2)335 void l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id,
336 UINT16 p1, UINT16 p2)
337 {
338 UINT16 param_len;
339 BT_HDR *p_buf;
340 UINT8 *p;
341
342 /* Put in L2CAP packet header */
343 if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED)
344 param_len = 2;
345 else if (reason == L2CAP_CMD_REJ_INVALID_CID)
346 param_len = 4;
347 else
348 param_len = 0;
349
350 if ((p_buf = l2cu_build_header (p_lcb, (UINT16) (L2CAP_CMD_REJECT_LEN + param_len), L2CAP_CMD_REJECT, rem_id)) == NULL )
351 {
352 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer cmd_rej");
353 return;
354 }
355
356 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
357 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
358
359 UINT16_TO_STREAM (p, reason);
360
361 if (param_len >= 2)
362 UINT16_TO_STREAM (p, p1);
363
364 if (param_len >= 4)
365 UINT16_TO_STREAM (p, p2);
366
367 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
368 }
369
370
371 /*******************************************************************************
372 **
373 ** Function l2cu_send_peer_connect_req
374 **
375 ** Description Build and send an L2CAP "connection request" message
376 ** to the peer.
377 **
378 ** Returns void
379 **
380 *******************************************************************************/
l2cu_send_peer_connect_req(tL2C_CCB * p_ccb)381 void l2cu_send_peer_connect_req (tL2C_CCB *p_ccb)
382 {
383 BT_HDR *p_buf;
384 UINT8 *p;
385
386 /* Create an identifier for this packet */
387 p_ccb->p_lcb->id++;
388 l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
389
390 p_ccb->local_id = p_ccb->p_lcb->id;
391
392 if ((p_buf = l2cu_build_header (p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ,
393 p_ccb->local_id)) == NULL)
394 {
395 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
396 return;
397 }
398
399 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
400 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
401
402 UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm);
403 UINT16_TO_STREAM (p, p_ccb->local_cid);
404
405 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
406 }
407
408
409 /*******************************************************************************
410 **
411 ** Function l2cu_send_peer_connect_rsp
412 **
413 ** Description Build and send an L2CAP "connection response" message
414 ** to the peer.
415 **
416 ** Returns void
417 **
418 *******************************************************************************/
l2cu_send_peer_connect_rsp(tL2C_CCB * p_ccb,UINT16 result,UINT16 status)419 void l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status)
420 {
421 BT_HDR *p_buf;
422 UINT8 *p;
423
424 if (result == L2CAP_CONN_PENDING)
425 {
426 /* if we already sent pending response */
427 if (p_ccb->flags & CCB_FLAG_SENT_PENDING)
428 return;
429 else
430 p_ccb->flags |= CCB_FLAG_SENT_PENDING;
431 }
432
433 if ((p_buf=l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, p_ccb->remote_id)) == NULL)
434 {
435 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_rsp");
436 return;
437 }
438
439 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
440 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
441
442 UINT16_TO_STREAM (p, p_ccb->local_cid);
443 UINT16_TO_STREAM (p, p_ccb->remote_cid);
444 UINT16_TO_STREAM (p, result);
445 UINT16_TO_STREAM (p, status);
446
447 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
448 }
449
450
451 /*******************************************************************************
452 **
453 ** Function l2cu_reject_connection
454 **
455 ** Description Build and send an L2CAP "connection response neg" message
456 ** to the peer. This function is called when there is no peer
457 ** CCB (non-existant PSM or no resources).
458 **
459 ** Returns void
460 **
461 *******************************************************************************/
l2cu_reject_connection(tL2C_LCB * p_lcb,UINT16 remote_cid,UINT8 rem_id,UINT16 result)462 void l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, UINT16 result)
463 {
464 BT_HDR *p_buf;
465 UINT8 *p;
466
467 if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL )
468 {
469 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
470 return;
471 }
472
473 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
474
475 UINT16_TO_STREAM (p, 0); /* Local CID of 0 */
476 UINT16_TO_STREAM (p, remote_cid);
477 UINT16_TO_STREAM (p, result);
478 UINT16_TO_STREAM (p, 0); /* Status of 0 */
479
480 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
481 }
482
483 /*******************************************************************************
484 **
485 ** Function l2cu_send_peer_config_req
486 **
487 ** Description Build and send an L2CAP "configuration request" message
488 ** to the peer.
489 **
490 ** Returns void
491 **
492 *******************************************************************************/
l2cu_send_peer_config_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)493 void l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
494 {
495 BT_HDR *p_buf;
496 UINT16 cfg_len=0;
497 UINT8 *p;
498
499 /* Create an identifier for this packet */
500 p_ccb->p_lcb->id++;
501 l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
502
503 p_ccb->local_id = p_ccb->p_lcb->id;
504
505 if (p_cfg->mtu_present)
506 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
507 if (p_cfg->flush_to_present)
508 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
509 if (p_cfg->qos_present)
510 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
511 if (p_cfg->fcr_present)
512 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
513 if (p_cfg->fcs_present)
514 cfg_len += L2CAP_CFG_FCS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
515 if (p_cfg->ext_flow_spec_present)
516 cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
517
518 if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16) (L2CAP_CONFIG_REQ_LEN + cfg_len),
519 L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL )
520 {
521 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
522 return;
523 }
524
525 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
526 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
527
528 UINT16_TO_STREAM (p, p_ccb->remote_cid);
529 UINT16_TO_STREAM (p, p_cfg->flags); /* Flags (continuation) */
530
531 /* Now, put the options */
532 if (p_cfg->mtu_present)
533 {
534 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_MTU);
535 UINT8_TO_STREAM (p, L2CAP_CFG_MTU_OPTION_LEN);
536 UINT16_TO_STREAM (p, p_cfg->mtu);
537 }
538 if (p_cfg->flush_to_present)
539 {
540 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
541 UINT8_TO_STREAM (p, L2CAP_CFG_FLUSH_OPTION_LEN);
542 UINT16_TO_STREAM (p, p_cfg->flush_to);
543 }
544 if (p_cfg->qos_present)
545 {
546 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_QOS);
547 UINT8_TO_STREAM (p, L2CAP_CFG_QOS_OPTION_LEN);
548 UINT8_TO_STREAM (p, p_cfg->qos.qos_flags);
549 UINT8_TO_STREAM (p, p_cfg->qos.service_type);
550 UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
551 UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
552 UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
553 UINT32_TO_STREAM (p, p_cfg->qos.latency);
554 UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
555 }
556 if (p_cfg->fcr_present)
557 {
558 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCR);
559 UINT8_TO_STREAM (p, L2CAP_CFG_FCR_OPTION_LEN);
560 UINT8_TO_STREAM (p, p_cfg->fcr.mode);
561 UINT8_TO_STREAM (p, p_cfg->fcr.tx_win_sz);
562 UINT8_TO_STREAM (p, p_cfg->fcr.max_transmit);
563 UINT16_TO_STREAM (p, p_cfg->fcr.rtrans_tout);
564 UINT16_TO_STREAM (p, p_cfg->fcr.mon_tout);
565 UINT16_TO_STREAM (p, p_cfg->fcr.mps);
566 }
567
568 if (p_cfg->fcs_present)
569 {
570 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCS);
571 UINT8_TO_STREAM (p, L2CAP_CFG_FCS_OPTION_LEN);
572 UINT8_TO_STREAM (p, p_cfg->fcs);
573 }
574
575 if (p_cfg->ext_flow_spec_present)
576 {
577 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_EXT_FLOW);
578 UINT8_TO_STREAM (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
579 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.id);
580 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.stype);
581 UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
582 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
583 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
584 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
585 }
586
587 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
588 }
589
590 /*******************************************************************************
591 **
592 ** Function l2cu_send_peer_config_rsp
593 **
594 ** Description Build and send an L2CAP "configuration response" message
595 ** to the peer.
596 **
597 ** Returns void
598 **
599 *******************************************************************************/
l2cu_send_peer_config_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)600 void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
601 {
602 BT_HDR *p_buf;
603 UINT16 cfg_len = 0;
604 UINT8 *p;
605
606 /* Create an identifier for this packet */
607 if (p_cfg->mtu_present)
608 cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
609 if (p_cfg->flush_to_present)
610 cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
611 if (p_cfg->qos_present)
612 cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
613 if (p_cfg->fcr_present)
614 cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
615 if (p_cfg->ext_flow_spec_present)
616 cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
617
618 if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16)(L2CAP_CONFIG_RSP_LEN + cfg_len),
619 L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL )
620 {
621 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
622 return;
623 }
624
625 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
626
627 UINT16_TO_STREAM (p, p_ccb->remote_cid);
628 UINT16_TO_STREAM (p, p_cfg->flags); /* Flags (continuation) Must match request */
629 UINT16_TO_STREAM (p, p_cfg->result);
630
631 /* Now, put the options */
632 if (p_cfg->mtu_present)
633 {
634 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_MTU);
635 UINT8_TO_STREAM (p, L2CAP_CFG_MTU_OPTION_LEN);
636 UINT16_TO_STREAM (p, p_cfg->mtu);
637 }
638 if (p_cfg->flush_to_present)
639 {
640 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
641 UINT8_TO_STREAM (p, L2CAP_CFG_FLUSH_OPTION_LEN);
642 UINT16_TO_STREAM (p, p_cfg->flush_to);
643 }
644 if (p_cfg->qos_present)
645 {
646 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_QOS);
647 UINT8_TO_STREAM (p, L2CAP_CFG_QOS_OPTION_LEN);
648 UINT8_TO_STREAM (p, p_cfg->qos.qos_flags);
649 UINT8_TO_STREAM (p, p_cfg->qos.service_type);
650 UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
651 UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
652 UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
653 UINT32_TO_STREAM (p, p_cfg->qos.latency);
654 UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
655 }
656 if (p_cfg->fcr_present)
657 {
658 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_FCR);
659 UINT8_TO_STREAM (p, L2CAP_CFG_FCR_OPTION_LEN);
660 UINT8_TO_STREAM (p, p_cfg->fcr.mode);
661 UINT8_TO_STREAM (p, p_cfg->fcr.tx_win_sz);
662 UINT8_TO_STREAM (p, p_cfg->fcr.max_transmit);
663 UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.rtrans_tout);
664 UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.mon_tout);
665 UINT16_TO_STREAM (p, p_cfg->fcr.mps);
666 }
667
668 if (p_cfg->ext_flow_spec_present)
669 {
670 UINT8_TO_STREAM (p, L2CAP_CFG_TYPE_EXT_FLOW);
671 UINT8_TO_STREAM (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
672 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.id);
673 UINT8_TO_STREAM (p, p_cfg->ext_flow_spec.stype);
674 UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
675 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
676 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
677 UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
678 }
679
680 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
681 }
682
683 /*******************************************************************************
684 **
685 ** Function l2cu_send_peer_config_rej
686 **
687 ** Description Build and send an L2CAP "configuration reject" message
688 ** to the peer.
689 **
690 ** Returns void
691 **
692 *******************************************************************************/
l2cu_send_peer_config_rej(tL2C_CCB * p_ccb,UINT8 * p_data,UINT16 data_len,UINT16 rej_len)693 void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len)
694 {
695 BT_HDR *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
696 UINT16 len, cfg_len;
697 UINT8 *p, *p_hci_len, *p_data_end;
698 UINT8 cfg_code;
699
700 if (!p_buf)
701 {
702 L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for cfg_rej");
703 return;
704 }
705
706 p_buf->offset = L2CAP_SEND_CMD_OFFSET;
707 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
708
709 /* Put in HCI header - handle + pkt boundary */
710 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
711 if (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ()))
712 {
713 UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
714 }
715 else
716 #endif
717 {
718 UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
719 }
720
721 /* Remember the HCI header length position, and save space for it */
722 p_hci_len = p;
723 p += 2;
724
725 /* Put in L2CAP packet header */
726 UINT16_TO_STREAM (p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
727 UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
728
729 /* Put in L2CAP command header */
730 UINT8_TO_STREAM (p, L2CAP_CMD_CONFIG_RSP);
731 UINT8_TO_STREAM (p, p_ccb->remote_id);
732
733 UINT16_TO_STREAM (p, L2CAP_CONFIG_RSP_LEN + rej_len);
734
735 UINT16_TO_STREAM (p, p_ccb->remote_cid);
736 UINT16_TO_STREAM (p, 0); /* Flags = 0 (no continuation) */
737 UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS);
738
739 /* Now, put the rejected options */
740 p_data_end = p_data + data_len;
741 while (p_data < p_data_end)
742 {
743 cfg_code = *p_data;
744 cfg_len = *(p_data + 1);
745
746 switch (cfg_code & 0x7F)
747 {
748 /* skip known options */
749 case L2CAP_CFG_TYPE_MTU:
750 case L2CAP_CFG_TYPE_FLUSH_TOUT:
751 case L2CAP_CFG_TYPE_QOS:
752 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
753 break;
754
755 /* unknown options; copy into rsp if not hints */
756 default:
757 /* sanity check option length */
758 if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len)
759 {
760 if ((cfg_code & 0x80) == 0)
761 {
762 memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
763 p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
764 }
765 p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
766 }
767 /* bad length; force loop exit */
768 else
769 {
770 p_data = p_data_end;
771 }
772 break;
773 }
774 }
775
776 len = (UINT16) (p - p_hci_len - 2);
777 UINT16_TO_STREAM (p_hci_len, len);
778
779 p_buf->len = len + 4;
780
781 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
782 }
783
784 /*******************************************************************************
785 **
786 ** Function l2cu_send_peer_disc_req
787 **
788 ** Description Build and send an L2CAP "disconnect request" message
789 ** to the peer.
790 **
791 ** Returns void
792 **
793 *******************************************************************************/
l2cu_send_peer_disc_req(tL2C_CCB * p_ccb)794 void l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
795 {
796 BT_HDR *p_buf, *p_buf2;
797 UINT8 *p;
798
799 /* Create an identifier for this packet */
800 p_ccb->p_lcb->id++;
801 l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
802
803 p_ccb->local_id = p_ccb->p_lcb->id;
804
805 if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_ccb->local_id)) == NULL)
806 {
807 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for disc_req");
808 return;
809 }
810
811 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
812
813 UINT16_TO_STREAM (p, p_ccb->remote_cid);
814 UINT16_TO_STREAM (p, p_ccb->local_cid);
815
816 /* Move all queued data packets to the LCB. In FCR mode, assume the higher
817 layer checks that all buffers are sent before disconnecting.
818 */
819 if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)
820 {
821 while (p_ccb->xmit_hold_q.p_first)
822 {
823 p_buf2 = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
824 l2cu_set_acl_hci_header (p_buf2, p_ccb);
825 l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2);
826 }
827 }
828
829 l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
830 }
831
832
833 /*******************************************************************************
834 **
835 ** Function l2cu_send_peer_disc_rsp
836 **
837 ** Description Build and send an L2CAP "disconnect response" message
838 ** to the peer.
839 **
840 ** This function is passed the parameters for the disconnect
841 ** response instead of the CCB address, as it may be called
842 ** to send a disconnect response when there is no CCB.
843 **
844 ** Returns void
845 **
846 *******************************************************************************/
l2cu_send_peer_disc_rsp(tL2C_LCB * p_lcb,UINT8 remote_id,UINT16 local_cid,UINT16 remote_cid)847 void l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid,
848 UINT16 remote_cid)
849 {
850 BT_HDR *p_buf;
851 UINT8 *p;
852
853 if ((p_buf=l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id)) == NULL)
854 {
855 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for disc_rsp");
856 return;
857 }
858
859 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
860
861 UINT16_TO_STREAM (p, local_cid);
862 UINT16_TO_STREAM (p, remote_cid);
863
864 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
865 }
866
867
868 /*******************************************************************************
869 **
870 ** Function l2cu_send_peer_echo_req
871 **
872 ** Description Build and send an L2CAP "echo request" message
873 ** to the peer. Note that we do not currently allow
874 ** data in the echo request.
875 **
876 ** Returns void
877 **
878 *******************************************************************************/
l2cu_send_peer_echo_req(tL2C_LCB * p_lcb,UINT8 * p_data,UINT16 data_len)879 void l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len)
880 {
881 BT_HDR *p_buf;
882 UINT8 *p;
883
884 p_lcb->id++;
885 l2cu_adj_id(p_lcb, L2CAP_ADJ_ZERO_ID); /* check for wrap to '0' */
886
887 if ((p_buf = l2cu_build_header(p_lcb, (UINT16) (L2CAP_ECHO_REQ_LEN + data_len), L2CAP_CMD_ECHO_REQ, p_lcb->id)) == NULL)
888 {
889 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for echo_req");
890 return;
891 }
892
893 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
894
895 if (data_len)
896 {
897 ARRAY_TO_STREAM (p, p_data, data_len);
898 }
899
900 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
901 }
902
903
904 /*******************************************************************************
905 **
906 ** Function l2cu_send_peer_echo_rsp
907 **
908 ** Description Build and send an L2CAP "echo response" message
909 ** to the peer.
910 **
911 ** Returns void
912 **
913 *******************************************************************************/
l2cu_send_peer_echo_rsp(tL2C_LCB * p_lcb,UINT8 id,UINT8 * p_data,UINT16 data_len)914 void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len)
915 {
916 BT_HDR *p_buf;
917 UINT8 *p;
918 UINT16 maxlen;
919
920 /* Don't return data if it does not fit in ACL and L2CAP MTU */
921 maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ?
922 btu_cb.hcit_acl_data_size : (UINT16)GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID);
923 maxlen -= (UINT16)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
924 L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN);
925
926 if (data_len > maxlen)
927 data_len = 0;
928
929 if ((p_buf = l2cu_build_header (p_lcb, (UINT16)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP, id)) == NULL)
930 {
931 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for echo_rsp");
932 return;
933 }
934
935 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
936 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
937
938 if (data_len)
939 {
940 ARRAY_TO_STREAM (p, p_data, data_len);
941 }
942
943 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
944 }
945
946 /*******************************************************************************
947 **
948 ** Function l2cu_send_peer_info_req
949 **
950 ** Description Build and send an L2CAP "info request" message
951 ** to the peer.
952 ** Returns void
953 **
954 *******************************************************************************/
l2cu_send_peer_info_req(tL2C_LCB * p_lcb,UINT16 info_type)955 void l2cu_send_peer_info_req (tL2C_LCB *p_lcb, UINT16 info_type)
956 {
957 BT_HDR *p_buf;
958 UINT8 *p;
959
960 /* check for wrap and/or BRCM ID */
961 p_lcb->id++;
962 l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
963
964 if ((p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->id)) == NULL)
965 {
966 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for info_req");
967 return;
968 }
969
970 L2CAP_TRACE_EVENT1 ("l2cu_send_peer_info_req: type 0x%04x", info_type);
971
972 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
973 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
974
975 UINT16_TO_STREAM (p, info_type);
976
977 p_lcb->w4_info_rsp = TRUE;
978 btu_start_timer (&p_lcb->info_timer_entry, BTU_TTYPE_L2CAP_INFO, L2CAP_WAIT_INFO_RSP_TOUT);
979
980 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
981 }
982
983
984 /*******************************************************************************
985 **
986 ** Function l2cu_send_peer_info_rsp
987 **
988 ** Description Build and send an L2CAP "info response" message
989 ** to the peer.
990 **
991 ** Returns void
992 **
993 *******************************************************************************/
l2cu_send_peer_info_rsp(tL2C_LCB * p_lcb,UINT8 remote_id,UINT16 info_type)994 void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type)
995 {
996 BT_HDR *p_buf;
997 UINT8 *p;
998 UINT16 len = L2CAP_INFO_RSP_LEN;
999
1000 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1001 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1002 && (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1003 L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
1004 L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
1005 L2CAP_EXTFEA_UCD_RECEPTION )) )
1006 #else
1007 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1008 && (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
1009 L2CAP_EXTFEA_NO_CRC |L2CAP_EXTFEA_FIXED_CHNLS |
1010 L2CAP_EXTFEA_UCD_RECEPTION )) )
1011 #endif
1012 {
1013 len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE;
1014 }
1015 else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
1016 {
1017 len += L2CAP_FIXED_CHNL_ARRAY_SIZE;
1018 }
1019 else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
1020 {
1021 len += L2CAP_CONNLESS_MTU_INFO_SIZE;
1022 }
1023
1024 if ((p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id)) == NULL)
1025 {
1026 L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for info_rsp");
1027 return;
1028 }
1029
1030 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
1031 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
1032
1033 UINT16_TO_STREAM (p, info_type);
1034
1035 #if (L2CAP_CONFORMANCE_TESTING == TRUE)
1036 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1037 && (l2cb.test_info_resp & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
1038 | L2CAP_EXTFEA_UCD_RECEPTION )) )
1039 #else
1040 if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
1041 && (L2CAP_EXTFEA_SUPPORTED_MASK & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
1042 | L2CAP_EXTFEA_UCD_RECEPTION )) )
1043 #endif
1044 {
1045 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1046 #if (BLE_INCLUDED == TRUE)
1047 if (p_lcb->is_ble_link)
1048 {
1049 /* optional data are not added for now */
1050 UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK);
1051 }
1052 else
1053 #endif
1054 {
1055 #if L2CAP_CONFORMANCE_TESTING == TRUE
1056 UINT32_TO_STREAM (p, l2cb.test_info_resp);
1057 #else
1058 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1059 UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS);
1060 #else
1061 UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK);
1062 #endif
1063 #endif
1064 }
1065 }
1066 else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
1067 {
1068 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1069 memset (p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE);
1070
1071 p[0] = L2CAP_FIXED_CHNL_SIG_BIT;
1072
1073 if ( L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION )
1074 p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT;
1075
1076 #if (L2CAP_NUM_FIXED_CHNLS > 0)
1077 {
1078 int xx;
1079
1080 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
1081 if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
1082 p[0] |= 1 << (xx + L2CAP_FIRST_FIXED_CHNL);
1083 }
1084 #endif
1085 }
1086 else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
1087 {
1088 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
1089 UINT16_TO_STREAM (p, L2CAP_UCD_MTU);
1090 }
1091 else
1092 {
1093 UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED); /* 'not supported' */
1094 }
1095
1096 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
1097 }
1098
1099 /******************************************************************************
1100 **
1101 ** Function l2cu_enqueue_ccb
1102 **
1103 ** Description queue CCB by priority. The first CCB is highest priority and
1104 ** is served at first. The CCB is queued to an LLCB or an LCB.
1105 **
1106 ** Returns None
1107 **
1108 *******************************************************************************/
l2cu_enqueue_ccb(tL2C_CCB * p_ccb)1109 void l2cu_enqueue_ccb (tL2C_CCB *p_ccb)
1110 {
1111 tL2C_CCB *p_ccb1;
1112 tL2C_CCB_Q *p_q = NULL;
1113
1114 /* Find out which queue the channel is on
1115 */
1116 if (p_ccb->p_lcb != NULL)
1117 p_q = &p_ccb->p_lcb->ccb_queue;
1118
1119 if ( (!p_ccb->in_use) || (p_q == NULL) )
1120 {
1121 L2CAP_TRACE_ERROR3 ("l2cu_enqueue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x",
1122 p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb);
1123 return;
1124 }
1125
1126 L2CAP_TRACE_DEBUG2 ("l2cu_enqueue_ccb CID: 0x%04x priority: %d",
1127 p_ccb->local_cid, p_ccb->ccb_priority);
1128
1129 /* If the queue is empty, we go at the front */
1130 if (!p_q->p_first_ccb)
1131 {
1132 p_q->p_first_ccb = p_q->p_last_ccb = p_ccb;
1133 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1134 }
1135 else
1136 {
1137 p_ccb1 = p_q->p_first_ccb;
1138
1139 while (p_ccb1 != NULL)
1140 {
1141 /* Insert new ccb at the end of the same priority. Lower number, higher priority */
1142 if (p_ccb->ccb_priority < p_ccb1->ccb_priority)
1143 {
1144 /* Are we at the head of the queue ? */
1145 if (p_ccb1 == p_q->p_first_ccb)
1146 p_q->p_first_ccb = p_ccb;
1147 else
1148 p_ccb1->p_prev_ccb->p_next_ccb = p_ccb;
1149
1150 p_ccb->p_next_ccb = p_ccb1;
1151 p_ccb->p_prev_ccb = p_ccb1->p_prev_ccb;
1152 p_ccb1->p_prev_ccb = p_ccb;
1153 break;
1154 }
1155
1156 p_ccb1 = p_ccb1->p_next_ccb;
1157 }
1158
1159 /* If we are lower then anyone in the list, we go at the end */
1160 if (!p_ccb1)
1161 {
1162 /* add new ccb at the end of the list */
1163 p_q->p_last_ccb->p_next_ccb = p_ccb;
1164
1165 p_ccb->p_next_ccb = NULL;
1166 p_ccb->p_prev_ccb = p_q->p_last_ccb;
1167 p_q->p_last_ccb = p_ccb;
1168 }
1169 }
1170
1171 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1172 /* Adding CCB into round robin service table of its LCB */
1173 if (p_ccb->p_lcb != NULL)
1174 {
1175 /* if this is the first channel in this priority group */
1176 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
1177 {
1178 /* Set the first channel to this CCB */
1179 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1180 /* Set the next serving channel in this group to this CCB */
1181 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1182 /* Initialize quota of this priority group based on its priority */
1183 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1184 }
1185 /* increase number of channels in this group */
1186 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++;
1187 }
1188 #endif
1189
1190 }
1191
1192 /******************************************************************************
1193 **
1194 ** Function l2cu_dequeue_ccb
1195 **
1196 ** Description dequeue CCB from a queue
1197 **
1198 ** Returns -
1199 **
1200 *******************************************************************************/
l2cu_dequeue_ccb(tL2C_CCB * p_ccb)1201 void l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
1202 {
1203 tL2C_CCB_Q *p_q = NULL;
1204
1205 L2CAP_TRACE_DEBUG1 ("l2cu_dequeue_ccb CID: 0x%04x", p_ccb->local_cid);
1206
1207 /* Find out which queue the channel is on
1208 */
1209 if (p_ccb->p_lcb != NULL)
1210 p_q = &p_ccb->p_lcb->ccb_queue;
1211
1212 if ( (!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL) )
1213 {
1214 L2CAP_TRACE_ERROR5 ("l2cu_dequeue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x p_q: 0x%08x p_q->p_first_ccb: 0x%08x",
1215 p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q, p_q ? p_q->p_first_ccb : 0);
1216 return;
1217 }
1218
1219 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1220 /* Removing CCB from round robin service table of its LCB */
1221 if (p_ccb->p_lcb != NULL)
1222 {
1223 /* decrease number of channels in this priority group */
1224 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--;
1225
1226 /* if it was the last channel in the priority group */
1227 if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
1228 {
1229 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1230 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1231 }
1232 else
1233 {
1234 /* if it is the first channel of this group */
1235 if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb )
1236 {
1237 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb->p_next_ccb;
1238 }
1239 /* if it is the next serving channel of this group */
1240 if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb )
1241 {
1242 /* simply, start serving from the first channel */
1243 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb
1244 = p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb;
1245 }
1246 }
1247 }
1248 #endif
1249
1250 if (p_ccb == p_q->p_first_ccb)
1251 {
1252 /* We are removing the first in a queue */
1253 p_q->p_first_ccb = p_ccb->p_next_ccb;
1254
1255 if (p_q->p_first_ccb)
1256 p_q->p_first_ccb->p_prev_ccb = NULL;
1257 else
1258 p_q->p_last_ccb = NULL;
1259 }
1260 else if (p_ccb == p_q->p_last_ccb)
1261 {
1262 /* We are removing the last in a queue */
1263 p_q->p_last_ccb = p_ccb->p_prev_ccb;
1264 p_q->p_last_ccb->p_next_ccb = NULL;
1265 }
1266 else
1267 {
1268 /* In the middle of a chain. */
1269 p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb;
1270 p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb;
1271 }
1272
1273 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1274 }
1275
1276 /******************************************************************************
1277 **
1278 ** Function l2cu_change_pri_ccb
1279 **
1280 ** Description
1281 **
1282 ** Returns -
1283 **
1284 *******************************************************************************/
l2cu_change_pri_ccb(tL2C_CCB * p_ccb,tL2CAP_CHNL_PRIORITY priority)1285 void l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
1286 {
1287 if (p_ccb->ccb_priority != priority)
1288 {
1289 /* If CCB is not the only guy on the queue */
1290 if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) )
1291 {
1292 L2CAP_TRACE_DEBUG0 ("Update CCB list in logical link");
1293
1294 /* Remove CCB from queue and re-queue it at new priority */
1295 l2cu_dequeue_ccb (p_ccb);
1296
1297 p_ccb->ccb_priority = priority;
1298 l2cu_enqueue_ccb (p_ccb);
1299 }
1300 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
1301 else
1302 {
1303 /* If CCB is the only guy on the queue, no need to re-enqueue */
1304 /* update only round robin service data */
1305 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0;
1306 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
1307 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
1308
1309 p_ccb->ccb_priority = priority;
1310
1311 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
1312 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
1313 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
1314 p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1;
1315 }
1316 #endif
1317 }
1318 }
1319
1320 /*******************************************************************************
1321 **
1322 ** Function l2cu_allocate_ccb
1323 **
1324 ** Description This function allocates a Channel Control Block and
1325 ** attaches it to a link control block. The local CID
1326 ** is also assigned.
1327 **
1328 ** Returns pointer to CCB, or NULL if none
1329 **
1330 *******************************************************************************/
l2cu_allocate_ccb(tL2C_LCB * p_lcb,UINT16 cid)1331 tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
1332 {
1333 tL2C_CCB *p_ccb;
1334 tL2C_CCB *p_prev;
1335
1336 L2CAP_TRACE_DEBUG1 ("l2cu_allocate_ccb: cid 0x%04x", cid);
1337
1338 if (!l2cb.p_free_ccb_first)
1339 return (NULL);
1340
1341 /* If a CID was passed in, use that, else take the first free one */
1342 if (cid == 0)
1343 {
1344 p_ccb = l2cb.p_free_ccb_first;
1345 l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1346 }
1347 else
1348 {
1349 p_prev = NULL;
1350
1351 p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID];
1352
1353 if (p_ccb == l2cb.p_free_ccb_first)
1354 l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
1355 else
1356 {
1357 for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL; p_prev = p_prev->p_next_ccb)
1358 {
1359 if (p_prev->p_next_ccb == p_ccb)
1360 {
1361 p_prev->p_next_ccb = p_ccb->p_next_ccb;
1362
1363 if (p_ccb == l2cb.p_free_ccb_last)
1364 l2cb.p_free_ccb_last = p_prev;
1365
1366 break;
1367 }
1368 }
1369 if (p_prev == NULL)
1370 {
1371 L2CAP_TRACE_ERROR1 ("l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free list", cid);
1372 return NULL;
1373 }
1374 }
1375 }
1376
1377 p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
1378
1379 p_ccb->in_use = TRUE;
1380
1381 /* Get a CID for the connection */
1382 p_ccb->local_cid = L2CAP_BASE_APPL_CID + (UINT16)(p_ccb - l2cb.ccb_pool);
1383
1384 p_ccb->p_lcb = p_lcb;
1385 p_ccb->p_rcb = NULL;
1386
1387 /* Set priority then insert ccb into LCB queue (if we have an LCB) */
1388 p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW;
1389
1390 if (p_lcb)
1391 l2cu_enqueue_ccb (p_ccb);
1392
1393 /* clear what peer wants to configure */
1394 p_ccb->peer_cfg_bits = 0;
1395
1396 /* Put in default values for configuration */
1397 memset (&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1398 memset (&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO));
1399
1400 /* Put in default values for local/peer configurations */
1401 p_ccb->our_cfg.flush_to = p_ccb->peer_cfg.flush_to = L2CAP_DEFAULT_FLUSH_TO;
1402 p_ccb->our_cfg.mtu = p_ccb->peer_cfg.mtu = L2CAP_DEFAULT_MTU;
1403 p_ccb->our_cfg.qos.service_type = p_ccb->peer_cfg.qos.service_type = L2CAP_DEFAULT_SERV_TYPE;
1404 p_ccb->our_cfg.qos.token_rate = p_ccb->peer_cfg.qos.token_rate = L2CAP_DEFAULT_TOKEN_RATE;
1405 p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size = L2CAP_DEFAULT_BUCKET_SIZE;
1406 p_ccb->our_cfg.qos.peak_bandwidth = p_ccb->peer_cfg.qos.peak_bandwidth = L2CAP_DEFAULT_PEAK_BANDWIDTH;
1407 p_ccb->our_cfg.qos.latency = p_ccb->peer_cfg.qos.latency = L2CAP_DEFAULT_LATENCY;
1408 p_ccb->our_cfg.qos.delay_variation = p_ccb->peer_cfg.qos.delay_variation = L2CAP_DEFAULT_DELAY;
1409
1410 p_ccb->bypass_fcs = 0;
1411 memset (&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO));
1412 p_ccb->peer_cfg_already_rejected = FALSE;
1413 p_ccb->fcr_cfg_tries = L2CAP_MAX_FCR_CFG_TRIES;
1414 p_ccb->fcrb.ack_timer.param = (TIMER_PARAM_TYPE)p_ccb;
1415
1416 /* if timer is running, remove it from timer list */
1417 if (p_ccb->fcrb.ack_timer.in_use)
1418 btu_stop_quick_timer (&p_ccb->fcrb.ack_timer);
1419
1420 p_ccb->fcrb.mon_retrans_timer.param = (TIMER_PARAM_TYPE)p_ccb;
1421
1422 // btla-specific ++
1423 /* CSP408639 Fix: When L2CAP send amp move channel request or receive
1424 * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
1425 * request -> Stop retrans/monitor timer -> Change channel state to CST_AMP_MOVING. */
1426 if (p_ccb->fcrb.mon_retrans_timer.in_use)
1427 btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
1428 // btla-specific --
1429
1430 l2c_fcr_stop_timer (p_ccb);
1431
1432 p_ccb->ertm_info.preferred_mode = L2CAP_FCR_BASIC_MODE; /* Default mode for channel is basic mode */
1433 p_ccb->ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_BASIC; /* Default mode for channel is basic mode */
1434 p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_FCR_RX_POOL_ID;
1435 p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_FCR_TX_POOL_ID;
1436 p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
1437 p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
1438 p_ccb->max_rx_mtu = L2CAP_MTU_SIZE;
1439 p_ccb->tx_mps = GKI_get_pool_bufsize(HCI_ACL_POOL_ID) - 32;
1440
1441 GKI_init_q (&p_ccb->xmit_hold_q);
1442
1443 p_ccb->cong_sent = FALSE;
1444 p_ccb->buff_quota = 2; /* This gets set after config */
1445
1446 /* If CCB was reserved Config_Done can already have some value */
1447 if (cid == 0)
1448 p_ccb->config_done = 0;
1449 else
1450 {
1451 L2CAP_TRACE_DEBUG2 ("l2cu_allocate_ccb: cid 0x%04x config_done:0x%x", cid, p_ccb->config_done);
1452 }
1453
1454 p_ccb->chnl_state = CST_CLOSED;
1455 p_ccb->flags = 0;
1456 p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1457 p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
1458
1459 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
1460 p_ccb->is_flushable = FALSE;
1461 #endif
1462
1463 p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
1464 p_ccb->timer_entry.in_use = 0;
1465
1466 l2c_link_adjust_chnl_allocation ();
1467
1468 return (p_ccb);
1469 }
1470
1471 /*******************************************************************************
1472 **
1473 ** Function l2cu_start_post_bond_timer
1474 **
1475 ** Description This function starts the ACL Link inactivity timer after
1476 ** dedicated bonding
1477 ** This timer can be longer than the normal link inactivity
1478 ** timer for some platforms.
1479 **
1480 ** Returns BOOLEAN - TRUE if idle timer started or disconnect initiated
1481 ** FALSE if there's one or more pending CCB's exist
1482 **
1483 *******************************************************************************/
l2cu_start_post_bond_timer(UINT16 handle)1484 BOOLEAN l2cu_start_post_bond_timer (UINT16 handle)
1485 {
1486 UINT16 timeout;
1487 tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
1488
1489 if (!p_lcb)
1490 return (TRUE);
1491
1492 p_lcb->is_bonding = FALSE;
1493
1494 /* Only start timer if no control blocks allocated */
1495 if (p_lcb->ccb_queue.p_first_ccb != NULL)
1496 return (FALSE);
1497
1498 /* If no channels on the connection, start idle timeout */
1499 if ( (p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_CONNECTING) || (p_lcb->link_state == LST_DISCONNECTING) )
1500 {
1501 if (p_lcb->idle_timeout == 0)
1502 {
1503 if (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER))
1504 {
1505 p_lcb->link_state = LST_DISCONNECTING;
1506 timeout = L2CAP_LINK_DISCONNECT_TOUT;
1507 }
1508 else
1509 timeout = BT_1SEC_TIMEOUT;
1510 }
1511 else
1512 {
1513 timeout = L2CAP_BONDING_TIMEOUT;
1514 }
1515
1516 if (timeout != 0xFFFF)
1517 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
1518
1519 return (TRUE);
1520 }
1521
1522 return (FALSE);
1523 }
1524
1525 /*******************************************************************************
1526 **
1527 ** Function l2cu_release_ccb
1528 **
1529 ** Description This function releases a Channel Control Block. The timer
1530 ** is stopped, any attached buffers freed, and the CCB is removed
1531 ** from the link control block.
1532 **
1533 ** Returns void
1534 **
1535 *******************************************************************************/
l2cu_release_ccb(tL2C_CCB * p_ccb)1536 void l2cu_release_ccb (tL2C_CCB *p_ccb)
1537 {
1538 tL2C_LCB *p_lcb = p_ccb->p_lcb;
1539 tL2C_RCB *p_rcb = p_ccb->p_rcb;
1540
1541 L2CAP_TRACE_DEBUG2 ("l2cu_release_ccb: cid 0x%04x in_use: %u", p_ccb->local_cid, p_ccb->in_use);
1542
1543 /* If already released, could be race condition */
1544 if (!p_ccb->in_use)
1545 return;
1546
1547 if (p_rcb && (p_rcb->psm != p_rcb->real_psm))
1548 {
1549 btm_sec_clr_service_by_psm(p_rcb->psm);
1550 }
1551
1552 btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr);
1553
1554 /* Stop the timer */
1555 btu_stop_timer (&p_ccb->timer_entry);
1556
1557 while (p_ccb->xmit_hold_q.p_first)
1558 GKI_freebuf (GKI_dequeue (&p_ccb->xmit_hold_q));
1559
1560 l2c_fcr_cleanup (p_ccb);
1561
1562 /* Channel may not be assigned to any LCB if it was just pre-reserved */
1563 if ( (p_lcb) &&
1564 ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID)
1565 #if (L2CAP_UCD_INCLUDED == TRUE)
1566 ||(p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID)
1567 #endif
1568 )
1569 )
1570 {
1571 l2cu_dequeue_ccb (p_ccb);
1572
1573 /* Delink the CCB from the LCB */
1574 p_ccb->p_lcb = NULL;
1575 }
1576
1577 /* Put the CCB back on the free pool */
1578 if (!l2cb.p_free_ccb_first)
1579 {
1580 l2cb.p_free_ccb_first = p_ccb;
1581 l2cb.p_free_ccb_last = p_ccb;
1582 p_ccb->p_next_ccb = NULL;
1583 p_ccb->p_prev_ccb = NULL;
1584 }
1585 else
1586 {
1587 p_ccb->p_next_ccb = NULL;
1588 p_ccb->p_prev_ccb = l2cb.p_free_ccb_last;
1589 l2cb.p_free_ccb_last->p_next_ccb = p_ccb;
1590 l2cb.p_free_ccb_last = p_ccb;
1591 }
1592
1593 /* Flag as not in use */
1594 p_ccb->in_use = FALSE;
1595
1596 /* If no channels on the connection, start idle timeout */
1597 if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED))
1598 {
1599 if (!p_lcb->ccb_queue.p_first_ccb)
1600 {
1601 l2cu_no_dynamic_ccbs (p_lcb);
1602 }
1603 else
1604 {
1605 /* Link is still active, adjust channel quotas. */
1606 l2c_link_adjust_chnl_allocation ();
1607 }
1608 }
1609 }
1610
1611 /*******************************************************************************
1612 **
1613 ** Function l2cu_find_ccb_by_remote_cid
1614 **
1615 ** Description Look through all active CCBs on a link for a match based
1616 ** on the remote CID.
1617 **
1618 ** Returns pointer to matched CCB, or NULL if no match
1619 **
1620 *******************************************************************************/
l2cu_find_ccb_by_remote_cid(tL2C_LCB * p_lcb,UINT16 remote_cid)1621 tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid)
1622 {
1623 tL2C_CCB *p_ccb;
1624
1625 /* If LCB is NULL, look through all active links */
1626 if (!p_lcb)
1627 {
1628 return NULL;
1629 }
1630 else
1631 {
1632 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
1633 if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid))
1634 return (p_ccb);
1635 }
1636
1637 /* If here, no match found */
1638 return (NULL);
1639 }
1640
1641 /*******************************************************************************
1642 **
1643 ** Function l2cu_allocate_rcb
1644 **
1645 ** Description Look through the Registration Control Blocks for a free
1646 ** one.
1647 **
1648 ** Returns Pointer to the RCB or NULL if not found
1649 **
1650 *******************************************************************************/
l2cu_allocate_rcb(UINT16 psm)1651 tL2C_RCB *l2cu_allocate_rcb (UINT16 psm)
1652 {
1653 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0];
1654 UINT16 xx;
1655
1656 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
1657 {
1658 if (!p_rcb->in_use)
1659 {
1660 p_rcb->in_use = TRUE;
1661 p_rcb->psm = psm;
1662 #if (L2CAP_UCD_INCLUDED == TRUE)
1663 p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
1664 #endif
1665 return (p_rcb);
1666 }
1667 }
1668
1669 /* If here, no free RCB found */
1670 return (NULL);
1671 }
1672
1673
1674 /*******************************************************************************
1675 **
1676 ** Function l2cu_release_rcb
1677 **
1678 ** Description Mark an RCB as no longet in use
1679 **
1680 ** Returns void
1681 **
1682 *******************************************************************************/
l2cu_release_rcb(tL2C_RCB * p_rcb)1683 void l2cu_release_rcb (tL2C_RCB *p_rcb)
1684 {
1685 p_rcb->in_use = FALSE;
1686 p_rcb->psm = 0;
1687 }
1688
1689
1690 /*******************************************************************************
1691 **
1692 ** Function l2cu_disconnect_chnl
1693 **
1694 ** Description Disconnect a channel. Typically, this is due to either
1695 ** receiving a bad configuration, bad packet or max_retries expiring.
1696 **
1697 *******************************************************************************/
l2cu_disconnect_chnl(tL2C_CCB * p_ccb)1698 void l2cu_disconnect_chnl (tL2C_CCB *p_ccb)
1699 {
1700 UINT16 local_cid = p_ccb->local_cid;
1701
1702 if (local_cid >= L2CAP_BASE_APPL_CID)
1703 {
1704 tL2CA_DISCONNECT_IND_CB *p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
1705
1706 L2CAP_TRACE_WARNING1 ("L2CAP - disconnect_chnl CID: 0x%04x", local_cid);
1707
1708 l2cu_send_peer_disc_req (p_ccb);
1709
1710 l2cu_release_ccb (p_ccb);
1711
1712 (*p_disc_cb)(local_cid, FALSE);
1713 }
1714 else
1715 {
1716 /* failure on the AMP channel, probably need to disconnect ACL */
1717 L2CAP_TRACE_ERROR1 ("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid);
1718 }
1719 }
1720
1721
1722 /*******************************************************************************
1723 **
1724 ** Function l2cu_find_rcb_by_psm
1725 **
1726 ** Description Look through the Registration Control Blocks to see if
1727 ** anyone registered to handle the PSM in question
1728 **
1729 ** Returns Pointer to the RCB or NULL if not found
1730 **
1731 *******************************************************************************/
l2cu_find_rcb_by_psm(UINT16 psm)1732 tL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm)
1733 {
1734 tL2C_RCB *p_rcb = &l2cb.rcb_pool[0];
1735 UINT16 xx;
1736
1737 for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
1738 {
1739 if ((p_rcb->in_use) && (p_rcb->psm == psm))
1740 return (p_rcb);
1741 }
1742
1743 /* If here, no match found */
1744 return (NULL);
1745 }
1746
1747
1748 /*******************************************************************************
1749 **
1750 ** Function l2cu_process_peer_cfg_req
1751 **
1752 ** Description This function is called when the peer sends us a "config request"
1753 ** message. It extracts the configuration of interest and saves
1754 ** it in the CCB.
1755 **
1756 ** Note: Negotiation of the FCR channel type is handled internally,
1757 ** all others are passed to the upper layer.
1758 **
1759 ** Returns UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer,
1760 ** L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to
1761 ** because parameters are unnacceptable from a specification
1762 ** point of view.
1763 ** L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes
1764 ** between the two devices, and shall be closed.
1765 **
1766 *******************************************************************************/
l2cu_process_peer_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)1767 UINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
1768 {
1769 BOOLEAN mtu_ok = TRUE;
1770 BOOLEAN qos_type_ok = TRUE;
1771 BOOLEAN flush_to_ok = TRUE;
1772 BOOLEAN fcr_ok = TRUE;
1773 UINT8 fcr_status;
1774
1775 /* Ignore FCR parameters for basic mode */
1776 if (!p_cfg->fcr_present)
1777 p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
1778
1779 /* Save the MTU that our peer can receive */
1780 if (p_cfg->mtu_present)
1781 {
1782 /* Make sure MTU is at least the minimum */
1783 if (p_cfg->mtu >= L2CAP_MIN_MTU)
1784 {
1785 /* In basic mode, limit the MTU to our buffer size */
1786 if ( (p_cfg->fcr_present == FALSE) && (p_cfg->mtu > L2CAP_MTU_SIZE) )
1787 p_cfg->mtu = L2CAP_MTU_SIZE;
1788
1789 /* Save the accepted value in case of renegotiation */
1790 p_ccb->peer_cfg.mtu = p_cfg->mtu;
1791 p_ccb->peer_cfg.mtu_present = TRUE;
1792 p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
1793 }
1794 else /* Illegal MTU value */
1795 {
1796 p_cfg->mtu = L2CAP_MIN_MTU;
1797 mtu_ok = FALSE;
1798 }
1799 }
1800 /* Reload mtu from a previously accepted config request */
1801 else if (p_ccb->peer_cfg.mtu_present)
1802 {
1803 p_cfg->mtu_present = TRUE;
1804 p_cfg->mtu = p_ccb->peer_cfg.mtu;
1805 }
1806
1807 /* Verify that the flush timeout is a valid value (0 is illegal) */
1808 if (p_cfg->flush_to_present)
1809 {
1810 if (!p_cfg->flush_to)
1811 {
1812 p_cfg->flush_to = 0xFFFF; /* Infinite retransmissions (spec default) */
1813 flush_to_ok = FALSE;
1814 }
1815 else /* Save the accepted value in case of renegotiation */
1816 {
1817 p_ccb->peer_cfg.flush_to_present = TRUE;
1818 p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
1819 p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
1820 }
1821 }
1822 /* Reload flush_to from a previously accepted config request */
1823 else if (p_ccb->peer_cfg.flush_to_present)
1824 {
1825 p_cfg->flush_to_present = TRUE;
1826 p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
1827 }
1828
1829 /* Save the QOS settings the the peer is using */
1830 if (p_cfg->qos_present)
1831 {
1832 /* Make sure service type is not a reserved value; otherwise let upper
1833 layer decide if acceptable
1834 */
1835 if (p_cfg->qos.service_type <= GUARANTEED)
1836 {
1837 p_ccb->peer_cfg.qos = p_cfg->qos;
1838 p_ccb->peer_cfg.qos_present = TRUE;
1839 p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
1840 }
1841 else /* Illegal service type value */
1842 {
1843 p_cfg->qos.service_type = BEST_EFFORT;
1844 qos_type_ok = FALSE;
1845 }
1846 }
1847 /* Reload QOS from a previously accepted config request */
1848 else if (p_ccb->peer_cfg.qos_present)
1849 {
1850 p_cfg->qos_present = TRUE;
1851 p_cfg->qos = p_ccb->peer_cfg.qos;
1852 }
1853
1854 if ((fcr_status = l2c_fcr_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_DISCONNECT)
1855 {
1856 /* Notify caller to disconnect the channel (incompatible modes) */
1857 p_cfg->result = L2CAP_CFG_FAILED_NO_REASON;
1858 p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
1859
1860 return (L2CAP_PEER_CFG_DISCONNECT);
1861 }
1862
1863 fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
1864
1865 /* Return any unacceptable parameters */
1866 if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok)
1867 {
1868 l2cu_adjust_out_mps (p_ccb);
1869 return (L2CAP_PEER_CFG_OK);
1870 }
1871 else
1872 {
1873 p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
1874
1875 if (mtu_ok)
1876 p_cfg->mtu_present = FALSE;
1877 if (flush_to_ok)
1878 p_cfg->flush_to_present = FALSE;
1879 if (qos_type_ok)
1880 p_cfg->qos_present = FALSE;
1881 if (fcr_ok)
1882 p_cfg->fcr_present = FALSE;
1883
1884 return (L2CAP_PEER_CFG_UNACCEPTABLE);
1885 }
1886 }
1887
1888
1889 /*******************************************************************************
1890 **
1891 ** Function l2cu_process_peer_cfg_rsp
1892 **
1893 ** Description This function is called when the peer sends us a "config response"
1894 ** message. It extracts the configuration of interest and saves
1895 ** it in the CCB.
1896 **
1897 ** Returns void
1898 **
1899 *******************************************************************************/
l2cu_process_peer_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)1900 void l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
1901 {
1902 /* If we wanted QoS and the peer sends us a positive response with QoS, use his values */
1903 if ( (p_cfg->qos_present) && (p_ccb->our_cfg.qos_present) )
1904 p_ccb->our_cfg.qos = p_cfg->qos;
1905
1906 if (p_cfg->fcr_present)
1907 {
1908 /* Save the retransmission and monitor timeout values */
1909 if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE)
1910 {
1911 p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
1912 p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
1913 }
1914
1915 /* Calculate the max number of packets for which we can delay sending an ack */
1916 if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz)
1917 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
1918 else
1919 p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
1920
1921 L2CAP_TRACE_DEBUG3 ("l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, max_held_acks: %d",
1922 p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks);
1923 }
1924 }
1925
1926 /*******************************************************************************
1927 **
1928 ** Function l2cu_process_our_cfg_req
1929 **
1930 ** Description This function is called when we send a "config request"
1931 ** message. It extracts the configuration of interest and saves
1932 ** it in the CCB.
1933 **
1934 ** Returns void
1935 **
1936 *******************************************************************************/
l2cu_process_our_cfg_req(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)1937 void l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
1938 {
1939 tL2C_LCB *p_lcb;
1940 UINT16 hci_flush_to;
1941
1942 /* Save the QOS settings we are using for transmit */
1943 if (p_cfg->qos_present)
1944 {
1945 p_ccb->our_cfg.qos_present = TRUE;
1946 p_ccb->our_cfg.qos = p_cfg->qos;
1947 }
1948
1949 if (p_cfg->fcr_present)
1950 {
1951 /* Override FCR options if attempting streaming or basic */
1952 if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)
1953 memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
1954 else
1955 {
1956 /* On BR/EDR, timer values are zero in config request */
1957 /* On class 2 AMP, timer value in config request shall be non-0 processing time */
1958 /* timer value in config response shall be greater than received processing time */
1959 p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
1960
1961 if (p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE)
1962 p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0;
1963 }
1964
1965 /* Set the threshold to send acks (may be updated in the cfg response) */
1966 p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
1967
1968 /* Include FCS option only if peer can handle it */
1969 if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC)
1970 {
1971 /* FCS check can be bypassed if peer also desires to bypass */
1972 if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS)
1973 p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR;
1974 }
1975 else
1976 p_cfg->fcs_present = FALSE;
1977 }
1978 else
1979 {
1980 p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
1981 }
1982
1983 p_ccb->our_cfg.fcr.mode = p_cfg->fcr.mode;
1984 p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
1985
1986 /* Check the flush timeout. If it is lower than the current one used */
1987 /* then we need to adjust the flush timeout sent to the controller */
1988 if (p_cfg->flush_to_present)
1989 {
1990 if ((p_cfg->flush_to == 0)||(p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH))
1991 {
1992 /* don't send invalid flush timeout */
1993 /* SPEC: The sender of the Request shall specify its flush timeout value */
1994 /* if it differs from the default value of 0xFFFF */
1995 p_cfg->flush_to_present = FALSE;
1996 }
1997 else
1998 {
1999 p_ccb->our_cfg.flush_to = p_cfg->flush_to;
2000 p_lcb = p_ccb->p_lcb;
2001
2002 if (p_cfg->flush_to < p_lcb->link_flush_tout)
2003 {
2004 p_lcb->link_flush_tout = p_cfg->flush_to;
2005
2006 /* If the timeout is within range of HCI, set the flush timeout */
2007 if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8))
2008 {
2009 /* Convert flush timeout to 0.625 ms units, with round */
2010 hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
2011 btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to);
2012 }
2013 }
2014 }
2015 }
2016 }
2017
2018
2019 /*******************************************************************************
2020 **
2021 ** Function l2cu_process_our_cfg_rsp
2022 **
2023 ** Description This function is called when we send the peer a "config response"
2024 ** message. It extracts the configuration of interest and saves
2025 ** it in the CCB.
2026 **
2027 ** Returns void
2028 **
2029 *******************************************************************************/
l2cu_process_our_cfg_rsp(tL2C_CCB * p_ccb,tL2CAP_CFG_INFO * p_cfg)2030 void l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
2031 {
2032 /* If peer wants QoS, we are allowed to change the values in a positive response */
2033 if ( (p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present) )
2034 p_ccb->peer_cfg.qos = p_cfg->qos;
2035 else
2036 p_cfg->qos_present = FALSE;
2037
2038 l2c_fcr_adj_our_rsp_options (p_ccb, p_cfg);
2039 }
2040
2041
2042 /*******************************************************************************
2043 **
2044 ** Function l2cu_device_reset
2045 **
2046 ** Description This function is called when reset of the device is
2047 ** completed. For all active connection simulate HCI_DISC
2048 **
2049 ** Returns void
2050 **
2051 *******************************************************************************/
l2cu_device_reset(void)2052 void l2cu_device_reset (void)
2053 {
2054 int xx;
2055 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
2056
2057 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2058 {
2059 if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE))
2060 {
2061 l2c_link_hci_disc_comp (p_lcb->handle, (UINT8) -1);
2062 }
2063 }
2064 #if (BLE_INCLUDED == TRUE)
2065 l2cb.is_ble_connecting = FALSE;
2066 #endif
2067 }
2068
2069 #if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
2070 extern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ;
2071 #endif
2072
2073 /*******************************************************************************
2074 **
2075 ** Function l2cu_create_conn
2076 **
2077 ** Description This function initiates an acl connection via HCI
2078 **
2079 ** Returns TRUE if successful, FALSE if gki get buffer fails.
2080 **
2081 *******************************************************************************/
l2cu_create_conn(tL2C_LCB * p_lcb)2082 BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb)
2083 {
2084 int xx;
2085 tL2C_LCB *p_lcb_cur = &l2cb.lcb_pool[0];
2086 #if BTM_SCO_INCLUDED == TRUE
2087 BOOLEAN is_sco_active;
2088 #endif
2089
2090 #if (BLE_INCLUDED == TRUE)
2091 tBT_DEVICE_TYPE dev_type;
2092 tBLE_ADDR_TYPE addr_type;
2093
2094 BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
2095
2096 if (dev_type == BT_DEVICE_TYPE_BLE)
2097 {
2098 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
2099 return FALSE;
2100
2101 p_lcb->ble_addr_type = addr_type;
2102 p_lcb->is_ble_link = TRUE;
2103
2104 return (l2cble_create_conn(p_lcb));
2105 }
2106 #endif
2107
2108 /* If there is a connection where we perform as a slave, try to switch roles
2109 for this connection */
2110 for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++)
2111 {
2112 if (p_lcb_cur == p_lcb)
2113 continue;
2114
2115 if ((p_lcb_cur->in_use) && (p_lcb_cur->link_role == HCI_ROLE_SLAVE))
2116 {
2117
2118 #if BTM_SCO_INCLUDED == TRUE
2119 /* The LMP_switch_req shall be sent only if the ACL logical transport
2120 is in active mode, when encryption is disabled, and all synchronous
2121 logical transports on the same physical link are disabled." */
2122
2123 /* Check if there is any SCO Active on this BD Address */
2124 is_sco_active = btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr);
2125
2126 L2CAP_TRACE_API1 ("l2cu_create_conn - btm_is_sco_active_by_bdaddr() is_sco_active = %s", \
2127 (is_sco_active == TRUE) ? "TRUE":"FALSE");
2128
2129 if (is_sco_active == TRUE)
2130 continue; /* No Master Slave switch not allowed when SCO Active */
2131 #endif
2132
2133 if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures()))
2134 {
2135 /* mark this lcb waiting for switch to be completed and
2136 start switch on the other one */
2137 p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH;
2138 p_lcb->link_role = HCI_ROLE_MASTER;
2139
2140 if (BTM_SwitchRole (p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) == BTM_CMD_STARTED)
2141 {
2142 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_ROLE_SWITCH_TOUT);
2143 return (TRUE);
2144 }
2145 }
2146 }
2147 }
2148
2149 p_lcb->link_state = LST_CONNECTING;
2150
2151 return (l2cu_create_conn_after_switch (p_lcb));
2152 }
2153
2154 /*******************************************************************************
2155 **
2156 ** Function l2cu_get_num_hi_priority
2157 **
2158 ** Description Gets the number of high priority channels.
2159 **
2160 ** Returns
2161 **
2162 *******************************************************************************/
l2cu_get_num_hi_priority(void)2163 UINT8 l2cu_get_num_hi_priority (void)
2164 {
2165 UINT8 no_hi = 0;
2166 int xx;
2167 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
2168
2169 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2170 {
2171 if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
2172 {
2173 no_hi++;
2174 }
2175 }
2176 return no_hi;
2177 }
2178
2179
2180 /*******************************************************************************
2181 **
2182 ** Function l2cu_create_conn_after_switch
2183 **
2184 ** Description This function initiates an acl connection via HCI
2185 ** If switch required to create connection it is already done.
2186 **
2187 ** Returns TRUE if successful, FALSE if gki get buffer fails.
2188 **
2189 *******************************************************************************/
2190
l2cu_create_conn_after_switch(tL2C_LCB * p_lcb)2191 BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb)
2192 {
2193 UINT8 allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
2194 tBTM_INQ_INFO *p_inq_info;
2195 UINT8 page_scan_rep_mode;
2196 UINT8 page_scan_mode;
2197 UINT16 clock_offset;
2198 UINT8 *p_features;
2199 UINT16 num_acl = BTM_GetNumAclLinks();
2200 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_lcb->remote_bd_addr);
2201 UINT8 no_hi_prio_chs = l2cu_get_num_hi_priority();
2202
2203 p_features = BTM_ReadLocalFeatures();
2204
2205 L2CAP_TRACE_DEBUG4 ("l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d",
2206 l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding);
2207 /* FW team says that we can participant in 4 piconets
2208 * typically 3 piconet + 1 for scanning.
2209 * We can enhance the code to count the number of piconets later. */
2210 if ( ((!l2cb.disallow_switch && (num_acl < 3)) || (p_lcb->is_bonding && (no_hi_prio_chs==0)))
2211 && HCI_SWITCH_SUPPORTED(p_features))
2212 allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
2213 else
2214 allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
2215
2216 p_lcb->link_state = LST_CONNECTING;
2217
2218
2219 #if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
2220 if ( (clock_offset = tcs_wug_get_clk_offset( p_lcb->remote_bd_addr )) != 0 )
2221 {
2222 page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R0;
2223 page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
2224 }
2225 else
2226 {
2227 #endif
2228
2229 /* Check with the BT manager if details about remote device are known */
2230 if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL)
2231 {
2232 page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
2233 page_scan_mode = p_inq_info->results.page_scan_mode;
2234 clock_offset = (UINT16)(p_inq_info->results.clock_offset);
2235 }
2236 else
2237 {
2238 /* No info known. Use default settings */
2239 page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
2240 page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
2241
2242 clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
2243 }
2244 #if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
2245 }
2246 #endif
2247
2248 if (!btsnd_hcic_create_conn (p_lcb->remote_bd_addr,
2249 HCI_PKT_TYPES_MASK_DM1 + HCI_PKT_TYPES_MASK_DH1,
2250 page_scan_rep_mode,
2251 page_scan_mode,
2252 clock_offset,
2253 allow_switch))
2254
2255 {
2256 L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for l2cu_create_conn");
2257 l2cu_release_lcb (p_lcb);
2258 return (FALSE);
2259 }
2260
2261 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2262 btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
2263 #endif
2264
2265 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK,
2266 L2CAP_LINK_CONNECT_TOUT);
2267
2268 return (TRUE);
2269 }
2270
2271
2272 /*******************************************************************************
2273 **
2274 ** Function l2cu_find_lcb_by_state
2275 **
2276 ** Description Look through all active LCBs for a match based on the
2277 ** LCB state.
2278 **
2279 ** Returns pointer to first matched LCB, or NULL if no match
2280 **
2281 *******************************************************************************/
l2cu_find_lcb_by_state(tL2C_LINK_STATE state)2282 tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state)
2283 {
2284 UINT16 i;
2285 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
2286
2287 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
2288 {
2289 if ((p_lcb->in_use) && (p_lcb->link_state == state))
2290 {
2291 return (p_lcb);
2292 }
2293 }
2294
2295 /* If here, no match found */
2296 return (NULL);
2297 }
2298
2299
2300 /*******************************************************************************
2301 **
2302 ** Function l2cu_lcb_disconnecting
2303 **
2304 ** Description On each active lcb, check if the lcb is in disconnecting
2305 ** state, or if there are no ccb's on the lcb (implying
2306 idle timeout is running), or if last ccb on the link
2307 is in disconnecting state.
2308 **
2309 ** Returns TRUE if any of above conditions met, FALSE otherwise
2310 **
2311 *******************************************************************************/
l2cu_lcb_disconnecting(void)2312 BOOLEAN l2cu_lcb_disconnecting (void)
2313 {
2314 tL2C_LCB *p_lcb;
2315 tL2C_CCB *p_ccb;
2316 UINT16 i;
2317 BOOLEAN status = FALSE;
2318
2319 p_lcb = &l2cb.lcb_pool[0];
2320
2321 for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
2322 {
2323 if (p_lcb->in_use)
2324 {
2325 /* no ccbs on lcb, or lcb is in disconnecting state */
2326 if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING))
2327 {
2328 status = TRUE;
2329 break;
2330 }
2331 /* only one ccb left on lcb */
2332 else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb)
2333 {
2334 p_ccb = p_lcb->ccb_queue.p_first_ccb;
2335
2336 if ((p_ccb->in_use) &&
2337 ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
2338 (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP)))
2339 {
2340 status = TRUE;
2341 break;
2342 }
2343 }
2344 }
2345 }
2346 return status;
2347 }
2348
2349
2350 /*******************************************************************************
2351 **
2352 ** Function l2cu_set_acl_priority
2353 **
2354 ** Description Sets the transmission priority for a channel.
2355 ** (For initial implementation only two values are valid.
2356 ** L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
2357 **
2358 ** Returns TRUE if a valid channel, else FALSE
2359 **
2360 *******************************************************************************/
2361
l2cu_set_acl_priority(BD_ADDR bd_addr,UINT8 priority,BOOLEAN reset_after_rs)2362 BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs)
2363 {
2364 tL2C_LCB *p_lcb;
2365 UINT8 *pp;
2366 UINT8 command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2367 UINT8 vs_param;
2368
2369 APPL_TRACE_EVENT1("SET ACL PRIORITY %d", priority);
2370
2371 /* Find the link control block for the acl channel */
2372 if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr)) == NULL)
2373 {
2374 L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_SetAclPriority");
2375 return (FALSE);
2376 }
2377
2378 if (BTM_IS_BRCM_CONTROLLER())
2379 {
2380 /* Called from above L2CAP through API; send VSC if changed */
2381 if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
2382 /* Called because of a master/slave role switch; if high resend VSC */
2383 ( reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
2384 {
2385 pp = command;
2386
2387 vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH : HCI_BRCM_ACL_PRIORITY_LOW;
2388
2389 UINT16_TO_STREAM (pp, p_lcb->handle);
2390 UINT8_TO_STREAM (pp, vs_param);
2391
2392 BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
2393
2394 /* Adjust lmp buffer allocation for this channel if priority changed */
2395 if (p_lcb->acl_priority != priority)
2396 {
2397 p_lcb->acl_priority = priority;
2398 l2c_link_adjust_allocation();
2399 }
2400 }
2401 }
2402 return(TRUE);
2403 }
2404
2405 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
2406 /******************************************************************************
2407 **
2408 ** Function l2cu_set_non_flushable_pbf
2409 **
2410 ** Description set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
2411 **
2412 ** Returns void
2413 **
2414 *******************************************************************************/
l2cu_set_non_flushable_pbf(BOOLEAN is_supported)2415 void l2cu_set_non_flushable_pbf (BOOLEAN is_supported)
2416 {
2417 if (is_supported)
2418 l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
2419 else
2420 l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
2421 }
2422 #endif
2423
2424 /*******************************************************************************
2425 **
2426 ** Function l2cu_resubmit_pending_sec_req
2427 **
2428 ** Description This function is called when required security procedures
2429 ** are completed and any pending requests can be re-submitted.
2430 **
2431 ** Returns void
2432 **
2433 *******************************************************************************/
l2cu_resubmit_pending_sec_req(BD_ADDR p_bda)2434 void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
2435 {
2436 tL2C_LCB *p_lcb;
2437 tL2C_CCB *p_ccb;
2438 tL2C_CCB *p_next_ccb;
2439 int xx;
2440
2441 L2CAP_TRACE_DEBUG1 ("l2cu_resubmit_pending_sec_req p_bda: 0x%08x", p_bda);
2442
2443 /* If we are called with a BDA, only resubmit for that BDA */
2444 if (p_bda)
2445 {
2446 p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
2447
2448 /* If we don't have one, this is an error */
2449 if (p_lcb)
2450 {
2451 /* For all channels, send the event through their FSMs */
2452 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
2453 {
2454 p_next_ccb = p_ccb->p_next_ccb;
2455 l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2456 }
2457 }
2458 else
2459 {
2460 L2CAP_TRACE_WARNING0 ("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
2461 }
2462 }
2463 else
2464 {
2465 /* No BDA pasesed in, so check all links */
2466 for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2467 {
2468 if (p_lcb->in_use)
2469 {
2470 /* For all channels, send the event through their FSMs */
2471 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
2472 {
2473 p_next_ccb = p_ccb->p_next_ccb;
2474 l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
2475 }
2476 }
2477 }
2478 }
2479 }
2480
2481 #if L2CAP_CONFORMANCE_TESTING == TRUE
2482 /*******************************************************************************
2483 **
2484 ** Function l2cu_set_info_rsp_mask
2485 **
2486 ** Description This function allows the script wrapper to change the
2487 ** info resp mask for conformance testing.
2488 **
2489 ** Returns pointer to CCB, or NULL if none
2490 **
2491 *******************************************************************************/
l2cu_set_info_rsp_mask(UINT32 mask)2492 void l2cu_set_info_rsp_mask (UINT32 mask)
2493 {
2494 l2cb.test_info_resp = mask;
2495 }
2496 #endif /* L2CAP_CONFORMANCE_TESTING */
2497
2498 /*******************************************************************************
2499 **
2500 ** Function l2cu_adjust_out_mps
2501 **
2502 ** Description Sets our MPS based on current controller capabilities
2503 **
2504 ** Returns void
2505 **
2506 *******************************************************************************/
l2cu_adjust_out_mps(tL2C_CCB * p_ccb)2507 void l2cu_adjust_out_mps (tL2C_CCB *p_ccb)
2508 {
2509 UINT16 packet_size;
2510
2511 /* on the tx side MTU is selected based on packet size of the controller */
2512 packet_size = btm_get_max_packet_size (p_ccb->p_lcb->remote_bd_addr);
2513
2514 if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN))
2515 {
2516 /* something is very wrong */
2517 L2CAP_TRACE_ERROR2 ("l2cu_adjust_out_mps bad packet size: %u will use MPS: %u", packet_size, p_ccb->peer_cfg.fcr.mps);
2518 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2519 }
2520 else
2521 {
2522 packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
2523
2524 /* We try to negotiate MTU that each packet can be split into whole
2525 number of max packets. For example if link is 1.2 max packet size is 339 bytes.
2526 At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4 overhead.
2527 1695, that will be 5 Dh5 packets. Now maximum L2CAP packet is
2528 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
2529
2530 For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1 3DH5 packet
2531 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. */
2532 if (p_ccb->peer_cfg.fcr.mps >= packet_size)
2533 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
2534 else
2535 p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
2536
2537 L2CAP_TRACE_DEBUG3 ("l2cu_adjust_out_mps use %d Based on peer_cfg.fcr.mps: %u packet_size: %u",
2538 p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
2539 }
2540 }
2541
2542
2543 /*******************************************************************************
2544 **
2545 ** Function l2cu_initialize_fixed_ccb
2546 **
2547 ** Description Initialize a fixed channel's CCB
2548 **
2549 ** Returns TRUE or FALSE
2550 **
2551 *******************************************************************************/
l2cu_initialize_fixed_ccb(tL2C_LCB * p_lcb,UINT16 fixed_cid,tL2CAP_FCR_OPTS * p_fcr)2552 BOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr)
2553 {
2554 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2555 tL2C_CCB *p_ccb;
2556
2557 /* If we already have a CCB, then simply return */
2558 if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL)
2559 return (TRUE);
2560
2561 if ((p_ccb = l2cu_allocate_ccb (NULL, 0)) == NULL)
2562 return (FALSE);
2563
2564 btu_stop_timer(&p_lcb->timer_entry);
2565
2566 /* Set CID for the connection */
2567 p_ccb->local_cid = fixed_cid;
2568 p_ccb->remote_cid = fixed_cid;
2569
2570 GKI_init_q (&p_ccb->xmit_hold_q);
2571
2572 p_ccb->is_flushable = FALSE;
2573
2574 p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
2575
2576
2577 if (p_fcr)
2578 {
2579 /* Set the FCR parameters. For now, we will use default pools */
2580 p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr;
2581
2582 p_ccb->ertm_info.fcr_rx_pool_id = HCI_ACL_POOL_ID;
2583 p_ccb->ertm_info.fcr_tx_pool_id = HCI_ACL_POOL_ID;
2584 p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
2585 p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
2586
2587 p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3;
2588 }
2589
2590 /* Link ccb to lcb and lcb to ccb */
2591 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
2592 p_ccb->p_lcb = p_lcb;
2593
2594 /* There is no configuration, so if the link is up, the channel is up */
2595 if (p_lcb->link_state == LST_CONNECTED)
2596 p_ccb->chnl_state = CST_OPEN;
2597
2598 /* Set the default idle timeout value to use */
2599 p_ccb->fixed_chnl_idle_tout = l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
2600 #endif
2601 return (TRUE);
2602 }
2603
2604 /*******************************************************************************
2605 **
2606 ** Function l2cu_no_dynamic_ccbs
2607 **
2608 ** Description Handles the case when there are no more dynamic CCBs. If there
2609 ** are any fixed CCBs, start the longest of the fixed CCB timeouts,
2610 ** otherwise start the default link idle timeout or disconnect.
2611 **
2612 ** Returns void
2613 **
2614 *******************************************************************************/
l2cu_no_dynamic_ccbs(tL2C_LCB * p_lcb)2615 void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
2616 {
2617 tBTM_STATUS rc;
2618 UINT16 timeout = p_lcb->idle_timeout;
2619
2620 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2621 int xx;
2622
2623 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
2624 {
2625 if ( (p_lcb->p_fixed_ccbs[xx] != NULL) && (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout > timeout) )
2626 timeout = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout;
2627 }
2628 #endif
2629
2630 /* If the link is pairing, do not mess with the timeouts */
2631 if (p_lcb->is_bonding)
2632 return;
2633
2634 if (timeout == 0)
2635 {
2636 L2CAP_TRACE_DEBUG0 ("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
2637
2638 rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
2639 if (rc == BTM_CMD_STARTED)
2640 {
2641 p_lcb->link_state = LST_DISCONNECTING;
2642 timeout = L2CAP_LINK_DISCONNECT_TOUT;
2643 }
2644 else if (rc == BTM_SUCCESS)
2645 {
2646 /* BTM SEC will make sure that link is release (probably after pairing is done) */
2647 p_lcb->link_state = LST_DISCONNECTING;
2648 timeout = 0xFFFF;
2649 }
2650 else if ( (p_lcb->is_bonding)
2651 && (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) )
2652 {
2653 p_lcb->link_state = LST_DISCONNECTING;
2654 timeout = L2CAP_LINK_DISCONNECT_TOUT;
2655 }
2656 else
2657 {
2658 /* probably no buffer to send disconnect */
2659 timeout = BT_1SEC_TIMEOUT;
2660 }
2661 }
2662
2663 if (timeout != 0xFFFF)
2664 {
2665 L2CAP_TRACE_DEBUG1 ("l2cu_no_dynamic_ccbs() starting IDLE timeout: %d", timeout);
2666 btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
2667 }
2668 else
2669 {
2670 btu_stop_timer(&p_lcb->timer_entry);
2671 }
2672 }
2673
2674 #if (L2CAP_NUM_FIXED_CHNLS > 0)
2675 /*******************************************************************************
2676 **
2677 ** Function l2cu_process_fixed_chnl_resp
2678 **
2679 ** Description handle a fixed channel response (or lack thereof)
2680 ** if the link failed, or a fixed channel response was
2681 ** not received, the bitfield is all zeros.
2682 **
2683 *******************************************************************************/
l2cu_process_fixed_chnl_resp(tL2C_LCB * p_lcb)2684 void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
2685 {
2686 int xx;
2687 #if BLE_INCLUDED == TRUE
2688 UINT16 reason = (p_lcb->is_ble_link ) ? 1 : 0;
2689 #else
2690 UINT16 reason =0;
2691 #endif
2692
2693 /* Tell all registered fixed channels about the connection */
2694 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
2695 {
2696 if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
2697 {
2698 if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
2699 {
2700 if (p_lcb->p_fixed_ccbs[xx])
2701 p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
2702
2703 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason);
2704 }
2705 else
2706 {
2707 (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
2708
2709 if (p_lcb->p_fixed_ccbs[xx])
2710 {
2711 l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
2712 p_lcb->p_fixed_ccbs[xx] = NULL;
2713 }
2714 }
2715 }
2716 }
2717 }
2718 #endif
2719
2720 #if (BLE_INCLUDED == TRUE)
2721 /*******************************************************************************
2722 **
2723 ** Function l2cu_send_peer_ble_par_req
2724 **
2725 ** Description Build and send a BLE parameter update request message
2726 ** to the peer.
2727 **
2728 ** Returns void
2729 **
2730 *******************************************************************************/
l2cu_send_peer_ble_par_req(tL2C_LCB * p_lcb,UINT16 min_int,UINT16 max_int,UINT16 latency,UINT16 timeout)2731 void l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout)
2732 {
2733 BT_HDR *p_buf;
2734 UINT8 *p;
2735
2736 /* Create an identifier for this packet */
2737 p_lcb->id++;
2738 l2cu_adj_id (p_lcb, L2CAP_ADJ_ID);
2739
2740 if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN, L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id)) == NULL )
2741 {
2742 L2CAP_TRACE_WARNING0 ("l2cu_send_peer_ble_par_req - no buffer");
2743 return;
2744 }
2745
2746 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2747 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2748
2749 UINT16_TO_STREAM (p, min_int);
2750 UINT16_TO_STREAM (p, max_int);
2751 UINT16_TO_STREAM (p, latency);
2752 UINT16_TO_STREAM (p, timeout);
2753
2754 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
2755 }
2756
2757 /*******************************************************************************
2758 **
2759 ** Function l2cu_send_peer_ble_par_rsp
2760 **
2761 ** Description Build and send a BLE parameter update response message
2762 ** to the peer.
2763 **
2764 ** Returns void
2765 **
2766 *******************************************************************************/
l2cu_send_peer_ble_par_rsp(tL2C_LCB * p_lcb,UINT16 reason,UINT8 rem_id)2767 void l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id)
2768 {
2769 BT_HDR *p_buf;
2770 UINT8 *p;
2771
2772 if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN, L2CAP_CMD_BLE_UPDATE_RSP, rem_id)) == NULL )
2773 {
2774 L2CAP_TRACE_WARNING0 ("l2cu_send_peer_ble_par_rsp - no buffer");
2775 return;
2776 }
2777
2778 p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
2779 L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
2780
2781 UINT16_TO_STREAM (p, reason);
2782
2783 l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
2784 }
2785
2786 #endif /* BLE_INCLUDED == TRUE */
2787
2788
2789 /*******************************************************************************
2790 ** Functions used by both Full and Light Stack
2791 ********************************************************************************/
2792
2793 /*******************************************************************************
2794 **
2795 ** Function l2cu_find_lcb_by_handle
2796 **
2797 ** Description Look through all active LCBs for a match based on the
2798 ** HCI handle.
2799 **
2800 ** Returns pointer to matched LCB, or NULL if no match
2801 **
2802 *******************************************************************************/
l2cu_find_lcb_by_handle(UINT16 handle)2803 tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle)
2804 {
2805 int xx;
2806 tL2C_LCB *p_lcb = &l2cb.lcb_pool[0];
2807
2808 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2809 {
2810 if ((p_lcb->in_use) && (p_lcb->handle == handle))
2811 {
2812 return (p_lcb);
2813 }
2814 }
2815
2816 /* If here, no match found */
2817 return (NULL);
2818 }
2819
2820 /*******************************************************************************
2821 **
2822 ** Function l2cu_find_ccb_by_cid
2823 **
2824 ** Description Look through all active CCBs on a link for a match based
2825 ** on the local CID. If passed the link pointer is NULL, all
2826 ** active links are searched.
2827 **
2828 ** Returns pointer to matched CCB, or NULL if no match
2829 **
2830 *******************************************************************************/
l2cu_find_ccb_by_cid(tL2C_LCB * p_lcb,UINT16 local_cid)2831 tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid)
2832 {
2833 tL2C_CCB *p_ccb = NULL;
2834 #if (L2CAP_UCD_INCLUDED == TRUE)
2835 UINT8 xx;
2836 #endif
2837
2838 if (local_cid >= L2CAP_BASE_APPL_CID)
2839 {
2840 /* find the associated CCB by "index" */
2841 local_cid -= L2CAP_BASE_APPL_CID;
2842
2843 if (local_cid >= MAX_L2CAP_CHANNELS)
2844 return NULL;
2845
2846 p_ccb = l2cb.ccb_pool + local_cid;
2847
2848 /* make sure the CCB is in use */
2849 if (!p_ccb->in_use)
2850 {
2851 p_ccb = NULL;
2852 }
2853 /* make sure it's for the same LCB */
2854 else if (p_lcb && p_lcb != p_ccb->p_lcb)
2855 {
2856 p_ccb = NULL;
2857 }
2858 }
2859 #if (L2CAP_UCD_INCLUDED == TRUE)
2860 else
2861 {
2862 /* searching fixed channel */
2863 p_ccb = l2cb.ccb_pool;
2864 for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ )
2865 {
2866 if ((p_ccb->local_cid == local_cid)
2867 &&(p_ccb->in_use)
2868 &&(p_lcb == p_ccb->p_lcb))
2869 break;
2870 else
2871 p_ccb++;
2872 }
2873 if ( xx >= MAX_L2CAP_CHANNELS )
2874 return NULL;
2875 }
2876 #endif
2877
2878 return (p_ccb);
2879 }
2880
2881 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
2882
2883 /******************************************************************************
2884 **
2885 ** Function l2cu_get_next_channel_in_rr
2886 **
2887 ** Description get the next channel to send on a link. It also adjusts the
2888 ** CCB queue to do a basic priority and round-robin scheduling.
2889 **
2890 ** Returns pointer to CCB or NULL
2891 **
2892 *******************************************************************************/
l2cu_get_next_channel_in_rr(tL2C_LCB * p_lcb)2893 static tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb)
2894 {
2895 tL2C_CCB *p_serve_ccb = NULL;
2896 tL2C_CCB *p_ccb;
2897
2898 int i, j;
2899
2900 /* scan all of priority until finding a channel to serve */
2901 for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY)&&(!p_serve_ccb); i++ )
2902 {
2903 /* scan all channel within serving priority group until finding a channel to serve */
2904 for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb)&&(!p_serve_ccb); j++)
2905 {
2906 /* scaning from next serving channel */
2907 p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
2908
2909 if (!p_ccb)
2910 {
2911 L2CAP_TRACE_ERROR1("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
2912 return NULL;
2913 }
2914
2915 L2CAP_TRACE_DEBUG3("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
2916 p_ccb->ccb_priority, p_ccb->local_cid, p_ccb->xmit_hold_q.count );
2917
2918 /* store the next serving channel */
2919 /* this channel is the last channel of its priority group */
2920 if (( p_ccb->p_next_ccb == NULL )
2921 ||( p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority ))
2922 {
2923 /* next serving channel is set to the first channel in the group */
2924 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb;
2925 }
2926 else
2927 {
2928 /* next serving channel is set to the next channel in the group */
2929 p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
2930 }
2931
2932 if (p_ccb->chnl_state != CST_OPEN)
2933 continue;
2934
2935 /* eL2CAP option in use */
2936 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
2937 {
2938 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
2939 continue;
2940
2941 if ( p_ccb->fcrb.retrans_q.count == 0 )
2942 {
2943 if ( p_ccb->xmit_hold_q.count == 0 )
2944 continue;
2945
2946 /* If using the common pool, should be at least 10% free. */
2947 if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
2948 continue;
2949
2950 /* If in eRTM mode, check for window closure */
2951 if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
2952 continue;
2953 }
2954 }
2955 else
2956 {
2957 if (p_ccb->xmit_hold_q.count == 0)
2958 continue;
2959 }
2960
2961 /* found a channel to serve */
2962 p_serve_ccb = p_ccb;
2963 /* decrease quota of its priority group */
2964 p_lcb->rr_serv[p_lcb->rr_pri].quota--;
2965 }
2966
2967 /* if there is no more quota of the priority group or no channel to have data to send */
2968 if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0)||(!p_serve_ccb))
2969 {
2970 /* serve next priority group */
2971 p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
2972 /* initialize its quota */
2973 p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
2974 }
2975 }
2976
2977 if (p_serve_ccb)
2978 {
2979 L2CAP_TRACE_DEBUG3("RR service pri=%d, quota=%d, lcid=0x%04x",
2980 p_serve_ccb->ccb_priority,
2981 p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
2982 p_serve_ccb->local_cid );
2983 }
2984
2985 return p_serve_ccb;
2986 }
2987
2988 #else /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
2989
2990 /******************************************************************************
2991 **
2992 ** Function l2cu_get_next_channel
2993 **
2994 ** Description get the next channel to send on a link bassed on priority
2995 ** scheduling.
2996 **
2997 ** Returns pointer to CCB or NULL
2998 **
2999 *******************************************************************************/
l2cu_get_next_channel(tL2C_LCB * p_lcb)3000 static tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
3001 {
3002 tL2C_CCB *p_ccb;
3003
3004 /* Get the first CCB with data to send.
3005 */
3006 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
3007 {
3008 if (p_ccb->chnl_state != CST_OPEN)
3009 continue;
3010
3011 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
3012 continue;
3013
3014 if (p_ccb->fcrb.retrans_q.count != 0)
3015 return p_ccb;
3016
3017 if (p_ccb->xmit_hold_q.count == 0)
3018 continue;
3019
3020 /* If using the common pool, should be at least 10% free. */
3021 if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
3022 continue;
3023
3024 /* If in eRTM mode, check for window closure */
3025 if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
3026 continue;
3027
3028 /* If here, we found someone */
3029 return p_ccb;
3030 }
3031
3032 return NULL;
3033 }
3034 #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
3035
3036 /******************************************************************************
3037 **
3038 ** Function l2cu_get_next_buffer_to_send
3039 **
3040 ** Description get the next buffer to send on a link. It also adjusts the
3041 ** CCB queue to do a basic priority and round-robin scheduling.
3042 **
3043 ** Returns pointer to buffer or NULL
3044 **
3045 *******************************************************************************/
l2cu_get_next_buffer_to_send(tL2C_LCB * p_lcb)3046 BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
3047 {
3048 tL2C_CCB *p_ccb;
3049 BT_HDR *p_buf;
3050
3051 /* Highest priority are fixed channels */
3052 #if (L2CAP_NUM_FIXED_CHNLS > 0)
3053 int xx;
3054
3055 for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
3056 {
3057 if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL)
3058 continue;
3059
3060 /* eL2CAP option in use */
3061 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
3062 {
3063 if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
3064 continue;
3065
3066 /* No more checks needed if sending from the reatransmit queue */
3067 if (p_ccb->fcrb.retrans_q.count == 0)
3068 {
3069 if (p_ccb->xmit_hold_q.count == 0)
3070 continue;
3071
3072 /* If using the common pool, should be at least 10% free. */
3073 if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
3074 continue;
3075
3076 /* If in eRTM mode, check for window closure */
3077 if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
3078 continue;
3079 }
3080
3081 if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) != NULL)
3082 {
3083 l2cu_set_acl_hci_header (p_buf, p_ccb);
3084 return (p_buf);
3085 }
3086 }
3087 else
3088 {
3089 if (p_ccb->xmit_hold_q.count != 0)
3090 {
3091 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3092 if(NULL == p_buf)
3093 {
3094 L2CAP_TRACE_ERROR0("l2cu_get_buffer_to_send: No data to be sent");
3095 return (NULL);
3096 }
3097 l2cu_set_acl_hci_header (p_buf, p_ccb);
3098 return (p_buf);
3099 }
3100 }
3101 }
3102 #endif
3103
3104 #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
3105 /* get next serving channel in round-robin */
3106 p_ccb = l2cu_get_next_channel_in_rr( p_lcb );
3107 #else
3108 p_ccb = l2cu_get_next_channel( p_lcb );
3109 #endif
3110
3111 /* Return if no buffer */
3112 if (p_ccb == NULL)
3113 return (NULL);
3114
3115 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
3116 {
3117 if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL)
3118 return (NULL);
3119 }
3120 else
3121 {
3122 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3123 if(NULL == p_buf)
3124 {
3125 L2CAP_TRACE_ERROR0("l2cu_get_buffer_to_send() #2: No data to be sent");
3126 return (NULL);
3127 }
3128 }
3129
3130 if ( p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_TxComplete_Cb && (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) )
3131 (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
3132
3133
3134 l2cu_check_channel_congestion (p_ccb);
3135
3136 l2cu_set_acl_hci_header (p_buf, p_ccb);
3137
3138 return (p_buf);
3139 }
3140
3141 /******************************************************************************
3142 **
3143 ** Function l2cu_set_acl_hci_header
3144 **
3145 ** Description Set HCI handle for ACL packet
3146 **
3147 ** Returns None
3148 **
3149 *******************************************************************************/
l2cu_set_acl_hci_header(BT_HDR * p_buf,tL2C_CCB * p_ccb)3150 void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb)
3151 {
3152 UINT8 *p;
3153
3154 /* Set the pointer to the beginning of the data minus 4 bytes for the packet header */
3155 p = (UINT8 *)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
3156
3157 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3158 if ( (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) && (p_ccb->is_flushable))
3159 || ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_PKT) )
3160 {
3161 UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3162 }
3163 else
3164 {
3165 UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
3166 }
3167 #else
3168 UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3169 #endif
3170 #if (BLE_INCLUDED == TRUE)
3171 if (p_ccb->p_lcb->is_ble_link)
3172 {
3173 /* The HCI transport will segment the buffers. */
3174 if (p_buf->len > btu_cb.hcit_ble_acl_data_size)
3175 {
3176 UINT16_TO_STREAM (p, btu_cb.hcit_ble_acl_data_size);
3177 }
3178 else
3179 {
3180 UINT16_TO_STREAM (p, p_buf->len);
3181 }
3182 } /* (BLE_INCLUDED == TRUE) */
3183 else
3184 #endif
3185 {
3186
3187 /* The HCI transport will segment the buffers. */
3188 if (p_buf->len > btu_cb.hcit_acl_data_size)
3189 {
3190 UINT16_TO_STREAM (p, btu_cb.hcit_acl_data_size);
3191 }
3192 else
3193 {
3194 UINT16_TO_STREAM (p, p_buf->len);
3195 }
3196 }
3197 p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
3198 p_buf->len += HCI_DATA_PREAMBLE_SIZE;
3199 }
3200
3201 /******************************************************************************
3202 **
3203 ** Function l2cu_check_channel_congestion
3204 **
3205 ** Description check if any change in congestion status
3206 **
3207 ** Returns None
3208 **
3209 *******************************************************************************/
l2cu_check_channel_congestion(tL2C_CCB * p_ccb)3210 void l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
3211 {
3212 UINT16 q_count = p_ccb->xmit_hold_q.count;
3213
3214 #if (L2CAP_UCD_INCLUDED == TRUE)
3215 if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
3216 {
3217 q_count += p_ccb->p_lcb->ucd_out_sec_pending_q.count;
3218 }
3219 #endif
3220
3221 /* If the CCB queue limit is subject to a quota, check for congestion */
3222
3223 /* if this channel has outgoing traffic */
3224 if ((p_ccb->p_rcb)&&(p_ccb->buff_quota != 0))
3225 {
3226 /* If this channel was congested */
3227 if ( p_ccb->cong_sent )
3228 {
3229 /* If the channel is not congested now, tell the app */
3230 if (q_count <= (p_ccb->buff_quota / 2))
3231 {
3232 p_ccb->cong_sent = FALSE;
3233 if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
3234 {
3235 L2CAP_TRACE_DEBUG3 ("L2CAP - Calling CongestionStatus_Cb (FALSE), CID: 0x%04x xmit_hold_q.count: %u buff_quota: %u",
3236 p_ccb->local_cid, q_count, p_ccb->buff_quota);
3237
3238 /* Prevent recursive calling */
3239 l2cb.is_cong_cback_context = TRUE;
3240 (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, FALSE);
3241 l2cb.is_cong_cback_context = FALSE;
3242 }
3243 #if (L2CAP_UCD_INCLUDED == TRUE)
3244 else if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
3245 {
3246 if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
3247 {
3248 L2CAP_TRACE_DEBUG3 ("L2CAP - Calling UCD CongestionStatus_Cb (FALSE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
3249 p_ccb->p_lcb->ucd_out_sec_pending_q.count,
3250 p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
3251 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, FALSE );
3252 }
3253 }
3254 #endif
3255 }
3256 }
3257 else
3258 {
3259 /* If this channel was not congested but it is congested now, tell the app */
3260 if (q_count > p_ccb->buff_quota)
3261 {
3262 p_ccb->cong_sent = TRUE;
3263 if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
3264 {
3265 L2CAP_TRACE_DEBUG3 ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u",
3266 p_ccb->local_cid, q_count, p_ccb->buff_quota);
3267
3268 (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, TRUE);
3269 }
3270 #if (L2CAP_UCD_INCLUDED == TRUE)
3271 else if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
3272 {
3273 if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
3274 {
3275 L2CAP_TRACE_DEBUG3 ("L2CAP - Calling UCD CongestionStatus_Cb (TRUE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
3276 p_ccb->p_lcb->ucd_out_sec_pending_q.count,
3277 p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
3278 p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, TRUE );
3279 }
3280 }
3281 #endif
3282 }
3283 }
3284 }
3285 }
3286
3287