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