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