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