15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 1999-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  This file contains L2CAP utility functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h>
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_types.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcimsgs.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2cdefs.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_int.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcidefs.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btu.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_int.h"
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcidefs.h"
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_lcb
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look for an unused LCB
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          LCB address or NULL if none found
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_lcb->in_use)
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memset (p_lcb, 0, sizeof (tL2C_LCB));
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->in_use          = TRUE;
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state      = LST_DISCONNECTED;
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->handle          = HCI_INVALID_HANDLE;
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_flush_tout = 0xFFFF;
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->info_timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->idle_timeout    = l2cb.idle_timeout;
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->id              = 1;                     /* spec does not allow '0' */
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->is_bonding      = is_bonding;
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cb.num_links_active++;
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_adjust_allocation();
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no free LCB found */
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_update_lcb_4_bonding
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Mark the lcb for bonding. Used when bonding takes place on
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  an existing ACL connection.  (Pre-Lisbon devices)
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr);
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb)
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_DEBUG3 ("l2cu_update_lcb_4_bonding  BDA: %08x%04x is_bonding: %d",
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          (p_bd_addr[4]<<8)+p_bd_addr[5], is_bonding);
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->is_bonding = is_bonding;
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_lcb
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Release an LCB. All timers will be stopped, channels
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  dropped, buffers returned etc.
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_lcb (tL2C_LCB *p_lcb)
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->in_use     = FALSE;
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->is_bonding = FALSE;
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Stop timers */
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_stop_timer (&p_lcb->timer_entry);
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_stop_timer (&p_lcb->info_timer_entry);
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Release any unfinished L2CAP packet on this link */
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->p_hcit_rcv_acl)
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf(p_lcb->p_hcit_rcv_acl);
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->p_hcit_rcv_acl = NULL;
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BTM_SCO_INCLUDED == TRUE
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Release all SCO links */
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btm_remove_sco_links(p_lcb->remote_bd_addr);
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13998657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    if (p_lcb->sent_not_acked > 0)
14098657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    {
14198657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach#if (BLE_INCLUDED == TRUE)
14298657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        if (p_lcb->is_ble_link)
14398657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        {
14498657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            l2cb.controller_le_xmit_window += p_lcb->sent_not_acked;
14598657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs)
14698657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            {
14798657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach                l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
14898657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            }
14998657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        }
15098657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        else
15198657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach#endif
15298657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        {
15398657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            l2cb.controller_xmit_window += p_lcb->sent_not_acked;
15498657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            if (l2cb.controller_xmit_window > l2cb.num_lm_acl_bufs)
15598657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            {
15698657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach                l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
15798657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            }
15898657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        }
15998657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    }
16098657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->is_ble_link = FALSE;
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cb.is_ble_connecting = FALSE;
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int         xx;
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->p_fixed_ccbs[xx])
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->p_fixed_ccbs[xx] = NULL;
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Ensure no CCBs left on this LCB */
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_lcb->ccb_queue.p_first_ccb)
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_ccb (p_ccb);
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Tell BTM Acl management the link was removed */
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING))
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btm_acl_removed (p_lcb->remote_bd_addr);
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Release any held buffers */
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (p_lcb->link_xmit_data_q.p_first)
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q));
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* clean up any security pending UCD */
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_ucd_delete_sec_pending_q(p_lcb);
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Re-adjust flow control windows make sure it does not go negative */
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (l2cb.num_links_active >= 1)
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.num_links_active--;
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_adjust_allocation();
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check for ping outstanding */
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->p_echo_rsp_cb)
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb;
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Zero out the callback in case app immediately calls us again */
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->p_echo_rsp_cb = NULL;
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_cb) (L2CAP_PING_RESULT_NO_LINK);
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_bd_addr
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  remote BD address.
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched LCB, or NULL if no match
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_LCB  *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr)
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_conn_role
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Determine the desired role (master or slave) of a link.
255a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu**                  If it is the previous connected remote device, use the same
256a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu**                  role as previous used role.
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  If already got a slave link, this one must be a master. If
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  already got at least 1 link where we are the master, make this
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  also a master.
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          HCI_ROLE_MASTER or HCI_ROLE_SLAVE
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
264a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai XuUINT8 l2cu_get_conn_role (BD_ADDR bd_addr)
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
266a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu    UINT8 i;
267a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu    for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) {
268a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu        if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) &&
269a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu            (!bdcmp(bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
270a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu            L2CAP_TRACE_WARNING1 ("l2cu_get_conn_role %d",
271a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu                                  btm_cb.previous_connected_role[i]);
272a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu            return btm_cb.previous_connected_role[i];
273a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu        }
274a934f018b6c6a7eda4662a60f2f04828afc3ab77Zhihai Xu    }
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return l2cb.desire_role;
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_build_header
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Builds the L2CAP command packet header
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to allocated packet or NULL if no resources
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id)
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_buf)
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_ERROR0 ("l2cu_build_header - no buffer");
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_SEND_CMD_OFFSET;
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in HCI header - handle + pkt boundary */
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_lcb->handle | l2cb.non_flushable_pbf);
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD);
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD);
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->is_ble_link)
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID);
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP command header */
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, cmd);
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, id);
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len);
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_buf);
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_adj_id
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Checks for valid ID based on specified mask
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  and adjusts the id if invalid.
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask)
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((adj_mask & L2CAP_ADJ_ZERO_ID) && !p_lcb->id)
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->id++;
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_cmd_reject
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "command reject" message
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id,
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                UINT16 p1, UINT16 p2)
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  param_len;
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP packet header */
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED)
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 2;
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (reason == L2CAP_CMD_REJ_INVALID_CID)
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 4;
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 0;
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_lcb, (UINT16) (L2CAP_CMD_REJECT_LEN + param_len), L2CAP_CMD_REJECT, rem_id)) == NULL )
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer cmd_rej");
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, reason);
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (param_len >= 2)
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p1);
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (param_len >= 4)
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p2);
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_connect_req
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection request" message
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_connect_req (tL2C_CCB *p_ccb)
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ,
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    p_ccb->local_id)) == NULL)
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm);
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_connect_rsp
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection response" message
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status)
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (result == L2CAP_CONN_PENDING)
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if we already sent pending response */
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->flags & CCB_FLAG_SENT_PENDING)
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return;
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->flags |= CCB_FLAG_SENT_PENDING;
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf=l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, p_ccb->remote_id)) == NULL)
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_rsp");
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, result);
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, status);
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_reject_connection
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection response neg" message
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer. This function is called when there is no peer
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB (non-existant PSM or no resources).
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, UINT16 result)
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL )
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Local CID of 0   */
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, remote_cid);
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, result);
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Status of 0      */
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_req
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration request" message
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  cfg_len=0;
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcs_present)
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16) (L2CAP_CONFIG_REQ_LEN + cfg_len),
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL )
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->flags);                    /* Flags (continuation) */
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the options */
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_MTU);
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_MTU_OPTION_LEN);
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->mtu);
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FLUSH_OPTION_LEN);
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->flush_to);
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_QOS);
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_QOS_OPTION_LEN);
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.qos_flags);
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.service_type);
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.latency);
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCR);
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCR_OPTION_LEN);
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.mode);
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.tx_win_sz);
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.max_transmit);
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.rtrans_tout);
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mon_tout);
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mps);
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcs_present)
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCS);
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCS_OPTION_LEN);
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcs);
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_EXT_FLOW);
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.id);
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.stype);
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_rsp
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration response" message
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  cfg_len = 0;
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16)(L2CAP_CONFIG_RSP_LEN + cfg_len),
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL )
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for conn_req");
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->flags);           /* Flags (continuation) Must match request */
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->result);
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the options */
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_MTU);
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_MTU_OPTION_LEN);
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->mtu);
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FLUSH_OPTION_LEN);
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->flush_to);
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_QOS);
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_QOS_OPTION_LEN);
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.qos_flags);
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.service_type);
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.latency);
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCR);
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCR_OPTION_LEN);
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.mode);
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.tx_win_sz);
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.max_transmit);
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.rtrans_tout);
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.mon_tout);
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mps);
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_EXT_FLOW);
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.id);
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.stype);
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_rej
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration reject" message
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len)
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  len, cfg_len;
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p, *p_hci_len, *p_data_end;
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   cfg_code;
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_buf)
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for cfg_rej");
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_SEND_CMD_OFFSET;
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in HCI header - handle + pkt boundary */
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ()))
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Remember the HCI header length position, and save space for it */
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_hci_len = p;
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p += 2;
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP packet header */
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP command header */
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, L2CAP_CMD_CONFIG_RSP);
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, p_ccb->remote_id);
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CONFIG_RSP_LEN + rej_len);
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Flags = 0 (no continuation) */
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS);
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the rejected options */
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data_end = p_data + data_len;
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (p_data < p_data_end)
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_code = *p_data;
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len = *(p_data + 1);
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch (cfg_code & 0x7F)
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* skip known options */
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_MTU:
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_FLUSH_TOUT:
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_QOS:
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* unknown options; copy into rsp if not hints */
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            default:
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* sanity check option length */
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len)
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ((cfg_code & 0x80) == 0)
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* bad length; force loop exit */
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_data = p_data_end;
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    len = (UINT16) (p - p_hci_len - 2);
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p_hci_len, len);
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = len + 4;
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_disc_req
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "disconnect request" message
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf, *p_buf2;
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_ccb->local_id)) == NULL)
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for disc_req");
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Move all queued data packets to the LCB. In FCR mode, assume the higher
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       layer checks that all buffers are sent before disconnecting.
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_ccb->xmit_hold_q.p_first)
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf2 = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_set_acl_hci_header (p_buf2, p_ccb);
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2);
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_disc_rsp
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "disconnect response" message
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This function is passed the parameters for the disconnect
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  response instead of the CCB address, as it may be called
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to send a disconnect response when there is no CCB.
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid,
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                              UINT16 remote_cid)
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf=l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id)) == NULL)
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for disc_rsp");
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, local_cid);
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, remote_cid);
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_echo_req
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "echo request" message
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer. Note that we do not currently allow
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  data in the echo request.
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len)
9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_lcb, L2CAP_ADJ_ZERO_ID);  /* check for wrap to '0' */
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, (UINT16) (L2CAP_ECHO_REQ_LEN + data_len), L2CAP_CMD_ECHO_REQ, p_lcb->id)) == NULL)
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for echo_req");
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len)
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ARRAY_TO_STREAM  (p, p_data, data_len);
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_echo_rsp
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "echo response" message
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len)
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16   maxlen;
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Don't return data if it does not fit in ACL and L2CAP MTU */
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ?
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project               btu_cb.hcit_acl_data_size : (UINT16)GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID);
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    maxlen -= (UINT16)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN);
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len > maxlen)
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        data_len = 0;
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_lcb, (UINT16)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP, id)) == NULL)
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for echo_rsp");
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len)
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ARRAY_TO_STREAM  (p, p_data, data_len);
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_info_req
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "info request" message
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_info_req (tL2C_LCB *p_lcb, UINT16 info_type)
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* check for wrap and/or BRCM ID */
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->id)) == NULL)
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for info_req");
9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CAP_TRACE_EVENT1 ("l2cu_send_peer_info_req: type 0x%04x", info_type);
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, info_type);
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->w4_info_rsp = TRUE;
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_start_timer (&p_lcb->info_timer_entry, BTU_TTYPE_L2CAP_INFO, L2CAP_WAIT_INFO_RSP_TOUT);
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_info_rsp
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "info response" message
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type)
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16   len = L2CAP_INFO_RSP_LEN;
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_CONFORMANCE_TESTING == TRUE)
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS   | L2CAP_EXTFEA_STREAM_MODE |
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_UCD_RECEPTION )) )
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                           L2CAP_EXTFEA_NO_CRC |L2CAP_EXTFEA_FIXED_CHNLS |
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                           L2CAP_EXTFEA_UCD_RECEPTION )) )
10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE;
10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_FIXED_CHNL_ARRAY_SIZE;
10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_CONNLESS_MTU_INFO_SIZE;
10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id)) == NULL)
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no buffer for info_rsp");
10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, info_type);
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_CONFORMANCE_TESTING == TRUE)
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (l2cb.test_info_resp & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                  | L2CAP_EXTFEA_UCD_RECEPTION )) )
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (L2CAP_EXTFEA_SUPPORTED_MASK & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          | L2CAP_EXTFEA_UCD_RECEPTION )) )
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->is_ble_link)
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* optional data are not added for now */
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK);
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CONFORMANCE_TESTING == TRUE
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, l2cb.test_info_resp);
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS);
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK);
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memset (p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE);
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p[0] = L2CAP_FIXED_CHNL_SIG_BIT;
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION )
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT;
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            int xx;
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p[0] |= 1 << (xx + L2CAP_FIRST_FIXED_CHNL);
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_UCD_MTU);
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED);  /* 'not supported' */
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_enqueue_ccb
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      queue CCB by priority. The first CCB is highest priority and
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is served at first. The CCB is queued to an LLCB or an LCB.
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_enqueue_ccb (tL2C_CCB *p_ccb)
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_ccb1;
11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB_Q      *p_q = NULL;
11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find out which queue the channel is on
11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q = &p_ccb->p_lcb->ccb_queue;
11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (!p_ccb->in_use) || (p_q == NULL) )
11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_ERROR3 ("l2cu_enqueue_ccb  CID: 0x%04x ERROR in_use: %u  p_lcb: 0x%08x",
11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb);
11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CAP_TRACE_DEBUG2 ("l2cu_enqueue_ccb CID: 0x%04x  priority: %d",
11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->local_cid, p_ccb->ccb_priority);
11525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the queue is empty, we go at the front */
11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_q->p_first_ccb)
11555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_first_ccb  = p_q->p_last_ccb   = p_ccb;
11575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb1 = p_q->p_first_ccb;
11625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_ccb1 != NULL)
11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Insert new ccb at the end of the same priority. Lower number, higher priority */
11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->ccb_priority < p_ccb1->ccb_priority)
11675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Are we at the head of the queue ? */
11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb1 == p_q->p_first_ccb)
11705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_q->p_first_ccb = p_ccb;
11715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_ccb1->p_prev_ccb->p_next_ccb  = p_ccb;
11735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_next_ccb  = p_ccb1;
11755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_prev_ccb  = p_ccb1->p_prev_ccb;
11765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb1->p_prev_ccb = p_ccb;
11775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
11785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
11795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb1 = p_ccb1->p_next_ccb;
11815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If we are lower then anyone in the list, we go at the end */
11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_ccb1)
11855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* add new ccb at the end of the list */
11875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb->p_next_ccb = p_ccb;
11885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_next_ccb   = NULL;
11905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_prev_ccb   = p_q->p_last_ccb;
11915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb = p_ccb;
11925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
11965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Adding CCB into round robin service table of its LCB */
11975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
11985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if this is the first channel in this priority group */
12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
12015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Set the first channel to this CCB */
12035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
12045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Set the next serving channel in this group to this CCB */
12055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
12065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Initialize quota of this priority group based on its priority */
12075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
12085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* increase number of channels in this group */
12105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++;
12115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
12135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_dequeue_ccb
12195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      dequeue CCB from a queue
12215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          -
12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
12255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
12265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
12275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB_Q      *p_q = NULL;
12285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CAP_TRACE_DEBUG1 ("l2cu_dequeue_ccb  CID: 0x%04x", p_ccb->local_cid);
12305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find out which queue the channel is on
12325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
12335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
12345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q = &p_ccb->p_lcb->ccb_queue;
12355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL) )
12375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        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",
12395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q, p_q ? p_q->p_first_ccb : 0);
12405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
12415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
12445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Removing CCB from round robin service table of its LCB */
12455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
12465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* decrease number of channels in this priority group */
12485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--;
12495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if it was the last channel in the priority group */
12515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
12525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
12545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
12555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
12575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if it is the first channel of this group */
12595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb )
12605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
12615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb->p_next_ccb;
12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
12635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if it is the next serving channel of this group */
12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb )
12655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
12665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* simply, start serving from the first channel */
12675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb
12685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    = p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb;
12695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
12705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
12735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb == p_q->p_first_ccb)
12755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We are removing the first in a queue */
12775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_first_ccb = p_ccb->p_next_ccb;
12785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_q->p_first_ccb)
12805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_first_ccb->p_prev_ccb = NULL;
12815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
12825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb = NULL;
12835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb == p_q->p_last_ccb)
12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We are removing the last in a queue */
12875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_last_ccb = p_ccb->p_prev_ccb;
12885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_last_ccb->p_next_ccb = NULL;
12895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
12915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* In the middle of a chain. */
12935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb;
12945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb;
12955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
12985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
13015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_change_pri_ccb
13035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description
13055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          -
13075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
13095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
13105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->ccb_priority != priority)
13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If CCB is not the only guy on the queue */
13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) )
13155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CAP_TRACE_DEBUG0 ("Update CCB list in logical link");
13175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Remove CCB from queue and re-queue it at new priority */
13195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_dequeue_ccb (p_ccb);
13205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->ccb_priority = priority;
13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_enqueue_ccb (p_ccb);
13235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
13255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
13265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* If CCB is the only guy on the queue, no need to re-enqueue */
13285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* update only round robin service data */
13295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0;
13305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
13315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
13325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->ccb_priority = priority;
13345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
13365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
13375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
13385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1;
13395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
13415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
13435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
13455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_ccb
13475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function allocates a Channel Control Block and
13495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  attaches it to a link control block. The local CID
13505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is also assigned.
13515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB, or NULL if none
13535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
13555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
13565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
13585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_prev;
13595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CAP_TRACE_DEBUG1 ("l2cu_allocate_ccb: cid 0x%04x", cid);
13615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!l2cb.p_free_ccb_first)
13635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
13645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If a CID was passed in, use that, else take the first free one */
13665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cid == 0)
13675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.p_free_ccb_first;
13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
13705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
13725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_prev = NULL;
13745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID];
13765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb == l2cb.p_free_ccb_first)
13785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
13795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
13805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL; p_prev = p_prev->p_next_ccb)
13825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_prev->p_next_ccb == p_ccb)
13845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_prev->p_next_ccb = p_ccb->p_next_ccb;
13865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_ccb == l2cb.p_free_ccb_last)
13885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        l2cb.p_free_ccb_last = p_prev;
13895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
13915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
13925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
13935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_prev == NULL)
13945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
13955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CAP_TRACE_ERROR1 ("l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free list", cid);
13965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return NULL;
13975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
13985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
14025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->in_use = TRUE;
14045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Get a CID for the connection */
14065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_cid = L2CAP_BASE_APPL_CID + (UINT16)(p_ccb - l2cb.ccb_pool);
14075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb = p_lcb;
14095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_rcb = NULL;
14105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set priority then insert ccb into LCB queue (if we have an LCB) */
14125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW;
14135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb)
14155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_enqueue_ccb (p_ccb);
14165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* clear what peer wants to configure */
14185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->peer_cfg_bits = 0;
14195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in default values for configuration */
14215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO));
14225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO));
14235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in default values for local/peer configurations */
14255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.flush_to              = p_ccb->peer_cfg.flush_to              = L2CAP_DEFAULT_FLUSH_TO;
14265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.mtu                   = p_ccb->peer_cfg.mtu                   = L2CAP_DEFAULT_MTU;
14275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.service_type      = p_ccb->peer_cfg.qos.service_type      = L2CAP_DEFAULT_SERV_TYPE;
14285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.token_rate        = p_ccb->peer_cfg.qos.token_rate        = L2CAP_DEFAULT_TOKEN_RATE;
14295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size = L2CAP_DEFAULT_BUCKET_SIZE;
14305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.peak_bandwidth    = p_ccb->peer_cfg.qos.peak_bandwidth    = L2CAP_DEFAULT_PEAK_BANDWIDTH;
14315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.latency           = p_ccb->peer_cfg.qos.latency           = L2CAP_DEFAULT_LATENCY;
14325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.delay_variation   = p_ccb->peer_cfg.qos.delay_variation   = L2CAP_DEFAULT_DELAY;
14335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->bypass_fcs = 0;
14355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO));
14365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->peer_cfg_already_rejected = FALSE;
14375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fcr_cfg_tries         = L2CAP_MAX_FCR_CFG_TRIES;
14385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fcrb.ack_timer.param  = (TIMER_PARAM_TYPE)p_ccb;
14395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* if timer is running, remove it from timer list */
14415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->fcrb.ack_timer.in_use)
14425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btu_stop_quick_timer (&p_ccb->fcrb.ack_timer);
14435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fcrb.mon_retrans_timer.param  = (TIMER_PARAM_TYPE)p_ccb;
14455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific ++
14475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /*  CSP408639 Fix: When L2CAP send amp move channel request or receive
14485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
14495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * request -> Stop retrans/monitor timer -> Change channel state to CST_AMP_MOVING. */
14505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (p_ccb->fcrb.mon_retrans_timer.in_use)
14515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
14525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific --
14535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_stop_timer (p_ccb);
14555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.preferred_mode  = L2CAP_FCR_BASIC_MODE;        /* Default mode for channel is basic mode */
14575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.allowed_modes   = L2CAP_FCR_CHAN_OPT_BASIC;    /* Default mode for channel is basic mode */
14585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.fcr_rx_pool_id  = L2CAP_FCR_RX_POOL_ID;
14595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.fcr_tx_pool_id  = L2CAP_FCR_TX_POOL_ID;
14605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
14615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
14625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->max_rx_mtu                = L2CAP_MTU_SIZE;
14635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->tx_mps                    = GKI_get_pool_bufsize(HCI_ACL_POOL_ID) - 32;
14645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_init_q (&p_ccb->xmit_hold_q);
14665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->cong_sent    = FALSE;
14685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->buff_quota   = 2;                /* This gets set after config */
14695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If CCB was reserved Config_Done can already have some value */
14715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cid == 0)
14725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->config_done  = 0;
14735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
14745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_DEBUG2 ("l2cu_allocate_ccb: cid 0x%04x config_done:0x%x", cid, p_ccb->config_done);
14765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->chnl_state   = CST_CLOSED;
14795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->flags        = 0;
14805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
14815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
14825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
14845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->is_flushable = FALSE;
14855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
14865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
14885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->timer_entry.in_use = 0;
14895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_adjust_chnl_allocation ();
14915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_ccb);
14935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
14945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
14965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_start_post_bond_timer
14985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function starts the ACL Link inactivity timer after
15005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  dedicated bonding
15015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This timer can be longer than the normal link inactivity
15025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  timer for some platforms.
15035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          BOOLEAN  - TRUE if idle timer started or disconnect initiated
15055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                             FALSE if there's one or more pending CCB's exist
15065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
15085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_start_post_bond_timer (UINT16 handle)
15095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
15105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16    timeout;
15115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
15125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_lcb)
15145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (TRUE);
15155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->is_bonding = FALSE;
15175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Only start timer if no control blocks allocated */
15195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->ccb_queue.p_first_ccb != NULL)
15205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
15215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If no channels on the connection, start idle timeout */
15235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_CONNECTING) || (p_lcb->link_state == LST_DISCONNECTING) )
15245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->idle_timeout == 0)
15265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
15275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER))
15285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
15295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_state = LST_DISCONNECTING;
15305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                timeout = L2CAP_LINK_DISCONNECT_TOUT;
15315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
15325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
15335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                timeout = BT_1SEC_TIMEOUT;
15345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
15355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
15365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
15375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = L2CAP_BONDING_TIMEOUT;
15385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
15395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (timeout != 0xFFFF)
15415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
15425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (TRUE);
15445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (FALSE);
15475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
15485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
15505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_ccb
15525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function releases a Channel Control Block. The timer
15545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is stopped, any attached buffers freed, and the CCB is removed
15555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  from the link control block.
15565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
15585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
15605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_ccb (tL2C_CCB *p_ccb)
15615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
15625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = p_ccb->p_lcb;
15635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = p_ccb->p_rcb;
15645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CAP_TRACE_DEBUG2 ("l2cu_release_ccb: cid 0x%04x  in_use: %u", p_ccb->local_cid, p_ccb->in_use);
15665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If already released, could be race condition */
15685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_ccb->in_use)
15695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
15705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_rcb && (p_rcb->psm != p_rcb->real_psm))
15725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btm_sec_clr_service_by_psm(p_rcb->psm);
15745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1575ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
1576ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr);
1577ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
15785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Stop the timer */
15795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_stop_timer (&p_ccb->timer_entry);
15805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (p_ccb->xmit_hold_q.p_first)
15825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (GKI_dequeue (&p_ccb->xmit_hold_q));
15835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_cleanup (p_ccb);
15855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Channel may not be assigned to any LCB if it was just pre-reserved */
15875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_lcb) &&
15885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID)
15895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
15905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ||(p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID)
15915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
15925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         )
15935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       )
15945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_dequeue_ccb (p_ccb);
15965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Delink the CCB from the LCB */
15985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb = NULL;
15995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put the CCB back on the free pool */
16025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!l2cb.p_free_ccb_first)
16035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_first = p_ccb;
16055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last  = p_ccb;
16065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb     = NULL;
16075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb     = NULL;
16085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
16105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb  = NULL;
16125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb  = l2cb.p_free_ccb_last;
16135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last->p_next_ccb = p_ccb;
16145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last  = p_ccb;
16155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Flag as not in use */
16185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->in_use = FALSE;
16195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If no channels on the connection, start idle timeout */
16215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED))
16225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_lcb->ccb_queue.p_first_ccb)
16245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
16255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_no_dynamic_ccbs (p_lcb);
16265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
16275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
16285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
16295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Link is still active, adjust channel quotas. */
16305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_adjust_chnl_allocation ();
16315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
16325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
16365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_ccb_by_remote_cid
16385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active CCBs on a link for a match based
16405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  on the remote CID.
16415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched CCB, or NULL if no match
16435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
16455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid)
16465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
16475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
16485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If LCB is NULL, look through all active links */
16505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_lcb)
16515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
16535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
16555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
16575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid))
16585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_ccb);
16595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
16625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
16635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
16665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_rcb
16685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through the Registration Control Blocks for a free
16705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  one.
16715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to the RCB or NULL if not found
16735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
16755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_RCB *l2cu_allocate_rcb (UINT16 psm)
16765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
16775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
16785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      xx;
16795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
16815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_rcb->in_use)
16835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
16845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->in_use = TRUE;
16855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->psm    = psm;
16865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
16875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
16885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
16895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_rcb);
16905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
16915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no free RCB found */
16945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
16955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
16995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_rcb
17015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Mark an RCB as no longet in use
17035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
17055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
17075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_rcb (tL2C_RCB *p_rcb)
17085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rcb->in_use = FALSE;
17105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rcb->psm    = 0;
17115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_disconnect_chnl
17175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Disconnect a channel. Typically, this is due to either
17195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  receiving a bad configuration,  bad packet or max_retries expiring.
17205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
17225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_disconnect_chnl (tL2C_CCB *p_ccb)
17235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      local_cid = p_ccb->local_cid;
17255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (local_cid >= L2CAP_BASE_APPL_CID)
17275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        tL2CA_DISCONNECT_IND_CB   *p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
17295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING1 ("L2CAP - disconnect_chnl CID: 0x%04x", local_cid);
17315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_send_peer_disc_req (p_ccb);
17335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_ccb (p_ccb);
17355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_disc_cb)(local_cid, FALSE);
17375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
17395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* failure on the AMP channel, probably need to disconnect ACL */
17415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_ERROR1 ("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid);
17425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_rcb_by_psm
17495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through the Registration Control Blocks to see if
17515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  anyone registered to handle the PSM in question
17525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to the RCB or NULL if not found
17545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
17565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm)
17575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
17595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      xx;
17605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
17625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_rcb->in_use) && (p_rcb->psm == psm))
17645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_rcb);
17655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
17685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
17695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_peer_cfg_req
17755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when the peer sends us a "config request"
17775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
17785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
17795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Note:  Negotiation of the FCR channel type is handled internally,
17815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                         all others are passed to the upper layer.
17825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer,
17845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                          L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to
17855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              because parameters are unnacceptable from a specification
17865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              point of view.
17875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                          L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes
17885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              between the two devices, and shall be closed.
17895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
17915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
17925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  mtu_ok      = TRUE;
17945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  qos_type_ok = TRUE;
17955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  flush_to_ok = TRUE;
17965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  fcr_ok      = TRUE;
17975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    fcr_status;
17985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Ignore FCR parameters for basic mode */
18005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_cfg->fcr_present)
18015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
18025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the MTU that our peer can receive */
18045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
18055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Make sure MTU is at least the minimum */
18075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->mtu >= L2CAP_MIN_MTU)
18085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
18095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* In basic mode, limit the MTU to our buffer size */
18105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( (p_cfg->fcr_present == FALSE) && (p_cfg->mtu > L2CAP_MTU_SIZE) )
18115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_cfg->mtu = L2CAP_MTU_SIZE;
18125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Save the accepted value in case of renegotiation */
18145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.mtu = p_cfg->mtu;
18155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.mtu_present = TRUE;
18165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
18175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
18185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Illegal MTU value */
18195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
18205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->mtu = L2CAP_MIN_MTU;
18215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mtu_ok     = FALSE;
18225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
18235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload mtu from a previously accepted config request */
18255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.mtu_present)
18265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu_present = TRUE;
18285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu = p_ccb->peer_cfg.mtu;
18295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Verify that the flush timeout is a valid value (0 is illegal) */
18325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
18335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_cfg->flush_to)
18355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
18365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->flush_to = 0xFFFF;   /* Infinite retransmissions (spec default) */
18375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            flush_to_ok     = FALSE;
18385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
18395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Save the accepted value in case of renegotiation */
18405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
18415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.flush_to_present = TRUE;
18425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
18435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
18445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
18455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload flush_to from a previously accepted config request */
18475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.flush_to_present)
18485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->flush_to_present = TRUE;
18505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
18515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the QOS settings the the peer is using */
18545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
18555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Make sure service type is not a reserved value; otherwise let upper
18575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           layer decide if acceptable
18585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        */
18595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->qos.service_type <= GUARANTEED)
18605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
18615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.qos         = p_cfg->qos;
18625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.qos_present = TRUE;
18635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
18645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
18655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Illegal service type value */
18665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
18675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->qos.service_type = BEST_EFFORT;
18685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            qos_type_ok             = FALSE;
18695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
18705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload QOS from a previously accepted config request */
18725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.qos_present)
18735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->qos_present = TRUE;
18755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->qos         = p_ccb->peer_cfg.qos;
18765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((fcr_status = l2c_fcr_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_DISCONNECT)
18795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Notify caller to disconnect the channel (incompatible modes) */
18815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->result = L2CAP_CFG_FAILED_NO_REASON;
18825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
18835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_DISCONNECT);
18855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
18885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Return any unacceptable parameters */
18905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok)
18915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_adjust_out_mps (p_ccb);
18935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_OK);
18945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
18965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
18985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu_ok)
19005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->mtu_present = FALSE;
19015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (flush_to_ok)
19025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->flush_to_present = FALSE;
19035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (qos_type_ok)
19045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->qos_present = FALSE;
19055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (fcr_ok)
19065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->fcr_present = FALSE;
19075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_UNACCEPTABLE);
19095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
19115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
19145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_peer_cfg_rsp
19165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when the peer sends us a "config response"
19185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
19195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
19205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
19225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
19245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
19255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
19265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we wanted QoS and the peer sends us a positive response with QoS, use his values */
19275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_cfg->qos_present) && (p_ccb->our_cfg.qos_present) )
19285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos = p_cfg->qos;
19295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
19315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Save the retransmission and monitor timeout values */
19335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE)
19345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
19365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
19375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Calculate the max number of packets for which we can delay sending an ack */
19405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz)
19415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
19425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
19435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
19445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_DEBUG3 ("l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, max_held_acks: %d",
19465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks);
19475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
19495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
19515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_our_cfg_req
19535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when we send a "config request"
19555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
19565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
19575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
19595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
19615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
19625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
19635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb;
19645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      hci_flush_to;
19655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the QOS settings we are using for transmit */
19675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
19685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos_present = TRUE;
19705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos         = p_cfg->qos;
19715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
19745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Override FCR options if attempting streaming or basic */
19765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)
19775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
19785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
19795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* On BR/EDR, timer values are zero in config request */
19815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* On class 2 AMP, timer value in config request shall be non-0 processing time */
19825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*                 timer value in config response shall be greater than received processing time */
19835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
19845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE)
19865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0;
19875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Set the threshold to send acks (may be updated in the cfg response) */
19905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
19915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Include FCS option only if peer can handle it */
19935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC)
19945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* FCS check can be bypassed if peer also desires to bypass */
19965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS)
19975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR;
19985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
20005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->fcs_present = FALSE;
20015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
20035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
20055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.fcr.mode    = p_cfg->fcr.mode;
20085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
20095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check the flush timeout. If it is lower than the current one used */
20115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* then we need to adjust the flush timeout sent to the controller   */
20125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
20135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_cfg->flush_to == 0)||(p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH))
20155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* don't send invalid flush timeout */
20175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* SPEC: The sender of the Request shall specify its flush timeout value */
20185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*       if it differs from the default value of 0xFFFF                  */
20195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->flush_to_present = FALSE;
20205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
20225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->our_cfg.flush_to = p_cfg->flush_to;
20245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb = p_ccb->p_lcb;
20255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->flush_to < p_lcb->link_flush_tout)
20275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
20285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_flush_tout = p_cfg->flush_to;
20295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If the timeout is within range of HCI, set the flush timeout */
20315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8))
20325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
20335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* Convert flush timeout to 0.625 ms units, with round */
20345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
20355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to);
20365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
20375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
20385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
20415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
20445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_our_cfg_rsp
20465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when we send the peer a "config response"
20485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
20495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
20505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
20525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
20545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
20555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
20565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If peer wants QoS, we are allowed to change the values in a positive response */
20575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present) )
20585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->peer_cfg.qos = p_cfg->qos;
20595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
20605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->qos_present = FALSE;
20615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_adj_our_rsp_options (p_ccb, p_cfg);
20635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
20645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
20675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_device_reset
20695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when reset of the device is
20715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  completed.  For all active connection simulate HCI_DISC
20725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
20745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
20765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_device_reset (void)
20775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
20785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
20795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
20805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
20825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE))
20845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_hci_disc_comp (p_lcb->handle, (UINT8) -1);
20865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2088ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if (BLE_INCLUDED == TRUE)
2089ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    l2cb.is_ble_connecting = FALSE;
2090ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
20915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
20925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
20945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectextern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ;
20955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
20965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
20985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_create_conn
21005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initiates an acl connection via HCI
21025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if successful, FALSE if gki get buffer fails.
21045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
21065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb)
21075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
21085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int             xx;
21095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB        *p_lcb_cur = &l2cb.lcb_pool[0];
21105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BTM_SCO_INCLUDED == TRUE
21115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN         is_sco_active;
21125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
21135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
21155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_DEVICE_TYPE     dev_type;
21165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBLE_ADDR_TYPE      addr_type;
21175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
21195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (dev_type == BT_DEVICE_TYPE_BLE)
21215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21223aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach        if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
21233aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach            return FALSE;
21243aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach
21255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->ble_addr_type = addr_type;
21265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->is_ble_link   = TRUE;
21275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (l2cble_create_conn(p_lcb));
21295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
21315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If there is a connection where we perform as a slave, try to switch roles
21335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       for this connection */
21345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++)
21355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb_cur == p_lcb)
21375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
21385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb_cur->in_use) && (p_lcb_cur->link_role == HCI_ROLE_SLAVE))
21405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BTM_SCO_INCLUDED == TRUE
21435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* The LMP_switch_req shall be sent only if the ACL logical transport
21445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            is in active mode, when encryption is disabled, and all synchronous
21455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            logical transports on the same physical link are disabled." */
21465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Check if there is any SCO Active on this BD Address */
21485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            is_sco_active = btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr);
21495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CAP_TRACE_API1 ("l2cu_create_conn - btm_is_sco_active_by_bdaddr() is_sco_active = %s", \
21515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (is_sco_active == TRUE) ? "TRUE":"FALSE");
21525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (is_sco_active == TRUE)
21545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue; /* No Master Slave switch not allowed when SCO Active */
21555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
21565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21573aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach            if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures()))
21585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
21595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* mark this lcb waiting for switch to be completed and
21605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   start switch on the other one */
21615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH;
21625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_role  = HCI_ROLE_MASTER;
21635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (BTM_SwitchRole (p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) == BTM_CMD_STARTED)
21655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
21665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_ROLE_SWITCH_TOUT);
21675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    return (TRUE);
21685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
21695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
21705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->link_state = LST_CONNECTING;
21745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (l2cu_create_conn_after_switch (p_lcb));
21765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
21775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
21795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_num_hi_priority
21815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Gets the number of high priority channels.
21835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns
21855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
21875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 l2cu_get_num_hi_priority (void)
21885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
21895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       no_hi = 0;
21905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
21915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
21925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
21945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
21965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            no_hi++;
21985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
22005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return no_hi;
22015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
22025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
22055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_create_conn_after_switch
22075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initiates an acl connection via HCI
22095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  If switch required to create connection it is already done.
22105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if successful, FALSE if gki get buffer fails.
22125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
22145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb)
22165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
22175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
22185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_INQ_INFO    *p_inq_info;
22195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            page_scan_rep_mode;
22205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            page_scan_mode;
22215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16           clock_offset;
22225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            *p_features;
22235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16           num_acl = BTM_GetNumAclLinks();
22245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_lcb->remote_bd_addr);
22255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            no_hi_prio_chs = l2cu_get_num_hi_priority();
22265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_features = BTM_ReadLocalFeatures();
22285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CAP_TRACE_DEBUG4 ("l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d",
22305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding);
22315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* FW team says that we can participant in 4 piconets
22325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * typically 3 piconet + 1 for scanning.
22335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * We can enhance the code to count the number of piconets later. */
22345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( ((!l2cb.disallow_switch && (num_acl < 3)) || (p_lcb->is_bonding && (no_hi_prio_chs==0)))
22355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && HCI_SWITCH_SUPPORTED(p_features))
22365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
22375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
22385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
22395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->link_state = LST_CONNECTING;
22415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
22445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (clock_offset = tcs_wug_get_clk_offset( p_lcb->remote_bd_addr )) != 0 )
22455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
22465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R0;
22475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
22485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
22495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
22505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
22515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Check with the BT manager if details about remote device are known */
22545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL)
22555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
22565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
22575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_mode = p_inq_info->results.page_scan_mode;
22585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            clock_offset = (UINT16)(p_inq_info->results.clock_offset);
22595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
22605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
22615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
22625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* No info known. Use default settings */
22635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
22645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
22655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
22675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
22685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
22695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
22705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!btsnd_hcic_create_conn (p_lcb->remote_bd_addr,
22735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 HCI_PKT_TYPES_MASK_DM1 + HCI_PKT_TYPES_MASK_DH1,
22745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 page_scan_rep_mode,
22755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 page_scan_mode,
22765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 clock_offset,
22775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 allow_switch))
22785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
22805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for l2cu_create_conn");
22815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_lcb (p_lcb);
22825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
22835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
22845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
22865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
22875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK,
22905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     L2CAP_LINK_CONNECT_TOUT);
22915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (TRUE);
22935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
22945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
22975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_state
22995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
23015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  LCB state.
23025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to first matched LCB, or NULL if no match
23045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
23065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state)
23075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
23085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      i;
23095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
23105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
23125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
23135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->link_state == state))
23145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
23155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
23165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
23175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
23205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
23215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
23225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
23255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_lcb_disconnecting
23275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      On each active lcb, check if the lcb is in disconnecting
23295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  state, or if there are no ccb's on the lcb (implying
23305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    idle timeout is running), or if last ccb on the link
23315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    is in disconnecting state.
23325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if any of above conditions met, FALSE otherwise
23345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
23365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_lcb_disconnecting (void)
23375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
23385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb;
23395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
23405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      i;
23415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     status = FALSE;
23425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb = &l2cb.lcb_pool[0];
23445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
23465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
23475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->in_use)
23485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
23495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* no ccbs on lcb, or lcb is in disconnecting state */
23505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING))
23515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
23525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                status = TRUE;
23535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
23545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
23555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* only one ccb left on lcb */
23565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb)
23575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
23585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb = p_lcb->ccb_queue.p_first_ccb;
23595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((p_ccb->in_use) &&
23615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
23625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP)))
23635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
23645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = TRUE;
23655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
23665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
23675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
23685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
23695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
23715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
23725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
23755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_acl_priority
23775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Sets the transmission priority for a channel.
23795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  (For initial implementation only two values are valid.
23805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
23815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if a valid channel, else FALSE
23835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
23855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs)
23875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
23885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB            *p_lcb;
23895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               *pp;
23905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8                command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
23915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8                vs_param;
23925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    APPL_TRACE_EVENT1("SET ACL PRIORITY %d", priority);
23945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find the link control block for the acl channel */
23965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr)) == NULL)
23975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
23985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_SetAclPriority");
23995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
24005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
24015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (BTM_IS_BRCM_CONTROLLER())
24035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
24045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Called from above L2CAP through API; send VSC if changed */
24055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
24065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              /* Called because of a master/slave role switch; if high resend VSC */
24075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ( reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
24085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            pp = command;
24105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH : HCI_BRCM_ACL_PRIORITY_LOW;
24125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (pp, p_lcb->handle);
24145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT8_TO_STREAM  (pp, vs_param);
24155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
24175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Adjust lmp buffer allocation for this channel if priority changed */
24195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->acl_priority != priority)
24205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
24215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->acl_priority = priority;
24225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2c_link_adjust_allocation();
24235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
24245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
24255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
24265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return(TRUE);
24275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
24285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
24305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
24315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_non_flushable_pbf
24335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
24355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
24375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
24395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_set_non_flushable_pbf (BOOLEAN is_supported)
24405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
24415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (is_supported)
24425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
24435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
24445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
24455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
24465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
24475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
24495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_resubmit_pending_sec_req
24515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when required security procedures
24535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  are completed and any pending requests can be re-submitted.
24545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
24565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
24585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
24595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
24605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB        *p_lcb;
24615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_ccb;
24625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_next_ccb;
24635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int             xx;
24645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    L2CAP_TRACE_DEBUG1 ("l2cu_resubmit_pending_sec_req  p_bda: 0x%08x", p_bda);
24665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we are called with a BDA, only resubmit for that BDA */
24685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_bda)
24695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
24705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
24715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If we don't have one, this is an error */
24735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb)
24745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* For all channels, send the event through their FSMs */
24765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
24775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
24785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_next_ccb = p_ccb->p_next_ccb;
24795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
24805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
24815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
24825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
24835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CAP_TRACE_WARNING0 ("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
24855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
24865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
24875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
24885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
24895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* No BDA pasesed in, so check all links */
24905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
24915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->in_use)
24935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
24945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* For all channels, send the event through their FSMs */
24955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
24965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
24975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_next_ccb = p_ccb->p_next_ccb;
24985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
24995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
25005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
25015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
25025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CONFORMANCE_TESTING == TRUE
25065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
25075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_info_rsp_mask
25095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function allows the script wrapper to change the
25115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  info resp mask for conformance testing.
25125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB, or NULL if none
25145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
25165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_set_info_rsp_mask (UINT32 mask)
25175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cb.test_info_resp = mask;
25195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif  /* L2CAP_CONFORMANCE_TESTING */
25215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
25235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_adjust_out_mps
25255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Sets our MPS based on current controller capabilities
25275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
25295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
25315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_adjust_out_mps (tL2C_CCB *p_ccb)
25325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 packet_size;
25345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* on the tx side MTU is selected based on packet size of the controller */
25365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    packet_size = btm_get_max_packet_size (p_ccb->p_lcb->remote_bd_addr);
25375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN))
25395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
25405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* something is very wrong */
25415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_ERROR2 ("l2cu_adjust_out_mps bad packet size: %u  will use MPS: %u", packet_size, p_ccb->peer_cfg.fcr.mps);
25425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
25435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
25455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
25465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
25475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We try to negotiate MTU that each packet can be split into whole
25495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        number of max packets.  For example if link is 1.2 max packet size is 339 bytes.
25505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        At first calculate how many whole packets it is.  MAX L2CAP is 1691 + 4 overhead.
25515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        1695, that will be 5 Dh5 packets.  Now maximum L2CAP packet is
25525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
25535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        For EDR 2.0 packet size is 1027.  So we better send RFCOMM packet as 1 3DH5 packet
25555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        1 * 1027 = 1027.  Minus 4 bytes L2CAP header 1023.  */
25565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->peer_cfg.fcr.mps >= packet_size)
25575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
25585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
25595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
25605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_DEBUG3 ("l2cu_adjust_out_mps use %d   Based on peer_cfg.fcr.mps: %u  packet_size: %u",
25625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
25635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
25685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_initialize_fixed_ccb
25705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Initialize a fixed channel's CCB
25725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE or FALSE
25745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
25765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr)
25775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
25795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
25805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we already have a CCB, then simply return */
25825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL)
25835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (TRUE);
25845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_ccb = l2cu_allocate_ccb (NULL, 0)) == NULL)
25865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
25875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2588ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    btu_stop_timer(&p_lcb->timer_entry);
2589ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
25905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set CID for the connection */
25915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_cid  = fixed_cid;
25925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->remote_cid = fixed_cid;
25935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_init_q (&p_ccb->xmit_hold_q);
25955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->is_flushable = FALSE;
25975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->timer_entry.param  = (TIMER_PARAM_TYPE)p_ccb;
25995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_fcr)
26025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Set the FCR parameters. For now, we will use default pools */
26045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr;
26055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.fcr_rx_pool_id  = HCI_ACL_POOL_ID;
26075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.fcr_tx_pool_id  = HCI_ACL_POOL_ID;
26085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
26095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
26105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3;
26125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Link ccb to lcb and lcb to ccb */
26155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
26165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb = p_lcb;
26175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* There is no configuration, so if the link is up, the channel is up */
26195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->link_state == LST_CONNECTED)
26205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->chnl_state = CST_OPEN;
26215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set the default idle timeout value to use */
26235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fixed_chnl_idle_tout = l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
26245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
26255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (TRUE);
26265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
26295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_no_dynamic_ccbs
26315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Handles the case when there are no more dynamic CCBs. If there
26335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  are any fixed CCBs, start the longest of the fixed CCB timeouts,
26345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  otherwise start the default link idle timeout or disconnect.
26355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
26375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
26395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
26405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
26415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_STATUS     rc;
26425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          timeout = p_lcb->idle_timeout;
26435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
26455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
26465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
26485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_lcb->p_fixed_ccbs[xx] != NULL) && (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout > timeout) )
26505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout;
26515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
26535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the link is pairing, do not mess with the timeouts */
26555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->is_bonding)
26565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
26575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (timeout == 0)
26595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_DEBUG0 ("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
26615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
26635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (rc == BTM_CMD_STARTED)
26645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
26655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
26665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = L2CAP_LINK_DISCONNECT_TOUT;
26675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (rc == BTM_SUCCESS)
26695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
26705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* BTM SEC will make sure that link is release (probably after pairing is done) */
26715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
26725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = 0xFFFF;
26735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if ( (p_lcb->is_bonding)
26755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            &&   (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) )
26765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
26775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
26785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = L2CAP_LINK_DISCONNECT_TOUT;
26795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
26815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
26825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* probably no buffer to send disconnect */
26835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = BT_1SEC_TIMEOUT;
26845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (timeout != 0xFFFF)
26885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_DEBUG1 ("l2cu_no_dynamic_ccbs() starting IDLE timeout: %d", timeout);
26905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
26915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
26935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btu_stop_timer(&p_lcb->timer_entry);
26955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
26995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
27005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_fixed_chnl_resp
27025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      handle a fixed channel response (or lack thereof)
27045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  if the link failed, or a fixed channel response was
27055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  not received, the bitfield is all zeros.
27065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
27085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
27095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
27105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int     xx;
27115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BLE_INCLUDED == TRUE
27125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  reason = (p_lcb->is_ble_link ) ? 1 : 0;
27135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
27145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 reason =0;
27155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
27165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Tell all registered fixed channels about the connection */
27185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
27195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
27205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
27215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
27225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
27235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
27245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_lcb->p_fixed_ccbs[xx])
27255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
27265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason);
27285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2729ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            else
27305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
27315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
2732ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
2733ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if (p_lcb->p_fixed_ccbs[xx])
2734ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
2735ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
2736ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    p_lcb->p_fixed_ccbs[xx] = NULL;
2737ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
27385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
27395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
27405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
27415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
27425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
27435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
27455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
27465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_ble_par_req
27485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send a BLE parameter update request message
27505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
27515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
27535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
27555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout)
27565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
27575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
27585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
27595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
27615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
27625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id (p_lcb, L2CAP_ADJ_ID);
27635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN, L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id)) == NULL )
27655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
27665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("l2cu_send_peer_ble_par_req - no buffer");
27675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
27685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
27695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
27715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
27725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, min_int);
27745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, max_int);
27755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, latency);
27765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, timeout);
27775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
27795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
27805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
27825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_ble_par_rsp
27845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send a BLE parameter update response message
27865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
27875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
27895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
27915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id)
27925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
27935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
27945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
27955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN, L2CAP_CMD_BLE_UPDATE_RSP, rem_id)) == NULL )
27975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
27985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_WARNING0 ("l2cu_send_peer_ble_par_rsp - no buffer");
27995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
28005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
28035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
28045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, reason);
28065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
28085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
28095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* BLE_INCLUDED == TRUE */
28115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
28145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Functions used by both Full and Light Stack
28155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project********************************************************************************/
28165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
28185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_handle
28205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
28225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  HCI handle.
28235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched LCB, or NULL if no match
28255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
28275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_LCB  *l2cu_find_lcb_by_handle (UINT16 handle)
28285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
28295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
28305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
28315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
28335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
28345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->handle == handle))
28355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
28375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
28415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
28425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
28435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
28455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_ccb_by_cid
28475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active CCBs on a link for a match based
28495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  on the local CID. If passed the link pointer is NULL, all
28505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  active links are searched.
28515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched CCB, or NULL if no match
28535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
28555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid)
28565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
28575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb = NULL;
28585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
28595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 xx;
28605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
28615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (local_cid >= L2CAP_BASE_APPL_CID)
28635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
28645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* find the associated CCB by "index" */
28655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        local_cid -= L2CAP_BASE_APPL_CID;
28665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (local_cid >= MAX_L2CAP_CHANNELS)
28685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
28695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.ccb_pool + local_cid;
28715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* make sure the CCB is in use */
28735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_ccb->in_use)
28745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = NULL;
28765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* make sure it's for the same LCB */
28785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (p_lcb && p_lcb != p_ccb->p_lcb)
28795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = NULL;
28815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
28845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
28855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
28865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* searching fixed channel */
28875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.ccb_pool;
28885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ )
28895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_ccb->local_cid == local_cid)
28915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              &&(p_ccb->in_use)
28925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              &&(p_lcb == p_ccb->p_lcb))
28935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
28945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
28955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb++;
28965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( xx >= MAX_L2CAP_CHANNELS )
28985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
28995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
29005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
29015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_ccb);
29035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
29045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
29065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
29085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_channel_in_rr
29105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next channel to send on a link. It also adjusts the
29125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB queue to do a basic priority and round-robin scheduling.
29135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB or NULL
29155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
29175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb)
29185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
29195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_serve_ccb = NULL;
29205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
29215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i, j;
29235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* scan all of priority until finding a channel to serve */
29255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY)&&(!p_serve_ccb); i++ )
29265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
29275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* scan all channel within serving priority group until finding a channel to serve */
29285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb)&&(!p_serve_ccb); j++)
29295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
29305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* scaning from next serving channel */
29315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
29325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (!p_ccb)
29345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
29355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CAP_TRACE_ERROR1("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
29365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return NULL;
29375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
29385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            L2CAP_TRACE_DEBUG3("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
29405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                p_ccb->ccb_priority, p_ccb->local_cid, p_ccb->xmit_hold_q.count );
29415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* store the next serving channel */
29435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* this channel is the last channel of its priority group */
29445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (( p_ccb->p_next_ccb == NULL )
29455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              ||( p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority ))
29465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
29475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* next serving channel is set to the first channel in the group */
29485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_first_ccb;
29495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
29505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
29515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
29525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* next serving channel is set to the next channel in the group */
29535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
29545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
29555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->chnl_state != CST_OPEN)
29575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue;
29585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* eL2CAP option in use */
29605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
29615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
29625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
29635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
29645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( p_ccb->fcrb.retrans_q.count == 0 )
29665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
29675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->xmit_hold_q.count == 0 )
29685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
29695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* If using the common pool, should be at least 10% free. */
29715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
29725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
29735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* If in eRTM mode, check for window closure */
29755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
29765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
29775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
29785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
29795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
29805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
29815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->xmit_hold_q.count == 0)
29825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
29835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
29845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* found a channel to serve */
29865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_serve_ccb = p_ccb;
29875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* decrease quota of its priority group */
29885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_serv[p_lcb->rr_pri].quota--;
29895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
29905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if there is no more quota of the priority group or no channel to have data to send */
29925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0)||(!p_serve_ccb))
29935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
29945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* serve next priority group */
29955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
29965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* initialize its quota */
29975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
29985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
29995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
30005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_serve_ccb)
30025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
30035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_TRACE_DEBUG3("RR service pri=%d, quota=%d, lcid=0x%04x",
30045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_serve_ccb->ccb_priority,
30055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
30065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_serve_ccb->local_cid );
30075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
30085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_serve_ccb;
30105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
30115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
30135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
30155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_channel
30175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next channel to send on a link bassed on priority
30195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  scheduling.
30205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB or NULL
30225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
30245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
30255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
30265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
30275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Get the first CCB with data to send.
30295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
30305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
30315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
30325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->chnl_state != CST_OPEN)
30335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
30345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
30365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
30375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->fcrb.retrans_q.count != 0)
30395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return p_ccb;
30405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->xmit_hold_q.count == 0)
30425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
30435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If using the common pool, should be at least 10% free. */
30455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
30465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
30475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If in eRTM mode, check for window closure */
30495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
30505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
30515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If here, we found someone */
30535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return p_ccb;
30545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
30555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
30575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
30585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
30595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
30615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_buffer_to_send
30635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next buffer to send on a link. It also adjusts the
30655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB queue to do a basic priority and round-robin scheduling.
30665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to buffer or NULL
30685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
30705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
30715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
30725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
30735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR      *p_buf;
30745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Highest priority are fixed channels */
30765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
30775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
30785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
30805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
30815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL)
30825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
30835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* eL2CAP option in use */
30855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
30865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
30875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
30885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue;
30895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* No more checks needed if sending from the reatransmit queue */
30915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->fcrb.retrans_q.count == 0)
30925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
30935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->xmit_hold_q.count == 0)
30945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
30955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If using the common pool, should be at least 10% free. */
30975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
30985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
30995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If in eRTM mode, check for window closure */
31015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
31025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
31035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) != NULL)
31065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
31075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_set_acl_hci_header (p_buf, p_ccb);
31085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_buf);
31095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
31115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
31125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
31135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->xmit_hold_q.count != 0)
31145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
31155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3116ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if(NULL == p_buf)
3117ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
3118ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    L2CAP_TRACE_ERROR0("l2cu_get_buffer_to_send: No data to be sent");
3119ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    return (NULL);
3120ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
31215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_set_acl_hci_header (p_buf, p_ccb);
31225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_buf);
31235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
31255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
31265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
31275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
31295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* get next serving channel in round-robin */
31305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb  = l2cu_get_next_channel_in_rr( p_lcb );
31315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
31325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb  = l2cu_get_next_channel( p_lcb );
31335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
31345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Return if no buffer */
31365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb == NULL)
31375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
31385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
31405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
31415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL)
31425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (NULL);
31435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
31445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
31455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
31465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3147ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if(NULL == p_buf)
3148ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
3149ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            L2CAP_TRACE_ERROR0("l2cu_get_buffer_to_send() #2: No data to be sent");
3150ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            return (NULL);
3151ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
31525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
31535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_TxComplete_Cb && (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) )
31555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
31565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_check_channel_congestion (p_ccb);
31595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_set_acl_hci_header (p_buf, p_ccb);
31615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_buf);
31635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
31645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
31665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_acl_hci_header
31685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Set HCI handle for ACL packet
31705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
31725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
31745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb)
31755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
31765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p;
31775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set the pointer to the beginning of the data minus 4 bytes for the packet header */
31795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
31805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
31825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) && (p_ccb->is_flushable))
31835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            || ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_PKT) )
31845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
31855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
31865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
31875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
31885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
31895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
31905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
31915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
31925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
31935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
31945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
31955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb->is_ble_link)
31965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
31975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The HCI transport will segment the buffers. */
31985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf->len > btu_cb.hcit_ble_acl_data_size)
31995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, btu_cb.hcit_ble_acl_data_size);
32015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
32035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, p_buf->len);
32055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    } /* (BLE_INCLUDED == TRUE) */
32075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
32085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
32095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The HCI transport will segment the buffers. */
32125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf->len > btu_cb.hcit_acl_data_size)
32135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, btu_cb.hcit_acl_data_size);
32155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
32175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, p_buf->len);
32195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
32215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
32225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len    += HCI_DATA_PREAMBLE_SIZE;
32235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
32245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
32265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_check_channel_congestion
32285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      check if any change in congestion status
32305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
32325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
32345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
32355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
32365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 q_count = p_ccb->xmit_hold_q.count;
32375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
32395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
32405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        q_count += p_ccb->p_lcb->ucd_out_sec_pending_q.count;
32425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
32435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
32445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the CCB queue limit is subject to a quota, check for congestion */
32465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* if this channel has outgoing traffic */
32485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_ccb->p_rcb)&&(p_ccb->buff_quota != 0))
32495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If this channel was congested */
32515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( p_ccb->cong_sent )
32525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* If the channel is not congested now, tell the app */
32545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (q_count <= (p_ccb->buff_quota / 2))
32555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
32565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->cong_sent = FALSE;
32575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
32585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
32595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    L2CAP_TRACE_DEBUG3 ("L2CAP - Calling CongestionStatus_Cb (FALSE), CID: 0x%04x  xmit_hold_q.count: %u  buff_quota: %u",
32605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      p_ccb->local_cid, q_count, p_ccb->buff_quota);
32615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* Prevent recursive calling */
32635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    l2cb.is_cong_cback_context = TRUE;
32645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, FALSE);
32655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    l2cb.is_cong_cback_context = FALSE;
32665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
32675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
32685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
32695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
32705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
32715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
32725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        L2CAP_TRACE_DEBUG3 ("L2CAP - Calling UCD CongestionStatus_Cb (FALSE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
32735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->p_lcb->ucd_out_sec_pending_q.count,
32745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
32755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, FALSE );
32765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
32775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
32785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
32795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
32805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
32825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* If this channel was not congested but it is congested now, tell the app */
32845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (q_count > p_ccb->buff_quota)
32855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
32865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->cong_sent = TRUE;
32875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
32885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
32895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    L2CAP_TRACE_DEBUG3 ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u",
32905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->local_cid, q_count, p_ccb->buff_quota);
32915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, TRUE);
32935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
32945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
32955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
32965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
32975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
32985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
32995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        L2CAP_TRACE_DEBUG3 ("L2CAP - Calling UCD CongestionStatus_Cb (TRUE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
33005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->p_lcb->ucd_out_sec_pending_q.count,
33015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
33025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, TRUE );
33035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
33045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
33055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
33065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
33075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
33085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
33095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
33105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3311