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