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