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"
3963471e74f8e56d7daa8a5b2fda8ddbe95df33696Mike J. Chen#include "bd.h"
408fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#include "bt_utils.h"
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_lcb
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look for an unused LCB
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          LCB address or NULL if none found
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
518fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi BattatL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport)
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_lcb->in_use)
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memset (p_lcb, 0, sizeof (tL2C_LCB));
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->in_use          = TRUE;
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state      = LST_DISCONNECTED;
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->handle          = HCI_INVALID_HANDLE;
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_flush_tout = 0xFFFF;
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->info_timer_entry.param = (TIMER_PARAM_TYPE)p_lcb;
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->idle_timeout    = l2cb.idle_timeout;
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->id              = 1;                     /* spec does not allow '0' */
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->is_bonding      = is_bonding;
7392ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth#if (BLE_INCLUDED == TRUE)
748fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            p_lcb->transport       = transport;
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7692ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            if (transport == BT_TRANSPORT_LE)
7792ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            {
7892ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2cb.num_ble_links_active++;
7992ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2c_ble_link_adjust_allocation();
8092ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            }
8192ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            else
8292ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth#endif
8392ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            {
8492ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2cb.num_links_active++;
8592ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2c_link_adjust_allocation();
8692ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            }
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no free LCB found */
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_update_lcb_4_bonding
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Mark the lcb for bonding. Used when bonding takes place on
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  an existing ACL connection.  (Pre-Lisbon devices)
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1078fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    tL2C_LCB    *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR);
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb)
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
111a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_update_lcb_4_bonding  BDA: %08x%04x is_bonding: %d",
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          (p_bd_addr[4]<<8)+p_bd_addr[5], is_bonding);
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->is_bonding = is_bonding;
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_lcb
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Release an LCB. All timers will be stopped, channels
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  dropped, buffers returned etc.
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_lcb (tL2C_LCB *p_lcb)
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->in_use     = FALSE;
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->is_bonding = FALSE;
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Stop timers */
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_stop_timer (&p_lcb->timer_entry);
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_stop_timer (&p_lcb->info_timer_entry);
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Release any unfinished L2CAP packet on this link */
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->p_hcit_rcv_acl)
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf(p_lcb->p_hcit_rcv_acl);
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->p_hcit_rcv_acl = NULL;
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BTM_SCO_INCLUDED == TRUE
1478fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if (BLE_INCLUDED == TRUE)
1488fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
1498fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
1508fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        /* Release all SCO links */
1518fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        btm_remove_sco_links(p_lcb->remote_bd_addr);
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15498657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    if (p_lcb->sent_not_acked > 0)
15598657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    {
15698657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach#if (BLE_INCLUDED == TRUE)
1578fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_LE)
15898657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        {
15998657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            l2cb.controller_le_xmit_window += p_lcb->sent_not_acked;
16098657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs)
16198657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            {
16298657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach                l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
16398657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            }
16498657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        }
16598657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        else
16698657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach#endif
16798657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        {
16898657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            l2cb.controller_xmit_window += p_lcb->sent_not_acked;
16998657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            if (l2cb.controller_xmit_window > l2cb.num_lm_acl_bufs)
17098657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            {
17198657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach                l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
17298657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            }
17398657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        }
17498657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    }
17598657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cb.is_ble_connecting = FALSE;
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int         xx;
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->p_fixed_ccbs[xx])
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->p_fixed_ccbs[xx] = NULL;
1908fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
1948fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Ensure no CCBs left on this LCB */
2005738f83aeb59361a0a2eda2460113f6dc919427The 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)
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_ccb (p_ccb);
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Tell BTM Acl management the link was removed */
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING))
2078fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if (BLE_INCLUDED == TRUE)
2088fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        btm_acl_removed (p_lcb->remote_bd_addr, p_lcb->transport);
2098fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#else
2108fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_BR_EDR);
2118fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Release any held buffers */
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (p_lcb->link_xmit_data_q.p_first)
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q));
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* clean up any security pending UCD */
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_ucd_delete_sec_pending_q(p_lcb);
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22192ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth#if BLE_INCLUDED == TRUE
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Re-adjust flow control windows make sure it does not go negative */
22392ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    if (p_lcb->transport == BT_TRANSPORT_LE)
22492ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    {
22592ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        if (l2cb.num_ble_links_active >= 1)
22692ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            l2cb.num_ble_links_active--;
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22892ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        l2c_ble_link_adjust_allocation();
22992ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    }
23092ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    else
23192ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth#endif
23292ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    {
23392ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        if (l2cb.num_links_active >= 1)
23492ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            l2cb.num_links_active--;
23592ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth
23692ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        l2c_link_adjust_allocation();
23792ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    }
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check for ping outstanding */
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->p_echo_rsp_cb)
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb;
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Zero out the callback in case app immediately calls us again */
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->p_echo_rsp_cb = NULL;
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_cb) (L2CAP_PING_RESULT_NO_LINK);
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/*******************************************************************************
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_bd_addr
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  remote BD address.
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched LCB, or NULL if no match
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2628fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi BattatL2C_LCB  *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport)
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2698fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if ((p_lcb->in_use) &&
2708fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if BLE_INCLUDED == TRUE
2718fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            p_lcb->transport == transport &&
2728fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
2738fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_conn_role
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Determine the desired role (master or slave) of a link.
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  If already got a slave link, this one must be a master. If
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  already got at least 1 link where we are the master, make this
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  also a master.
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          HCI_ROLE_MASTER or HCI_ROLE_SLAVE
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2958fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi BattaUINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb)
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return l2cb.desire_role;
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3028fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Function         l2c_is_cmd_rejected
3038fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
3048fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Description      Checks if cmd_code is command or response
3058fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**                  If a command it will be rejected per spec.
3068fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**                  This function is used when a illegal packet length is detected
3078fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
3088fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Returns          BOOLEAN - TRUE if cmd_code is a command and it is rejected,
3098fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**                            FALSE if response code. (command not rejected)
3108fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
3118fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta*******************************************************************************/
3128fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi BattaBOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb)
3138fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta{
3148fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    switch(cmd_code)
3158fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
3168fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_CONN_REQ:
3178fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_CONFIG_REQ:
3188fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_DISC_REQ:
3198fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_ECHO_REQ:
3208fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_INFO_REQ:
3218fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_AMP_CONN_REQ:
3228fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_AMP_MOVE_REQ:
3238fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_BLE_UPDATE_REQ:
3248fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, L2CAP_DEFAULT_MTU, 0);
325a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("Dumping first Command (%d)", cmd_code);
3268fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return TRUE;
3278fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
3288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    default:    /* Otherwise a response */
3298fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return FALSE;
3308fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
3318fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta}
3328fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
3338fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta/*******************************************************************************
3348fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_build_header
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Builds the L2CAP command packet header
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to allocated packet or NULL if no resources
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id)
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_buf)
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
349a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("l2cu_build_header - no buffer");
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_SEND_CMD_OFFSET;
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in HCI header - handle + pkt boundary */
358eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#if (BLE_INCLUDED == TRUE)
359eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    if (p_lcb->transport == BT_TRANSPORT_LE)
360eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    {
361eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
362eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    }
363eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    else
364eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#endif
365eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    {
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
367eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, p_lcb->handle | l2cb.non_flushable_pbf);
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
369eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
371eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    }
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD);
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD);
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
3778fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (p_lcb->transport == BT_TRANSPORT_LE)
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID);
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP command header */
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, cmd);
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, id);
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len);
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_buf);
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_adj_id
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Checks for valid ID based on specified mask
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  and adjusts the id if invalid.
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_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask)
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((adj_mask & L2CAP_ADJ_ZERO_ID) && !p_lcb->id)
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->id++;
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_cmd_reject
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "command reject" message
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id,
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                UINT16 p1, UINT16 p2)
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  param_len;
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP packet header */
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED)
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 2;
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (reason == L2CAP_CMD_REJ_INVALID_CID)
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 4;
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 0;
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4385738f83aeb59361a0a2eda2460113f6dc919427The 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 )
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
440a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer cmd_rej");
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, reason);
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (param_len >= 2)
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p1);
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (param_len >= 4)
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p2);
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_connect_req
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection request" message
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_connect_req (tL2C_CCB *p_ccb)
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ,
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    p_ccb->local_id)) == NULL)
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
483a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm);
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_connect_rsp
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection response" message
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, UINT16 result, UINT16 status)
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (result == L2CAP_CONN_PENDING)
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if we already sent pending response */
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->flags & CCB_FLAG_SENT_PENDING)
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return;
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->flags |= CCB_FLAG_SENT_PENDING;
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5215738f83aeb59361a0a2eda2460113f6dc919427The 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)
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
523a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_rsp");
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, result);
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, status);
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_reject_connection
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection response neg" message
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer. This function is called when there is no peer
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB (non-existant PSM or no resources).
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_reject_connection (tL2C_LCB *p_lcb, UINT16 remote_cid, UINT8 rem_id, UINT16 result)
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL )
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
557a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Local CID of 0   */
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, remote_cid);
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, result);
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Status of 0      */
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_req
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration request" message
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  cfg_len=0;
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcs_present)
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16) (L2CAP_CONFIG_REQ_LEN + cfg_len),
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL )
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
609a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->flags);                    /* Flags (continuation) */
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the options */
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_MTU);
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_MTU_OPTION_LEN);
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->mtu);
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FLUSH_OPTION_LEN);
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->flush_to);
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_QOS);
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_QOS_OPTION_LEN);
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.qos_flags);
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.service_type);
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.latency);
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCR);
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCR_OPTION_LEN);
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.mode);
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.tx_win_sz);
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.max_transmit);
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.rtrans_tout);
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mon_tout);
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mps);
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcs_present)
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCS);
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCS_OPTION_LEN);
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcs);
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_EXT_FLOW);
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.id);
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.stype);
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_rsp
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration response" message
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  cfg_len = 0;
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (UINT16)(L2CAP_CONFIG_RSP_LEN + cfg_len),
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL )
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
709a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->flags);           /* Flags (continuation) Must match request */
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->result);
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the options */
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_MTU);
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_MTU_OPTION_LEN);
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->mtu);
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FLUSH_OPTION_LEN);
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->flush_to);
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_QOS);
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_QOS_OPTION_LEN);
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.qos_flags);
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.service_type);
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.latency);
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCR);
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCR_OPTION_LEN);
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.mode);
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.tx_win_sz);
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.max_transmit);
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.rtrans_tout);
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.mon_tout);
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mps);
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_EXT_FLOW);
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.id);
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.stype);
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_rej
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration reject" message
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len)
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7838fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    BT_HDR  *p_buf;
7848fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    UINT16  len, cfg_len, buf_space, len1;
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p, *p_hci_len, *p_data_end;
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   cfg_code;
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
788a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", data_len, rej_len);
7898fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
7908fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
7918fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN;
7928fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    len1 = 0xFFFF - len;
7938fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (rej_len > len1)
7948fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
795a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("L2CAP - cfg_rej pkt size exceeds buffer design max limit.");
7968fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return;
7978fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
7988fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
7998fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    p_buf = (BT_HDR *)GKI_getbuf (len + rej_len);
8008fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_buf)
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
803a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("L2CAP - no buffer for cfg_rej");
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_SEND_CMD_OFFSET;
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in HCI header - handle + pkt boundary */
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ()))
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Remember the HCI header length position, and save space for it */
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_hci_len = p;
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p += 2;
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP packet header */
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP command header */
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, L2CAP_CMD_CONFIG_RSP);
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, p_ccb->remote_id);
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CONFIG_RSP_LEN + rej_len);
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Flags = 0 (no continuation) */
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS);
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8408fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    buf_space = rej_len;
8418fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the rejected options */
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data_end = p_data + data_len;
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (p_data < p_data_end)
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_code = *p_data;
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len = *(p_data + 1);
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch (cfg_code & 0x7F)
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* skip known options */
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_MTU:
8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_FLUSH_TOUT:
8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_QOS:
8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* unknown options; copy into rsp if not hints */
8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            default:
8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* sanity check option length */
8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len)
8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ((cfg_code & 0x80) == 0)
8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8658fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD))
8668fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        {
8678fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
8688fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
8698fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
8708fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        }
8718fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        else
8728fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        {
873a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                            L2CAP_TRACE_WARNING("L2CAP - cfg_rej exceeds allocated buffer");
8748fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            p_data = p_data_end; /* force loop exit */
8758fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            break;
8768fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        }
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* bad length; force loop exit */
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_data = p_data_end;
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    len = (UINT16) (p - p_hci_len - 2);
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p_hci_len, len);
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = len + 4;
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
894a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d",
8958fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        len, (L2CAP_CMD_OVERHEAD+L2CAP_CONFIG_RSP_LEN+rej_len));
8968fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_disc_req
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "disconnect request" message
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf, *p_buf2;
9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9215738f83aeb59361a0a2eda2460113f6dc919427The 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)
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
923a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for disc_req");
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Move all queued data packets to the LCB. In FCR mode, assume the higher
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       layer checks that all buffers are sent before disconnecting.
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_ccb->xmit_hold_q.p_first)
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf2 = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_set_acl_hci_header (p_buf2, p_ccb);
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2);
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_disc_rsp
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "disconnect response" message
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This function is passed the parameters for the disconnect
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  response instead of the CCB address, as it may be called
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to send a disconnect response when there is no CCB.
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 local_cid,
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                              UINT16 remote_cid)
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf=l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id)) == NULL)
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
971a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for disc_rsp");
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, local_cid);
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, remote_cid);
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_echo_req
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "echo request" message
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer. Note that we do not currently allow
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  data in the echo request.
9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, UINT8 *p_data, UINT16 data_len)
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_lcb, L2CAP_ADJ_ZERO_ID);  /* check for wrap to '0' */
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10035738f83aeb59361a0a2eda2460113f6dc919427The 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)
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1005a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for echo_req");
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len)
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ARRAY_TO_STREAM  (p, p_data, data_len);
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_echo_rsp
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "echo response" message
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 data_len)
10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16   maxlen;
10358fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    /* Filter out duplicate IDs or if available buffers are low (intruder checking) */
10368fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (!id || id == p_lcb->cur_echo_id)
10378fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
10388fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        /* Dump this request since it is illegal */
1039a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP ignoring duplicate echo request (%d)", id);
10408fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return;
10418fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
10428fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    else
10438fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        p_lcb->cur_echo_id = id;
10448fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta     /* Don't respond if we more than 10% of our buffers are used */
10458fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (GKI_poolutilization (L2CAP_CMD_POOL_ID) > 10)
10468fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
1047a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP gki pool used up to more than 10%%, ignore echo response");
10488fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return;
10498fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Don't return data if it does not fit in ACL and L2CAP MTU */
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ?
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project               btu_cb.hcit_acl_data_size : (UINT16)GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID);
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    maxlen -= (UINT16)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN);
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len > maxlen)
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        data_len = 0;
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10605738f83aeb59361a0a2eda2460113f6dc919427The 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)
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1062a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for echo_rsp");
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len)
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ARRAY_TO_STREAM  (p, p_data, data_len);
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_info_req
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "info request" message
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_info_req (tL2C_LCB *p_lcb, UINT16 info_type)
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* check for wrap and/or BRCM ID */
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->id)) == NULL)
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1097a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for info_req");
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1101a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_EVENT ("l2cu_send_peer_info_req: type 0x%04x", info_type);
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, info_type);
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->w4_info_rsp = TRUE;
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_start_timer (&p_lcb->info_timer_entry, BTU_TTYPE_L2CAP_INFO, L2CAP_WAIT_INFO_RSP_TOUT);
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_info_rsp
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "info response" message
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type)
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16   len = L2CAP_INFO_RSP_LEN;
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_CONFORMANCE_TESTING == TRUE)
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS   | L2CAP_EXTFEA_STREAM_MODE |
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_UCD_RECEPTION )) )
11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                           L2CAP_EXTFEA_NO_CRC |L2CAP_EXTFEA_FIXED_CHNLS |
11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                           L2CAP_EXTFEA_UCD_RECEPTION )) )
11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE;
11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_FIXED_CHNL_ARRAY_SIZE;
11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_CONNLESS_MTU_INFO_SIZE;
11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id)) == NULL)
11565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1157a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for info_rsp");
11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
11625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, info_type);
11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_CONFORMANCE_TESTING == TRUE)
11675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (l2cb.test_info_resp & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                  | L2CAP_EXTFEA_UCD_RECEPTION )) )
11705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (L2CAP_EXTFEA_SUPPORTED_MASK & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
11735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                          | L2CAP_EXTFEA_UCD_RECEPTION )) )
11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
11775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
11788fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_LE)
11795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* optional data are not added for now */
11815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK);
11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CONFORMANCE_TESTING == TRUE
11875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, l2cb.test_info_resp);
11885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
11905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS);
11915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK);
11935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
11985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memset (p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE);
12015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p[0] = L2CAP_FIXED_CHNL_SIG_BIT;
12035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION )
12055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT;
12065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
12085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            int xx;
12105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
12125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
12135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p[0] |= 1 << (xx + L2CAP_FIRST_FIXED_CHNL);
12145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
12165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
12185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
12205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_UCD_MTU);
12215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED);  /* 'not supported' */
12255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
12285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
12315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_enqueue_ccb
12335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      queue CCB by priority. The first CCB is highest priority and
12355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is served at first. The CCB is queued to an LLCB or an LCB.
12365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
12385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
12405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_enqueue_ccb (tL2C_CCB *p_ccb)
12415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
12425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_ccb1;
12435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB_Q      *p_q = NULL;
12445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find out which queue the channel is on
12465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
12475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
12485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q = &p_ccb->p_lcb->ccb_queue;
12495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (!p_ccb->in_use) || (p_q == NULL) )
12515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1252a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("l2cu_enqueue_ccb  CID: 0x%04x ERROR in_use: %u  p_lcb: 0x%08x",
12535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb);
12545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
12555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1257a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_enqueue_ccb CID: 0x%04x  priority: %d",
12585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->local_cid, p_ccb->ccb_priority);
12595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the queue is empty, we go at the front */
12615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_q->p_first_ccb)
12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_first_ccb  = p_q->p_last_ccb   = p_ccb;
12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
12655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
12675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb1 = p_q->p_first_ccb;
12695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_ccb1 != NULL)
12715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Insert new ccb at the end of the same priority. Lower number, higher priority */
12735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->ccb_priority < p_ccb1->ccb_priority)
12745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
12755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Are we at the head of the queue ? */
12765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb1 == p_q->p_first_ccb)
12775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_q->p_first_ccb = p_ccb;
12785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
12795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_ccb1->p_prev_ccb->p_next_ccb  = p_ccb;
12805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_next_ccb  = p_ccb1;
12825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_prev_ccb  = p_ccb1->p_prev_ccb;
12835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb1->p_prev_ccb = p_ccb;
12845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
12865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb1 = p_ccb1->p_next_ccb;
12885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If we are lower then anyone in the list, we go at the end */
12915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_ccb1)
12925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* add new ccb at the end of the list */
12945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb->p_next_ccb = p_ccb;
12955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_next_ccb   = NULL;
12975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_prev_ccb   = p_q->p_last_ccb;
12985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb = p_ccb;
12995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
13035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Adding CCB into round robin service table of its LCB */
13045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
13055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if this is the first channel in this priority group */
13075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
13085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Set the first channel to this CCB */
13105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
13115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Set the next serving channel in this group to this CCB */
13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Initialize quota of this priority group based on its priority */
13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
13155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* increase number of channels in this group */
13175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++;
13185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
13205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
13245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_dequeue_ccb
13265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      dequeue CCB from a queue
13285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          -
13305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
13325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
13335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB_Q      *p_q = NULL;
13355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1336a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_dequeue_ccb  CID: 0x%04x", p_ccb->local_cid);
13375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find out which queue the channel is on
13395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
13405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
13415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q = &p_ccb->p_lcb->ccb_queue;
13425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL) )
13445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1345a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("l2cu_dequeue_ccb  CID: 0x%04x ERROR in_use: %u  p_lcb: 0x%08x  p_q: 0x%08x  p_q->p_first_ccb: 0x%08x",
13465738f83aeb59361a0a2eda2460113f6dc919427The 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);
13475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
13485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
13515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Removing CCB from round robin service table of its LCB */
13525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
13535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* decrease number of channels in this priority group */
13555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--;
13565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if it was the last channel in the priority group */
13585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
13595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
13615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
13645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if it is the first channel of this group */
13665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb )
13675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
13685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb->p_next_ccb;
13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
13705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if it is the next serving channel of this group */
13715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb )
13725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
13735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* simply, start serving from the first channel */
13745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb
13755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    = p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb;
13765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
13775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
13805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb == p_q->p_first_ccb)
13825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We are removing the first in a queue */
13845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_first_ccb = p_ccb->p_next_ccb;
13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_q->p_first_ccb)
13875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_first_ccb->p_prev_ccb = NULL;
13885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
13895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb = NULL;
13905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb == p_q->p_last_ccb)
13925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We are removing the last in a queue */
13945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_last_ccb = p_ccb->p_prev_ccb;
13955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_last_ccb->p_next_ccb = NULL;
13965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
13985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* In the middle of a chain. */
14005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb;
14015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb;
14025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
14055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
14065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
14085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_change_pri_ccb
14105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description
14125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          -
14145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
14165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
14175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
14185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->ccb_priority != priority)
14195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If CCB is not the only guy on the queue */
14215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) )
14225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1423a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_DEBUG ("Update CCB list in logical link");
14245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Remove CCB from queue and re-queue it at new priority */
14265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_dequeue_ccb (p_ccb);
14275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->ccb_priority = priority;
14295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_enqueue_ccb (p_ccb);
14305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
14315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
14325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
14335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
14345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* If CCB is the only guy on the queue, no need to re-enqueue */
14355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* update only round robin service data */
14365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0;
14375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
14385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
14395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->ccb_priority = priority;
14415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
14435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
14445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
14455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1;
14465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
14475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
14485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
14505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
14525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_ccb
14545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function allocates a Channel Control Block and
14565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  attaches it to a link control block. The local CID
14575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is also assigned.
14585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB, or NULL if none
14605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
14625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid)
14635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
14645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
14655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_prev;
14665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1467a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x", cid);
14685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!l2cb.p_free_ccb_first)
14705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
14715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If a CID was passed in, use that, else take the first free one */
14735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cid == 0)
14745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.p_free_ccb_first;
14765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
14775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
14795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_prev = NULL;
14815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID];
14835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb == l2cb.p_free_ccb_first)
14855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
14865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
14875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
14885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL; p_prev = p_prev->p_next_ccb)
14895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
14905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_prev->p_next_ccb == p_ccb)
14915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
14925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_prev->p_next_ccb = p_ccb->p_next_ccb;
14935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_ccb == l2cb.p_free_ccb_last)
14955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        l2cb.p_free_ccb_last = p_prev;
14965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
14985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
14995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
15005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_prev == NULL)
15015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
1502a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                L2CAP_TRACE_ERROR ("l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free list", cid);
15035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return NULL;
15045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
15055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
15065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
15095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->in_use = TRUE;
15115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Get a CID for the connection */
15135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_cid = L2CAP_BASE_APPL_CID + (UINT16)(p_ccb - l2cb.ccb_pool);
15145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb = p_lcb;
15165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_rcb = NULL;
15175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set priority then insert ccb into LCB queue (if we have an LCB) */
15195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW;
15205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb)
15225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_enqueue_ccb (p_ccb);
15235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* clear what peer wants to configure */
15255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->peer_cfg_bits = 0;
15265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in default values for configuration */
15285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO));
15295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO));
15305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in default values for local/peer configurations */
15325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.flush_to              = p_ccb->peer_cfg.flush_to              = L2CAP_DEFAULT_FLUSH_TO;
15335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.mtu                   = p_ccb->peer_cfg.mtu                   = L2CAP_DEFAULT_MTU;
15345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.service_type      = p_ccb->peer_cfg.qos.service_type      = L2CAP_DEFAULT_SERV_TYPE;
15355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.token_rate        = p_ccb->peer_cfg.qos.token_rate        = L2CAP_DEFAULT_TOKEN_RATE;
15365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size = L2CAP_DEFAULT_BUCKET_SIZE;
15375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.peak_bandwidth    = p_ccb->peer_cfg.qos.peak_bandwidth    = L2CAP_DEFAULT_PEAK_BANDWIDTH;
15385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.latency           = p_ccb->peer_cfg.qos.latency           = L2CAP_DEFAULT_LATENCY;
15395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.delay_variation   = p_ccb->peer_cfg.qos.delay_variation   = L2CAP_DEFAULT_DELAY;
15405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->bypass_fcs = 0;
15425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO));
15435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->peer_cfg_already_rejected = FALSE;
15445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fcr_cfg_tries         = L2CAP_MAX_FCR_CFG_TRIES;
15455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fcrb.ack_timer.param  = (TIMER_PARAM_TYPE)p_ccb;
15465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* if timer is running, remove it from timer list */
15485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->fcrb.ack_timer.in_use)
15495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btu_stop_quick_timer (&p_ccb->fcrb.ack_timer);
15505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fcrb.mon_retrans_timer.param  = (TIMER_PARAM_TYPE)p_ccb;
15525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific ++
15545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /*  CSP408639 Fix: When L2CAP send amp move channel request or receive
15555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
15565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * request -> Stop retrans/monitor timer -> Change channel state to CST_AMP_MOVING. */
15575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if (p_ccb->fcrb.mon_retrans_timer.in_use)
15585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
15595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific --
15605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_stop_timer (p_ccb);
15625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.preferred_mode  = L2CAP_FCR_BASIC_MODE;        /* Default mode for channel is basic mode */
15645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.allowed_modes   = L2CAP_FCR_CHAN_OPT_BASIC;    /* Default mode for channel is basic mode */
15655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.fcr_rx_pool_id  = L2CAP_FCR_RX_POOL_ID;
15665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.fcr_tx_pool_id  = L2CAP_FCR_TX_POOL_ID;
15675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
15685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
15695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->max_rx_mtu                = L2CAP_MTU_SIZE;
15705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->tx_mps                    = GKI_get_pool_bufsize(HCI_ACL_POOL_ID) - 32;
15715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_init_q (&p_ccb->xmit_hold_q);
15735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->cong_sent    = FALSE;
15755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->buff_quota   = 2;                /* This gets set after config */
15765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If CCB was reserved Config_Done can already have some value */
15785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cid == 0)
15795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->config_done  = 0;
15805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
15815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1582a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x config_done:0x%x", cid, p_ccb->config_done);
15835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->chnl_state   = CST_CLOSED;
15865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->flags        = 0;
15875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
15885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
15895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
15915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->is_flushable = FALSE;
15925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
15935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
15955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->timer_entry.in_use = 0;
15965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_adjust_chnl_allocation ();
15985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_ccb);
16005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
16035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_start_post_bond_timer
16055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function starts the ACL Link inactivity timer after
16075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  dedicated bonding
16085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This timer can be longer than the normal link inactivity
16095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  timer for some platforms.
16105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          BOOLEAN  - TRUE if idle timer started or disconnect initiated
16125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                             FALSE if there's one or more pending CCB's exist
16135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
16155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_start_post_bond_timer (UINT16 handle)
16165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
16175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16    timeout;
16185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
16195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_lcb)
16215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (TRUE);
16225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->is_bonding = FALSE;
16245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Only start timer if no control blocks allocated */
16265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->ccb_queue.p_first_ccb != NULL)
16275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
16285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If no channels on the connection, start idle timeout */
16305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_CONNECTING) || (p_lcb->link_state == LST_DISCONNECTING) )
16315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->idle_timeout == 0)
16335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
16345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER))
16355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
16365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_state = LST_DISCONNECTING;
16375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                timeout = L2CAP_LINK_DISCONNECT_TOUT;
16385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
16395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
16405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                timeout = BT_1SEC_TIMEOUT;
16415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
16425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
16435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
16445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = L2CAP_BONDING_TIMEOUT;
16455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
16465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (timeout != 0xFFFF)
16485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
16495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (TRUE);
16515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (FALSE);
16545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
16575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_ccb
16595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function releases a Channel Control Block. The timer
16615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is stopped, any attached buffers freed, and the CCB is removed
16625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  from the link control block.
16635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
16655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
16675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_ccb (tL2C_CCB *p_ccb)
16685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
16695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = p_ccb->p_lcb;
16705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = p_ccb->p_rcb;
16715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1672a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_release_ccb: cid 0x%04x  in_use: %u", p_ccb->local_cid, p_ccb->in_use);
16735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If already released, could be race condition */
16755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_ccb->in_use)
16765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
16775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_rcb && (p_rcb->psm != p_rcb->real_psm))
16795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btm_sec_clr_service_by_psm(p_rcb->psm);
16815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1682ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
1683ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr);
1684ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
16855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Stop the timer */
16865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_stop_timer (&p_ccb->timer_entry);
16875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (p_ccb->xmit_hold_q.p_first)
16895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (GKI_dequeue (&p_ccb->xmit_hold_q));
16905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_cleanup (p_ccb);
16925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Channel may not be assigned to any LCB if it was just pre-reserved */
16945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_lcb) &&
16955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID)
16965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
16975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ||(p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID)
16985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
16995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         )
17005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       )
17015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_dequeue_ccb (p_ccb);
17035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Delink the CCB from the LCB */
17055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb = NULL;
17065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put the CCB back on the free pool */
17095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!l2cb.p_free_ccb_first)
17105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_first = p_ccb;
17125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last  = p_ccb;
17135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb     = NULL;
17145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb     = NULL;
17155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
17175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb  = NULL;
17195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb  = l2cb.p_free_ccb_last;
17205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last->p_next_ccb = p_ccb;
17215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last  = p_ccb;
17225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Flag as not in use */
17255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->in_use = FALSE;
17265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If no channels on the connection, start idle timeout */
17285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED))
17295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_lcb->ccb_queue.p_first_ccb)
17315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
17325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_no_dynamic_ccbs (p_lcb);
17335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
17345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
17355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
17365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Link is still active, adjust channel quotas. */
17375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_adjust_chnl_allocation ();
17385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
17395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_ccb_by_remote_cid
17455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active CCBs on a link for a match based
17475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  on the remote CID.
17485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched CCB, or NULL if no match
17505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
17525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid)
17535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
17555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If LCB is NULL, look through all active links */
17575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_lcb)
17585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
17605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
17625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
17645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid))
17655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_ccb);
17665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
17695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
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_allocate_rcb
17755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through the Registration Control Blocks for a free
17775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  one.
17785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to the RCB or NULL if not found
17805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
17825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_RCB *l2cu_allocate_rcb (UINT16 psm)
17835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
17855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      xx;
17865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
17885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_rcb->in_use)
17905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
17915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->in_use = TRUE;
17925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->psm    = psm;
17935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
17945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
17955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
17965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_rcb);
17975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
17985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no free RCB found */
18015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
18025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_rcb
18085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Mark an RCB as no longet in use
18105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
18125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_rcb (tL2C_RCB *p_rcb)
18155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
18165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rcb->in_use = FALSE;
18175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rcb->psm    = 0;
18185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_disconnect_chnl
18245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Disconnect a channel. Typically, this is due to either
18265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  receiving a bad configuration,  bad packet or max_retries expiring.
18275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_disconnect_chnl (tL2C_CCB *p_ccb)
18305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
18315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      local_cid = p_ccb->local_cid;
18325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (local_cid >= L2CAP_BASE_APPL_CID)
18345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        tL2CA_DISCONNECT_IND_CB   *p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
18365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1837a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - disconnect_chnl CID: 0x%04x", local_cid);
18385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_send_peer_disc_req (p_ccb);
18405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_ccb (p_ccb);
18425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_disc_cb)(local_cid, FALSE);
18445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
18465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* failure on the AMP channel, probably need to disconnect ACL */
1848a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid);
18495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_rcb_by_psm
18565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through the Registration Control Blocks to see if
18585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  anyone registered to handle the PSM in question
18595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to the RCB or NULL if not found
18615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_RCB *l2cu_find_rcb_by_psm (UINT16 psm)
18645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
18655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
18665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      xx;
18675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
18695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_rcb->in_use) && (p_rcb->psm == psm))
18715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_rcb);
18725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
18755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
18765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_peer_cfg_req
18825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when the peer sends us a "config request"
18845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
18855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
18865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Note:  Negotiation of the FCR channel type is handled internally,
18885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                         all others are passed to the upper layer.
18895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          UINT8 - L2CAP_PEER_CFG_OK if passed to upper layer,
18915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                          L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to
18925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              because parameters are unnacceptable from a specification
18935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              point of view.
18945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                          L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes
18955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              between the two devices, and shall be closed.
18965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
18995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
19005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  mtu_ok      = TRUE;
19015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  qos_type_ok = TRUE;
19025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  flush_to_ok = TRUE;
19035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN  fcr_ok      = TRUE;
19045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8    fcr_status;
19055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Ignore FCR parameters for basic mode */
19075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_cfg->fcr_present)
19085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
19095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the MTU that our peer can receive */
19115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
19125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Make sure MTU is at least the minimum */
19145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->mtu >= L2CAP_MIN_MTU)
19155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* In basic mode, limit the MTU to our buffer size */
19175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( (p_cfg->fcr_present == FALSE) && (p_cfg->mtu > L2CAP_MTU_SIZE) )
19185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_cfg->mtu = L2CAP_MTU_SIZE;
19195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Save the accepted value in case of renegotiation */
19215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.mtu = p_cfg->mtu;
19225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.mtu_present = TRUE;
19235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
19245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Illegal MTU value */
19265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->mtu = L2CAP_MIN_MTU;
19285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            mtu_ok     = FALSE;
19295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload mtu from a previously accepted config request */
19325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.mtu_present)
19335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu_present = TRUE;
19355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu = p_ccb->peer_cfg.mtu;
19365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Verify that the flush timeout is a valid value (0 is illegal) */
19395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
19405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_cfg->flush_to)
19425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->flush_to = 0xFFFF;   /* Infinite retransmissions (spec default) */
19445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            flush_to_ok     = FALSE;
19455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Save the accepted value in case of renegotiation */
19475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.flush_to_present = TRUE;
19495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
19505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
19515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload flush_to from a previously accepted config request */
19545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.flush_to_present)
19555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->flush_to_present = TRUE;
19575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
19585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the QOS settings the the peer is using */
19615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
19625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Make sure service type is not a reserved value; otherwise let upper
19645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           layer decide if acceptable
19655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        */
19665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->qos.service_type <= GUARANTEED)
19675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.qos         = p_cfg->qos;
19695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.qos_present = TRUE;
19705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
19715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Illegal service type value */
19735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->qos.service_type = BEST_EFFORT;
19755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            qos_type_ok             = FALSE;
19765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload QOS from a previously accepted config request */
19795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.qos_present)
19805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->qos_present = TRUE;
19825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->qos         = p_ccb->peer_cfg.qos;
19835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((fcr_status = l2c_fcr_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_DISCONNECT)
19865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Notify caller to disconnect the channel (incompatible modes) */
19885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->result = L2CAP_CFG_FAILED_NO_REASON;
19895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
19905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_DISCONNECT);
19925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
19955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Return any unacceptable parameters */
19975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok)
19985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_adjust_out_mps (p_ccb);
20005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_OK);
20015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
20035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
20055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu_ok)
20075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->mtu_present = FALSE;
20085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (flush_to_ok)
20095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->flush_to_present = FALSE;
20105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (qos_type_ok)
20115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->qos_present = FALSE;
20125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (fcr_ok)
20135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->fcr_present = FALSE;
20145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_UNACCEPTABLE);
20165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
20185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
20215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_peer_cfg_rsp
20235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when the peer sends us a "config response"
20255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
20265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
20275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
20295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
20315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
20325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
20335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we wanted QoS and the peer sends us a positive response with QoS, use his values */
20345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_cfg->qos_present) && (p_ccb->our_cfg.qos_present) )
20355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos = p_cfg->qos;
20365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
20385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Save the retransmission and monitor timeout values */
20405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE)
20415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
20435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
20445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Calculate the max number of packets for which we can delay sending an ack */
20475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz)
20485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
20495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
20505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
20515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2052a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, max_held_acks: %d",
20535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks);
20545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
20565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
20585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_our_cfg_req
20605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when we send a "config request"
20625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
20635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
20645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
20665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
20685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
20695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
20705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb;
20715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      hci_flush_to;
20725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the QOS settings we are using for transmit */
20745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
20755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos_present = TRUE;
20775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos         = p_cfg->qos;
20785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
20815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Override FCR options if attempting streaming or basic */
20835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)
20845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
20855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
20865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* On BR/EDR, timer values are zero in config request */
20885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* On class 2 AMP, timer value in config request shall be non-0 processing time */
20895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*                 timer value in config response shall be greater than received processing time */
20905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
20915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE)
20935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0;
20945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Set the threshold to send acks (may be updated in the cfg response) */
20975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
20985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Include FCS option only if peer can handle it */
21005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC)
21015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* FCS check can be bypassed if peer also desires to bypass */
21035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS)
21045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR;
21055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
21075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->fcs_present = FALSE;
21085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
21105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
21125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.fcr.mode    = p_cfg->fcr.mode;
21155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
21165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check the flush timeout. If it is lower than the current one used */
21185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* then we need to adjust the flush timeout sent to the controller   */
21195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
21205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_cfg->flush_to == 0)||(p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH))
21225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* don't send invalid flush timeout */
21245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* SPEC: The sender of the Request shall specify its flush timeout value */
21255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*       if it differs from the default value of 0xFFFF                  */
21265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->flush_to_present = FALSE;
21275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
21295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->our_cfg.flush_to = p_cfg->flush_to;
21315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb = p_ccb->p_lcb;
21325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->flush_to < p_lcb->link_flush_tout)
21345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
21355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_flush_tout = p_cfg->flush_to;
21365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If the timeout is within range of HCI, set the flush timeout */
21385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8))
21395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
21405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* Convert flush timeout to 0.625 ms units, with round */
21415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
21425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to);
21435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
21445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
21455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
21485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
21515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_our_cfg_rsp
21535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when we send the peer a "config response"
21555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
21565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
21575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
21595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
21615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
21625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
21635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If peer wants QoS, we are allowed to change the values in a positive response */
21645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present) )
21655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->peer_cfg.qos = p_cfg->qos;
21665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
21675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->qos_present = FALSE;
21685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_adj_our_rsp_options (p_ccb, p_cfg);
21705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
21715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
21745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_device_reset
21765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when reset of the device is
21785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  completed.  For all active connection simulate HCI_DISC
21795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
21815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
21835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_device_reset (void)
21845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
21855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
21865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
21875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
21895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE))
21915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_hci_disc_comp (p_lcb->handle, (UINT8) -1);
21935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2195ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#if (BLE_INCLUDED == TRUE)
2196ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    l2cb.is_ble_connecting = FALSE;
2197ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta#endif
21985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
21995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
22015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectextern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ;
22025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
22055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_create_conn
22075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initiates an acl connection via HCI
22095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if successful, FALSE if gki get buffer fails.
22115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
22138fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi BattaBOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport)
22145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
22155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int             xx;
22165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB        *p_lcb_cur = &l2cb.lcb_pool[0];
22175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BTM_SCO_INCLUDED == TRUE
22185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN         is_sco_active;
22195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
22225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_DEVICE_TYPE     dev_type;
22235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBLE_ADDR_TYPE      addr_type;
22245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22258fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
22265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
22275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (transport == BT_TRANSPORT_LE)
22295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
22303aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach        if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
22313aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach            return FALSE;
22323aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach
22335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->ble_addr_type = addr_type;
22348fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        p_lcb->transport = BT_TRANSPORT_LE;
22355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (l2cble_create_conn(p_lcb));
22375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
22385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If there is a connection where we perform as a slave, try to switch roles
22415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       for this connection */
22425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++)
22435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
22445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb_cur == p_lcb)
22455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
22465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb_cur->in_use) && (p_lcb_cur->link_role == HCI_ROLE_SLAVE))
22485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
22495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BTM_SCO_INCLUDED == TRUE
22515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* The LMP_switch_req shall be sent only if the ACL logical transport
22525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            is in active mode, when encryption is disabled, and all synchronous
22535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            logical transports on the same physical link are disabled." */
22545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Check if there is any SCO Active on this BD Address */
22565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            is_sco_active = btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr);
22575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2258a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_API ("l2cu_create_conn - btm_is_sco_active_by_bdaddr() is_sco_active = %s", \
22595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (is_sco_active == TRUE) ? "TRUE":"FALSE");
22605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (is_sco_active == TRUE)
22625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue; /* No Master Slave switch not allowed when SCO Active */
22635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22648fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            /*4_1_TODO check  if btm_cb.devcb.local_features to be used instead */
22653aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach            if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures()))
22665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
22675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* mark this lcb waiting for switch to be completed and
22685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   start switch on the other one */
22695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH;
22705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_role  = HCI_ROLE_MASTER;
22715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (BTM_SwitchRole (p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) == BTM_CMD_STARTED)
22735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
22745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_ROLE_SWITCH_TOUT);
22755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    return (TRUE);
22765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
22775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
22785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
22795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
22805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->link_state = LST_CONNECTING;
22825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (l2cu_create_conn_after_switch (p_lcb));
22845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
22855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
22875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_num_hi_priority
22895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Gets the number of high priority channels.
22915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns
22935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
22955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 l2cu_get_num_hi_priority (void)
22965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
22975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       no_hi = 0;
22985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
22995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
23005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
23025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
23035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
23045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
23055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            no_hi++;
23065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
23075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return no_hi;
23095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
23105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
23135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_create_conn_after_switch
23155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initiates an acl connection via HCI
23175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  If switch required to create connection it is already done.
23185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if successful, FALSE if gki get buffer fails.
23205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
23225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb)
23245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
23255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
23265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_INQ_INFO    *p_inq_info;
23275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            page_scan_rep_mode;
23285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            page_scan_mode;
23295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16           clock_offset;
23305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            *p_features;
23315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16           num_acl = BTM_GetNumAclLinks();
23325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_lcb->remote_bd_addr);
23335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8            no_hi_prio_chs = l2cu_get_num_hi_priority();
23345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_features = BTM_ReadLocalFeatures();
23365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2337a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d",
23385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding);
23395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* FW team says that we can participant in 4 piconets
23405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * typically 3 piconet + 1 for scanning.
23415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * We can enhance the code to count the number of piconets later. */
23425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( ((!l2cb.disallow_switch && (num_acl < 3)) || (p_lcb->is_bonding && (no_hi_prio_chs==0)))
23435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && HCI_SWITCH_SUPPORTED(p_features))
23445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
23455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
23465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
23475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->link_state = LST_CONNECTING;
23495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
23525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (clock_offset = tcs_wug_get_clk_offset( p_lcb->remote_bd_addr )) != 0 )
23535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
23545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R0;
23555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
23565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
23585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
23595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
23605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Check with the BT manager if details about remote device are known */
23625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL)
23635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
23645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
23655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_mode = p_inq_info->results.page_scan_mode;
23665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            clock_offset = (UINT16)(p_inq_info->results.clock_offset);
23675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
23685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
23695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
23705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* No info known. Use default settings */
23715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
23725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
23735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
23755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
23765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (TCS_WUG_MEMBER_INCLUDED == TRUE && TCS_INCLUDED == TRUE)
23775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
23795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!btsnd_hcic_create_conn (p_lcb->remote_bd_addr,
238179f454dc544280cc1a3ca3acc643f7dddfe91cd9Hemant Gupta                                 ( HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1
238279f454dc544280cc1a3ca3acc643f7dddfe91cd9Hemant Gupta                                 | HCI_PKT_TYPES_MASK_DM3 | HCI_PKT_TYPES_MASK_DH3
238379f454dc544280cc1a3ca3acc643f7dddfe91cd9Hemant Gupta                                 | HCI_PKT_TYPES_MASK_DM5 | HCI_PKT_TYPES_MASK_DH5 ),
23845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 page_scan_rep_mode,
23855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 page_scan_mode,
23865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 clock_offset,
23875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                 allow_switch))
23885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2390a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("L2CAP - no buffer for l2cu_create_conn");
23915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_lcb (p_lcb);
23925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
23935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
23965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
23975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
23985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK,
24005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     L2CAP_LINK_CONNECT_TOUT);
24015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (TRUE);
24035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
24045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
24075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_state
24095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
24115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  LCB state.
24125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to first matched LCB, or NULL if no match
24145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
24165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state)
24175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
24185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      i;
24195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
24205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
24225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
24235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->link_state == state))
24245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
24265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
24275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
24285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
24305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
24315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
24325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
24355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_lcb_disconnecting
24375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      On each active lcb, check if the lcb is in disconnecting
24395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  state, or if there are no ccb's on the lcb (implying
24405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    idle timeout is running), or if last ccb on the link
24415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    is in disconnecting state.
24425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if any of above conditions met, FALSE otherwise
24445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
24465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_lcb_disconnecting (void)
24475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
24485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb;
24495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
24505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      i;
24515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     status = FALSE;
24525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb = &l2cb.lcb_pool[0];
24545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
24565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
24575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->in_use)
24585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* no ccbs on lcb, or lcb is in disconnecting state */
24605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING))
24615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
24625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                status = TRUE;
24635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
24645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
24655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* only one ccb left on lcb */
24665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb)
24675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
24685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb = p_lcb->ccb_queue.p_first_ccb;
24695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((p_ccb->in_use) &&
24715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
24725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP)))
24735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
24745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = TRUE;
24755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
24765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
24775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
24785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
24795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
24805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
24815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
24825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
24855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_acl_priority
24875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Sets the transmission priority for a channel.
24895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  (For initial implementation only two values are valid.
24905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
24915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if a valid channel, else FALSE
24935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
24955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs)
24975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
24985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB            *p_lcb;
24995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               *pp;
25005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8                command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
25015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8                vs_param;
25025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2503e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_EVENT("SET ACL PRIORITY %d", priority);
25045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find the link control block for the acl channel */
25068fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
25075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2508a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_SetAclPriority");
25095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
25105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (BTM_IS_BRCM_CONTROLLER())
25135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
25145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Called from above L2CAP through API; send VSC if changed */
25155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
25165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              /* Called because of a master/slave role switch; if high resend VSC */
25175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ( reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
25185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
25195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            pp = command;
25205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH : HCI_BRCM_ACL_PRIORITY_LOW;
25225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (pp, p_lcb->handle);
25245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT8_TO_STREAM  (pp, vs_param);
25255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
25275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Adjust lmp buffer allocation for this channel if priority changed */
25295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->acl_priority != priority)
25305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
25315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->acl_priority = priority;
25325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2c_link_adjust_allocation();
25335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
25345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
25355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return(TRUE);
25375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
25405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_non_flushable_pbf
25435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
25455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
25475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
25495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_set_non_flushable_pbf (BOOLEAN is_supported)
25505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (is_supported)
25525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
25535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
25545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
25555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
25575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
25595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_resubmit_pending_sec_req
25615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when required security procedures
25635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  are completed and any pending requests can be re-submitted.
25645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
25665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
25685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
25695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB        *p_lcb;
25715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_ccb;
25725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_next_ccb;
25735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int             xx;
25745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2575a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_resubmit_pending_sec_req  p_bda: 0x%08x", p_bda);
25765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we are called with a BDA, only resubmit for that BDA */
25785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_bda)
25795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
25808fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
25815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If we don't have one, this is an error */
25835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb)
25845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
25855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* For all channels, send the event through their FSMs */
25865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
25875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
25885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_next_ccb = p_ccb->p_next_ccb;
25895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
25905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
25915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
25925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
25935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2594a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_WARNING ("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
25955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
25965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
25985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
25995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* No BDA pasesed in, so check all links */
26005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
26015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
26025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->in_use)
26035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
26045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* For all channels, send the event through their FSMs */
26055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
26065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
26075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_next_ccb = p_ccb->p_next_ccb;
26085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
26095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
26105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
26115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CONFORMANCE_TESTING == TRUE
26165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
26175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_info_rsp_mask
26195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function allows the script wrapper to change the
26215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  info resp mask for conformance testing.
26225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB, or NULL if none
26245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
26265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_set_info_rsp_mask (UINT32 mask)
26275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
26285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cb.test_info_resp = mask;
26295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif  /* L2CAP_CONFORMANCE_TESTING */
26315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
26335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_adjust_out_mps
26355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Sets our MPS based on current controller capabilities
26375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
26395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
26415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_adjust_out_mps (tL2C_CCB *p_ccb)
26425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
26435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 packet_size;
26445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* on the tx side MTU is selected based on packet size of the controller */
26465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    packet_size = btm_get_max_packet_size (p_ccb->p_lcb->remote_bd_addr);
26475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN))
26495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* something is very wrong */
2651a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("l2cu_adjust_out_mps bad packet size: %u  will use MPS: %u", packet_size, p_ccb->peer_cfg.fcr.mps);
26525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
26535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
26555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
26575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We try to negotiate MTU that each packet can be split into whole
26595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        number of max packets.  For example if link is 1.2 max packet size is 339 bytes.
26605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        At first calculate how many whole packets it is.  MAX L2CAP is 1691 + 4 overhead.
26615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        1695, that will be 5 Dh5 packets.  Now maximum L2CAP packet is
26625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
26635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        For EDR 2.0 packet size is 1027.  So we better send RFCOMM packet as 1 3DH5 packet
26655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        1 * 1027 = 1027.  Minus 4 bytes L2CAP header 1023.  */
26665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->peer_cfg.fcr.mps >= packet_size)
26675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
26685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
26695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
26705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2671a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_adjust_out_mps use %d   Based on peer_cfg.fcr.mps: %u  packet_size: %u",
26725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
26735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
26785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_initialize_fixed_ccb
26805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Initialize a fixed channel's CCB
26825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE or FALSE
26845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
26865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, UINT16 fixed_cid, tL2CAP_FCR_OPTS *p_fcr)
26875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
26885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
26895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
26905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we already have a CCB, then simply return */
26925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL)
26935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (TRUE);
26945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_ccb = l2cu_allocate_ccb (NULL, 0)) == NULL)
26965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (FALSE);
26975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2698ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    btu_stop_timer(&p_lcb->timer_entry);
2699ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
27005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set CID for the connection */
27015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_cid  = fixed_cid;
27025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->remote_cid = fixed_cid;
27035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GKI_init_q (&p_ccb->xmit_hold_q);
27055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->is_flushable = FALSE;
27075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->timer_entry.param  = (TIMER_PARAM_TYPE)p_ccb;
27095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_fcr)
27125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
27135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Set the FCR parameters. For now, we will use default pools */
27145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr;
27155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.fcr_rx_pool_id  = HCI_ACL_POOL_ID;
27175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.fcr_tx_pool_id  = HCI_ACL_POOL_ID;
27185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.user_rx_pool_id = HCI_ACL_POOL_ID;
27195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
27205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3;
27225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
27235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Link ccb to lcb and lcb to ccb */
27255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
27265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb = p_lcb;
27275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* There is no configuration, so if the link is up, the channel is up */
27295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->link_state == LST_CONNECTED)
27305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->chnl_state = CST_OPEN;
27315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set the default idle timeout value to use */
27335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fixed_chnl_idle_tout = l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
27345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
27355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (TRUE);
27365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
27375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
27395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_no_dynamic_ccbs
27415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Handles the case when there are no more dynamic CCBs. If there
27435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  are any fixed CCBs, start the longest of the fixed CCB timeouts,
27445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  otherwise start the default link idle timeout or disconnect.
27455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
27475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
27495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
27505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
27515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_STATUS     rc;
27525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16          timeout = p_lcb->idle_timeout;
27535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
27555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
27565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
27585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
27595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_lcb->p_fixed_ccbs[xx] != NULL) && (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout > timeout) )
27605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout;
27615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
27625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
27635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the link is pairing, do not mess with the timeouts */
27655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->is_bonding)
27665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
27675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (timeout == 0)
27695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2770a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
27715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
27735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (rc == BTM_CMD_STARTED)
27745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
27758fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            l2cu_process_fixed_disc_cback(p_lcb);
27765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
27775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = L2CAP_LINK_DISCONNECT_TOUT;
27785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
27795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (rc == BTM_SUCCESS)
27805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
27818fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            l2cu_process_fixed_disc_cback(p_lcb);
27825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* BTM SEC will make sure that link is release (probably after pairing is done) */
27835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
27845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = 0xFFFF;
27855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
27865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if ( (p_lcb->is_bonding)
27875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            &&   (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) )
27885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
27898fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            l2cu_process_fixed_disc_cback(p_lcb);
27905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
27915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = L2CAP_LINK_DISCONNECT_TOUT;
27925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
27935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
27945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
27955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* probably no buffer to send disconnect */
27965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            timeout = BT_1SEC_TIMEOUT;
27975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
27985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
27995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (timeout != 0xFFFF)
28015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2802a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_no_dynamic_ccbs() starting IDLE timeout: %d", timeout);
28035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, timeout);
28045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
28065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
28075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btu_stop_timer(&p_lcb->timer_entry);
28085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
28105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
28125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
28135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_fixed_chnl_resp
28155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      handle a fixed channel response (or lack thereof)
28175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  if the link failed, or a fixed channel response was
28185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  not received, the bitfield is all zeros.
28195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
28215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
28225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
28235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int     xx;
28248fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if (BLE_INCLUDED == TRUE)
28258fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    /* always exclude LE fixed channel on BR/EDR fix channel capability */
28268fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
28278fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        p_lcb->peer_chnl_mask[0] &= ~(L2CAP_FIXED_CHNL_ATT_BIT| \
28288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                                      L2CAP_FIXED_CHNL_BLE_SIG_BIT| \
28298fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                                      L2CAP_FIXED_CHNL_SMP_BIT);
28305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
28315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Tell all registered fixed channels about the connection */
28335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
28345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
28358fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if BLE_INCLUDED == TRUE
28368fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        /* skip sending LE fix channel callbacks on BR/EDR links */
28378fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
28388fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            xx + L2CAP_FIRST_FIXED_CHNL >= L2CAP_ATT_CID &&
28398fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            xx + L2CAP_FIRST_FIXED_CHNL <= L2CAP_SMP_CID)
28408fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            continue;
28418fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
28425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
28435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
28455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
28465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_lcb->p_fixed_ccbs[xx])
28475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
28488fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if BLE_INCLUDED == TRUE
28498fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport);
28508fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#else
28518fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR);
28528fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
28535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2854ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            else
28555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
28568fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if BLE_INCLUDED == TRUE
28578fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
28588fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#else
28598fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
28608fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
2861ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
2862ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if (p_lcb->p_fixed_ccbs[xx])
2863ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
2864ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
2865ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    p_lcb->p_fixed_ccbs[xx] = NULL;
2866ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
28675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
28685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
28715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
28725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28738fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
28748fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta/*******************************************************************************
28758fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
28768fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Function         l2cu_process_fixed_disc_cback
28778fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
28788fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Description      send l2cap fixed channel disconnection callback to application
28798fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
28808fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
28818fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Returns          void
28828fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
28838fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta*******************************************************************************/
28848fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Battavoid l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
28858fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta{
28868fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if (L2CAP_NUM_FIXED_CHNLS > 0)
28878fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    int         xx;
28888fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
28898fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
28908fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
28918fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->p_fixed_ccbs[xx])
28928fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        {
28937ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham            if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
28947ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham            {
28957ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham                l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
28967ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham                p_lcb->p_fixed_ccbs[xx] = NULL;
28978fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if BLE_INCLUDED == TRUE
28988fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
28998fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#else
29008fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
29018fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
29027ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham           }
29038fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        }
29048fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
29058fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta               && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
29068fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if BLE_INCLUDED == TRUE
29078fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
29088fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#else
29098fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
29108fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
29118fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
29128fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
29138fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta}
29148fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
29155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
29165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
29175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_ble_par_req
29195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send a BLE parameter update request message
29215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
29225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
29245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
29265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout)
29275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
29285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
29295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
29305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
29325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
29335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id (p_lcb, L2CAP_ADJ_ID);
29345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29355738f83aeb59361a0a2eda2460113f6dc919427The 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 )
29365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2937a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_req - no buffer");
29385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
29395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
29405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
29425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
29435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, min_int);
29455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, max_int);
29465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, latency);
29475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, timeout);
29485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
29505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
29515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
29535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_ble_par_rsp
29555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send a BLE parameter update response message
29575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
29585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
29605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
29625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, UINT16 reason, UINT8 rem_id)
29635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
29645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
29655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p;
29665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29675738f83aeb59361a0a2eda2460113f6dc919427The 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 )
29685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2969a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_rsp - no buffer");
29705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
29715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
29725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
29745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
29755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, reason);
29775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
29795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
29805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* BLE_INCLUDED == TRUE */
29825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
29855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Functions used by both Full and Light Stack
29865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project********************************************************************************/
29875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
29895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_handle
29915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
29935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  HCI handle.
29945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched LCB, or NULL if no match
29965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
29985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_LCB  *l2cu_find_lcb_by_handle (UINT16 handle)
29995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
30005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
30015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
30025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
30045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
30055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->handle == handle))
30065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
30075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
30085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
30095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
30105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
30125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
30135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
30145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
30165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_ccb_by_cid
30185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active CCBs on a link for a match based
30205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  on the local CID. If passed the link pointer is NULL, all
30215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  active links are searched.
30225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched CCB, or NULL if no match
30245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
30265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid)
30275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
30285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb = NULL;
30295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
30305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 xx;
30315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
30325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (local_cid >= L2CAP_BASE_APPL_CID)
30345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
30355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* find the associated CCB by "index" */
30365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        local_cid -= L2CAP_BASE_APPL_CID;
30375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (local_cid >= MAX_L2CAP_CHANNELS)
30395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
30405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.ccb_pool + local_cid;
30425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* make sure the CCB is in use */
30445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_ccb->in_use)
30455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
30465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = NULL;
30475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
30485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* make sure it's for the same LCB */
30495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (p_lcb && p_lcb != p_ccb->p_lcb)
30505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
30515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = NULL;
30525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
30535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
30545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
30555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
30565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
30575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* searching fixed channel */
30585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.ccb_pool;
30595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ )
30605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
30615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_ccb->local_cid == local_cid)
30625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              &&(p_ccb->in_use)
30635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              &&(p_lcb == p_ccb->p_lcb))
30645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
30655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
30665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb++;
30675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
30685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( xx >= MAX_L2CAP_CHANNELS )
30695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
30705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
30715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
30725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_ccb);
30745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
30755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
30775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
30795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_channel_in_rr
30815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next channel to send on a link. It also adjusts the
30835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB queue to do a basic priority and round-robin scheduling.
30845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB or NULL
30865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
30875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
30885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb)
30895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
30905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_serve_ccb = NULL;
30915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
30925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i, j;
30945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* scan all of priority until finding a channel to serve */
30965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY)&&(!p_serve_ccb); i++ )
30975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
30985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* scan all channel within serving priority group until finding a channel to serve */
30995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb)&&(!p_serve_ccb); j++)
31005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
31015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* scaning from next serving channel */
31025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
31035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (!p_ccb)
31055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3106a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                L2CAP_TRACE_ERROR("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
31075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return NULL;
31085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3110a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_DEBUG("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
31115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                p_ccb->ccb_priority, p_ccb->local_cid, p_ccb->xmit_hold_q.count );
31125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* store the next serving channel */
31145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* this channel is the last channel of its priority group */
31155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (( p_ccb->p_next_ccb == NULL )
31165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              ||( p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority ))
31175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
31185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* next serving channel is set to the first channel in the group */
31195738f83aeb59361a0a2eda2460113f6dc919427The 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;
31205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
31225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
31235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* next serving channel is set to the next channel in the group */
31245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
31255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->chnl_state != CST_OPEN)
31285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue;
31295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* eL2CAP option in use */
31315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
31325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
31335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
31345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
31355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( p_ccb->fcrb.retrans_q.count == 0 )
31375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
31385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->xmit_hold_q.count == 0 )
31395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
31405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* If using the common pool, should be at least 10% free. */
31425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
31435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
31445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* If in eRTM mode, check for window closure */
31465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
31475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
31485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
31495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
31515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
31525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->xmit_hold_q.count == 0)
31535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
31545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
31555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* found a channel to serve */
31575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_serve_ccb = p_ccb;
31585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* decrease quota of its priority group */
31595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_serv[p_lcb->rr_pri].quota--;
31605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
31615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if there is no more quota of the priority group or no channel to have data to send */
31635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0)||(!p_serve_ccb))
31645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
31655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* serve next priority group */
31665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
31675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* initialize its quota */
31685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
31695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
31705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
31715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_serve_ccb)
31735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3174a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG("RR service pri=%d, quota=%d, lcid=0x%04x",
31755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_serve_ccb->ccb_priority,
31765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
31775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_serve_ccb->local_cid );
31785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
31795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_serve_ccb;
31815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
31825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
31845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
31865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_channel
31885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next channel to send on a link bassed on priority
31905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  scheduling.
31915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB or NULL
31935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
31945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
31955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
31965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
31975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
31985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
31995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Get the first CCB with data to send.
32005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
32015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
32025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->chnl_state != CST_OPEN)
32045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
32055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
32075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
32085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->fcrb.retrans_q.count != 0)
32105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return p_ccb;
32115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->xmit_hold_q.count == 0)
32135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
32145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If using the common pool, should be at least 10% free. */
32165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
32175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
32185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If in eRTM mode, check for window closure */
32205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
32215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
32225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If here, we found someone */
32245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return p_ccb;
32255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
32265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
32285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
32295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
32305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
32325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_buffer_to_send
32345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next buffer to send on a link. It also adjusts the
32365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB queue to do a basic priority and round-robin scheduling.
32375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to buffer or NULL
32395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
32415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
32425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
32435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
32445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR      *p_buf;
32455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Highest priority are fixed channels */
32475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
32485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
32495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
32515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL)
32535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
32545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* eL2CAP option in use */
32565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
32575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
32595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue;
32605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* No more checks needed if sending from the reatransmit queue */
32625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->fcrb.retrans_q.count == 0)
32635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
32645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb->xmit_hold_q.count == 0)
32655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
32665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If using the common pool, should be at least 10% free. */
32685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( (p_ccb->ertm_info.fcr_tx_pool_id == HCI_ACL_POOL_ID) && (GKI_poolutilization (HCI_ACL_POOL_ID) > 90) )
32695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
32705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If in eRTM mode, check for window closure */
32725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
32735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
32745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
32755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) != NULL)
32775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3278493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                l2cu_check_channel_congestion (p_ccb);
32795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_set_acl_hci_header (p_buf, p_ccb);
32805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_buf);
32815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
32825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
32845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->xmit_hold_q.count != 0)
32865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
32875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3288ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if(NULL == p_buf)
3289ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
3290a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                    L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
3291ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    return (NULL);
3292ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
3293493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                l2cu_check_channel_congestion (p_ccb);
32945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_set_acl_hci_header (p_buf, p_ccb);
32955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_buf);
32965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
32975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
32995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
33005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
33025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* get next serving channel in round-robin */
33035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb  = l2cu_get_next_channel_in_rr( p_lcb );
33045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
33055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb  = l2cu_get_next_channel( p_lcb );
33065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
33075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Return if no buffer */
33095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb == NULL)
33105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
33115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
33135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
33145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL)
33155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (NULL);
33165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
33175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
33185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
33195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q);
3320ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if(NULL == p_buf)
3321ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
3322a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send() #2: No data to be sent");
3323ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            return (NULL);
3324ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
33255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
33265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33275738f83aeb59361a0a2eda2460113f6dc919427The 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) )
33285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
33295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_check_channel_congestion (p_ccb);
33325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_set_acl_hci_header (p_buf, p_ccb);
33345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_buf);
33365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
33375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
33395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_acl_hci_header
33415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Set HCI handle for ACL packet
33435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
33455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
33475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb)
33485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
33495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       *p;
33505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set the pointer to the beginning of the data minus 4 bytes for the packet header */
33525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p = (UINT8 *)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
33535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BLE_INCLUDED == TRUE)
33558fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
33565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3357eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT));
3358eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh
33595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The HCI transport will segment the buffers. */
33605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf->len > btu_cb.hcit_ble_acl_data_size)
33615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
33625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, btu_cb.hcit_ble_acl_data_size);
33635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
33645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
33655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
33665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, p_buf->len);
33675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
33685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    } /* (BLE_INCLUDED == TRUE) */
33695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
33705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
33715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3372eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3373eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        if ( (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) && (p_ccb->is_flushable))
3374eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh                || ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_PKT) )
3375eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        {
3376eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh            UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3377eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        }
3378eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        else
3379eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        {
3380eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh            UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
3381eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        }
3382eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#else
3383eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3384eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#endif
33855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The HCI transport will segment the buffers. */
33875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf->len > btu_cb.hcit_acl_data_size)
33885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
33895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, btu_cb.hcit_acl_data_size);
33905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
33915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
33925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
33935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, p_buf->len);
33945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
33955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
33965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
33975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len    += HCI_DATA_PREAMBLE_SIZE;
33985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
33995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
34015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_check_channel_congestion
34035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      check if any change in congestion status
34055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
34075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
34095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
34105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
34115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16 q_count = p_ccb->xmit_hold_q.count;
34125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
34145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
34155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
34165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        q_count += p_ccb->p_lcb->ucd_out_sec_pending_q.count;
34175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
34185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
34195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the CCB queue limit is subject to a quota, check for congestion */
34215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* if this channel has outgoing traffic */
3423493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach    if (p_ccb->buff_quota != 0)
34245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
34255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If this channel was congested */
34265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( p_ccb->cong_sent )
34275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
34285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* If the channel is not congested now, tell the app */
34295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (q_count <= (p_ccb->buff_quota / 2))
34305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
34315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->cong_sent = FALSE;
3432493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
34335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3434a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                    L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (FALSE), CID: 0x%04x  xmit_hold_q.count: %u  buff_quota: %u",
34355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      p_ccb->local_cid, q_count, p_ccb->buff_quota);
34365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* Prevent recursive calling */
34385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    l2cb.is_cong_cback_context = TRUE;
34395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, FALSE);
34405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    l2cb.is_cong_cback_context = FALSE;
34415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
34425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
3443493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
34445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
34455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
34465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3447a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                        L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (FALSE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
34485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->p_lcb->ucd_out_sec_pending_q.count,
34495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
34505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, FALSE );
34515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
34525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
34535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3454493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#if (L2CAP_NUM_FIXED_CHNLS > 0)
3455493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else
3456493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                {
3457493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    UINT8 xx;
3458493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
3459493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    {
3460493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
3461493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        {
3462493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3463493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                                (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, FALSE);
3464493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            break;
3465493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        }
3466493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    }
3467493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                }
3468493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#endif
34695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
34705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
34715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
34725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
34735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* If this channel was not congested but it is congested now, tell the app */
34745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (q_count > p_ccb->buff_quota)
34755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
34765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->cong_sent = TRUE;
3477493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
34785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3479a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                    L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u",
34805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->local_cid, q_count, p_ccb->buff_quota);
34815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, TRUE);
34835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
34845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
3485493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
34865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
34875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
34885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3489a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                        L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (TRUE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
34905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->p_lcb->ucd_out_sec_pending_q.count,
34915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                             p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
34925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, TRUE );
34935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
34945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
34955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3496493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#if (L2CAP_NUM_FIXED_CHNLS > 0)
3497493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else
3498493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                {
3499493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    UINT8 xx;
3500493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
3501493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    {
3502493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
3503493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        {
3504493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3505493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                                (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, TRUE);
3506493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            break;
3507493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        }
3508493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    }
3509493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                }
3510493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#endif
35115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
35125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
35135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
35145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
35155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3516