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