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