l2c_utils.cc revision 84baa7f16e830394408278dbb8c508dd9fa02887
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
2979ecab5d0418fde77e9afcdd451bd713af73e180Chris Manton#include "device/include/controller.h"
30258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_types.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcimsgs.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2cdefs.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_int.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcidefs.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btu.h"
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_int.h"
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hcidefs.h"
408fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#include "bt_utils.h"
41a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati#include "osi/include/allocator.h"
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavovextern fixed_queue_t *btu_general_alarm_queue;
4478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_lcb
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look for an unused LCB
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          LCB address or NULL if none found
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
54d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, bool    is_bonding, tBT_TRANSPORT transport)
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_lcb->in_use)
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            alarm_free(p_lcb->l2c_lcb_timer);
6478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            alarm_free(p_lcb->info_resp_timer);
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memset (p_lcb, 0, sizeof (tL2C_LCB));
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
69d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_lcb->in_use          = true;
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state      = LST_DISCONNECTED;
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->handle          = HCI_INVALID_HANDLE;
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_flush_tout = 0xFFFF;
7378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            p_lcb->l2c_lcb_timer   = alarm_new("l2c_lcb.l2c_lcb_timer");
7478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            p_lcb->info_resp_timer = alarm_new("l2c_lcb.info_resp_timer");
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->idle_timeout    = l2cb.idle_timeout;
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->id              = 1;                     /* spec does not allow '0' */
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->is_bonding      = is_bonding;
788fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            p_lcb->transport       = transport;
79636d6714a4c08dd99d2147dcce05dc3892e804b4Priti Aghera            p_lcb->tx_data_len     = controller_get_interface()->get_ble_default_data_packet_length();
805e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar            p_lcb->le_sec_pending_q = fixed_queue_new(SIZE_MAX);
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8292ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            if (transport == BT_TRANSPORT_LE)
8392ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            {
8492ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2cb.num_ble_links_active++;
8592ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2c_ble_link_adjust_allocation();
8692ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            }
8792ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            else
8892ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            {
8992ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2cb.num_links_active++;
9092ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth                l2c_link_adjust_allocation();
9192ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            }
921a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov#if (L2CAP_UCD_INCLUDED == TRUE)
931a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            p_lcb->ucd_out_sec_pending_q = fixed_queue_new(SIZE_MAX);
941a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            p_lcb->ucd_in_sec_pending_q = fixed_queue_new(SIZE_MAX);
951a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov#endif
966c303aeca25783453333172d0b29e5472f1b1c93Chris Manton            p_lcb->link_xmit_data_q = list_new(NULL);
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no free LCB found */
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
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** Function         l2cu_update_lcb_4_bonding
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Mark the lcb for bonding. Used when bonding takes place on
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  an existing ACL connection.  (Pre-Lisbon devices)
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Nothing
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
115d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, bool    is_bonding)
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1178fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    tL2C_LCB    *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR);
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb)
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
121a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_update_lcb_4_bonding  BDA: %08x%04x is_bonding: %d",
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                          (p_bd_addr[4]<<8)+p_bd_addr[5], is_bonding);
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->is_bonding = is_bonding;
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_lcb
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov** Description      Release an LCB. All timers will be stopped and freed,
13378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov**                  channels dropped, buffers returned etc.
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_lcb (tL2C_LCB *p_lcb)
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
142d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_lcb->in_use     = false;
143d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_lcb->is_bonding = false;
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14578bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    /* Stop and free timers */
14678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_free(p_lcb->l2c_lcb_timer);
14778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    p_lcb->l2c_lcb_timer = NULL;
14878bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_free(p_lcb->info_resp_timer);
14978bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    p_lcb->info_resp_timer = NULL;
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Release any unfinished L2CAP packet on this link */
152cceb430489a70add1b996d54289867c17f4ac0fdPavlin Radoslavov    osi_free_and_reset((void **)&p_lcb->p_hcit_rcv_acl);
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
154d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (BTM_SCO_INCLUDED == TRUE)
1558fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
1568fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        /* Release all SCO links */
1578fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        btm_remove_sco_links(p_lcb->remote_bd_addr);
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16098657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    if (p_lcb->sent_not_acked > 0)
16198657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    {
1628fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_LE)
16398657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        {
16498657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            l2cb.controller_le_xmit_window += p_lcb->sent_not_acked;
16598657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs)
16698657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            {
16798657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach                l2cb.controller_le_xmit_window = l2cb.num_lm_ble_bufs;
16898657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            }
16998657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        }
17098657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        else
17198657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        {
17298657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            l2cb.controller_xmit_window += p_lcb->sent_not_acked;
17398657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            if (l2cb.controller_xmit_window > l2cb.num_lm_acl_bufs)
17498657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            {
17598657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach                l2cb.controller_xmit_window = l2cb.num_lm_acl_bufs;
17698657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach            }
17798657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach        }
17898657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach    }
17998657a365c7230b84a005c63ce5bcf036d69f6ebAndre Eisenbach
180b2386cb6e196487f2cc703d84bb1815eb1c5fc62Nitin Arora    // Reset BLE connecting flag only if the address matches
181b2386cb6e196487f2cc703d84bb1815eb1c5fc62Nitin Arora    if (!memcmp(l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN))
182d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        l2cb.is_ble_connecting = false;
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
1850b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji    l2cu_process_fixed_disc_cback(p_lcb);
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Ensure no CCBs left on this LCB */
1895738f83aeb59361a0a2eda2460113f6dc919427The 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)
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_ccb (p_ccb);
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Tell BTM Acl management the link was removed */
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING))
1968fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        btm_acl_removed (p_lcb->remote_bd_addr, p_lcb->transport);
197ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Release any held buffers */
199ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach    if (p_lcb->link_xmit_data_q)
200ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach    {
201ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach        while (!list_is_empty(p_lcb->link_xmit_data_q)) {
202b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavov            BT_HDR *p_buf =
203b2a292b5d8df2f359c38b0787bc01181225a9bc9Pavlin Radoslavov                static_cast<BT_HDR *>(list_front(p_lcb->link_xmit_data_q));
204ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach            list_remove(p_lcb->link_xmit_data_q, p_buf);
205cceb430489a70add1b996d54289867c17f4ac0fdPavlin Radoslavov            osi_free(p_buf);
206ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach        }
207ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach        list_free(p_lcb->link_xmit_data_q);
208ef92b534112a5df57de11ef45f5174f75d44b355Andre Eisenbach        p_lcb->link_xmit_data_q = NULL;
2096c303aeca25783453333172d0b29e5472f1b1c93Chris Manton    }
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* clean up any security pending UCD */
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_ucd_delete_sec_pending_q(p_lcb);
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Re-adjust flow control windows make sure it does not go negative */
21792ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    if (p_lcb->transport == BT_TRANSPORT_LE)
21892ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    {
21992ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        if (l2cb.num_ble_links_active >= 1)
22092ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            l2cb.num_ble_links_active--;
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22292ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        l2c_ble_link_adjust_allocation();
22392ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    }
22492ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    else
22592ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    {
22692ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        if (l2cb.num_links_active >= 1)
22792ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth            l2cb.num_links_active--;
22892ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth
22992ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth        l2c_link_adjust_allocation();
23092ac2d8919f8e38a091903270eb5500073d67d4bMudumba Ananth    }
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check for ping outstanding */
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->p_echo_rsp_cb)
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb;
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Zero out the callback in case app immediately calls us again */
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->p_echo_rsp_cb = NULL;
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_cb) (L2CAP_PING_RESULT_NO_LINK);
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2425e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar
2435e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar    /* Check and release all the LE COC connections waiting for security */
2445e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar    if (p_lcb->le_sec_pending_q)
2455e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar    {
2465e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar        while (!fixed_queue_is_empty(p_lcb->le_sec_pending_q))
2475e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar        {
2485e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar            tL2CAP_SEC_DATA *p_buf = (tL2CAP_SEC_DATA*) fixed_queue_try_dequeue(p_lcb->le_sec_pending_q);
2495e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar            if (p_buf->p_callback)
2505e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar                p_buf->p_callback(p_lcb->remote_bd_addr, p_lcb->transport, p_buf->p_ref_data, BTM_DEV_RESET);
2515e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar            osi_free(p_buf);
2525e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar        }
2535e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar        fixed_queue_free(p_lcb->le_sec_pending_q, NULL);
2548cbc291080730cd7d04990a8fc0e11249b06aa08Pavlin Radoslavov        p_lcb->le_sec_pending_q = NULL;
2555e8a3d7790e8c0e744173dfa8bb76a567160cbfaNavin Kochar    }
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_bd_addr
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  remote BD address.
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched LCB, or NULL if no match
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2698fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi BattatL2C_LCB  *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport)
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2768fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if ((p_lcb->in_use) &&
2778fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            p_lcb->transport == transport &&
2788fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_conn_role
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Determine the desired role (master or slave) of a link.
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  If already got a slave link, this one must be a master. If
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  already got at least 1 link where we are the master, make this
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  also a master.
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          HCI_ROLE_MASTER or HCI_ROLE_SLAVE
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
300d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenuint8_t l2cu_get_conn_role (tL2C_LCB *p_this_lcb)
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return l2cb.desire_role;
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3078fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Function         l2c_is_cmd_rejected
3088fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
3098fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Description      Checks if cmd_code is command or response
3108fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**                  If a command it will be rejected per spec.
3118fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**                  This function is used when a illegal packet length is detected
3128fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
313d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          bool    - true if cmd_code is a command and it is rejected,
314d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen**                            false if response code. (command not rejected)
3158fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
3168fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta*******************************************************************************/
317d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2c_is_cmd_rejected (uint8_t cmd_code, uint8_t id, tL2C_LCB *p_lcb)
3188fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta{
3198fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    switch(cmd_code)
3208fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
3218fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_CONN_REQ:
3228fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_CONFIG_REQ:
3238fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_DISC_REQ:
3248fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_ECHO_REQ:
3258fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_INFO_REQ:
3268fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_AMP_CONN_REQ:
3278fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_AMP_MOVE_REQ:
3288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    case L2CAP_CMD_BLE_UPDATE_REQ:
3298fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, L2CAP_DEFAULT_MTU, 0);
330a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("Dumping first Command (%d)", cmd_code);
331d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return true;
3328fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
3338fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    default:    /* Otherwise a response */
334d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return false;
3358fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
3368fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta}
3378fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
3388fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta/*******************************************************************************
3398fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_build_header
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Builds the L2CAP command packet header
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to allocated packet or NULL if no resources
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
347d19e0785e662e640191a075eda07acce61c2aedaMarie JanssenBT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, uint16_t len, uint8_t cmd, uint8_t id)
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
349cceb430489a70add1b996d54289867c17f4ac0fdPavlin Radoslavov    BT_HDR  *p_buf = (BT_HDR *)osi_malloc(L2CAP_CMD_BUF_SIZE);
350d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_SEND_CMD_OFFSET;
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = len + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
354d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in HCI header - handle + pkt boundary */
357eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    if (p_lcb->transport == BT_TRANSPORT_LE)
358eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    {
359eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
360eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    }
361eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    else
362eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    {
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
364eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, p_lcb->handle | l2cb.non_flushable_pbf);
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
366eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, (p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
368eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh    }
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD);
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD);
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3738fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (p_lcb->transport == BT_TRANSPORT_LE)
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
375cccf02fadb2dd4dceb22f2d58ed5840b0ef1860eChris Manton
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID);
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP command header */
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, cmd);
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, id);
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, len);
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_buf);
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_adj_id
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Checks for valid ID based on specified mask
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  and adjusts the id if invalid.
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
401d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_adj_id (tL2C_LCB *p_lcb, uint8_t adj_mask)
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((adj_mask & L2CAP_ADJ_ZERO_ID) && !p_lcb->id)
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_lcb->id++;
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_cmd_reject
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "command reject" message
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
419d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, uint16_t reason, uint8_t rem_id,
420d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                                uint16_t p1, uint16_t p2)
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
422d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t param_len;
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
424d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP packet header */
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (reason == L2CAP_CMD_REJ_MTU_EXCEEDED)
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 2;
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (reason == L2CAP_CMD_REJ_INVALID_CID)
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 4;
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        param_len = 0;
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
434d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    if ((p_buf = l2cu_build_header (p_lcb, (uint16_t) (L2CAP_CMD_REJECT_LEN + param_len), L2CAP_CMD_REJECT, rem_id)) == NULL )
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
436a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer cmd_rej");
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
440d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, reason);
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (param_len >= 2)
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p1);
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (param_len >= 4)
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p2);
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_connect_req
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection request" message
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_connect_req (tL2C_CCB *p_ccb)
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
468d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ,
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    p_ccb->local_id)) == NULL)
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
479a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
483d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm);
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_connect_rsp
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection response" message
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
503d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_connect_rsp (tL2C_CCB *p_ccb, uint16_t result, uint16_t status)
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
506d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (result == L2CAP_CONN_PENDING)
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if we already sent pending response */
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->flags & CCB_FLAG_SENT_PENDING)
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return;
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->flags |= CCB_FLAG_SENT_PENDING;
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5175738f83aeb59361a0a2eda2460113f6dc919427The 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)
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
519a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_rsp");
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
523d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(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->local_cid);
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, result);
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, status);
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_reject_connection
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "connection response neg" message
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer. This function is called when there is no peer
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB (non-existant PSM or no resources).
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
546d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_reject_connection (tL2C_LCB *p_lcb, uint16_t remote_cid, uint8_t rem_id, uint16_t result)
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
549d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id)) == NULL )
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
553a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
557d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Local CID of 0   */
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, remote_cid);
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, result);
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Status of 0      */
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_req
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration request" message
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
580d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t cfg_len=0;
581d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcs_present)
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
602d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (uint16_t) (L2CAP_CONFIG_REQ_LEN + cfg_len),
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_CMD_CONFIG_REQ, p_ccb->local_id)) == NULL )
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
605a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
609d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->flags);                    /* Flags (continuation) */
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the options */
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_MTU);
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_MTU_OPTION_LEN);
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->mtu);
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FLUSH_OPTION_LEN);
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->flush_to);
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_QOS);
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_QOS_OPTION_LEN);
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.qos_flags);
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.service_type);
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.latency);
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCR);
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCR_OPTION_LEN);
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.mode);
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.tx_win_sz);
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.max_transmit);
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.rtrans_tout);
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mon_tout);
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mps);
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcs_present)
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCS);
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCS_OPTION_LEN);
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcs);
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_EXT_FLOW);
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.id);
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.stype);
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_rsp
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration response" message
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
687d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t cfg_len = 0;
688d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_MTU_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FLUSH_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_QOS_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_FCR_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len += L2CAP_CFG_EXT_FLOW_OPTION_LEN + L2CAP_CFG_OPTION_OVERHEAD;
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
702d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    if ((p_buf = l2cu_build_header (p_ccb->p_lcb, (uint16_t)(L2CAP_CONFIG_RSP_LEN + cfg_len),
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id)) == NULL )
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
705a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for conn_req");
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
709d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->flags);           /* Flags (continuation) Must match request */
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_cfg->result);
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the options */
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_MTU);
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_MTU_OPTION_LEN);
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->mtu);
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FLUSH_TOUT);
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FLUSH_OPTION_LEN);
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->flush_to);
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_QOS);
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_QOS_OPTION_LEN);
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.qos_flags);
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->qos.service_type);
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_rate);
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.token_bucket_size);
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.peak_bandwidth);
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.latency);
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->qos.delay_variation);
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_FCR);
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_FCR_OPTION_LEN);
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.mode);
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.tx_win_sz);
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->fcr.max_transmit);
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.rtrans_tout);
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_ccb->our_cfg.fcr.mon_tout);
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->fcr.mps);
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->ext_flow_spec_present)
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_TYPE_EXT_FLOW);
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, L2CAP_CFG_EXT_FLOW_OPTION_LEN);
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.id);
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT8_TO_STREAM  (p, p_cfg->ext_flow_spec.stype);
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, p_cfg->ext_flow_spec.max_sdu_size);
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.sdu_inter_time);
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.access_latency);
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, p_cfg->ext_flow_spec.flush_timeout);
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_config_rej
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "configuration reject" message
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
777d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, uint8_t *p_data, uint16_t data_len, uint16_t rej_len)
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
779d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t len, cfg_len, buf_space, len1;
780d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p, *p_hci_len, *p_data_end;
781d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t cfg_code;
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
783a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", data_len, rej_len);
7848fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
7858fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
7868fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN;
7878fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    len1 = 0xFFFF - len;
7888fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (rej_len > len1)
7898fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
790a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("L2CAP - cfg_rej pkt size exceeds buffer design max limit.");
7918fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return;
7928fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
7938fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
794717a4a9f3a044f264ec2482c2d1806ec3093707aPavlin Radoslavov    BT_HDR *p_buf = (BT_HDR *)osi_malloc(len + rej_len);
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset = L2CAP_SEND_CMD_OFFSET;
796d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET;
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in HCI header - handle + pkt boundary */
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (HCI_NON_FLUSHABLE_PB_SUPPORTED(BTM_ReadLocalFeatures ()))
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT)));
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, (p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT)));
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Remember the HCI header length position, and save space for it */
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_hci_len = p;
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p += 2;
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP packet header */
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len);
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_SIGNALLING_CID);
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in L2CAP command header */
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, L2CAP_CMD_CONFIG_RSP);
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8_TO_STREAM  (p, p_ccb->remote_id);
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CONFIG_RSP_LEN + rej_len);
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, 0);                    /* Flags = 0 (no continuation) */
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS);
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    buf_space = rej_len;
8298fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Now, put the rejected options */
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_data_end = p_data + data_len;
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (p_data < p_data_end)
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_code = *p_data;
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_len = *(p_data + 1);
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        switch (cfg_code & 0x7F)
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* skip known options */
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_MTU:
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_FLUSH_TOUT:
8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            case L2CAP_CFG_TYPE_QOS:
8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* unknown options; copy into rsp if not hints */
8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            default:
8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* sanity check option length */
8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= data_len)
8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ((cfg_code & 0x80) == 0)
8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
8538fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD))
8548fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        {
8558fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
8568fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
8578fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
8588fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        }
8598fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        else
8608fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        {
861a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                            L2CAP_TRACE_WARNING("L2CAP - cfg_rej exceeds allocated buffer");
8628fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            p_data = p_data_end; /* force loop exit */
8638fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                            break;
8648fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        }
8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* bad length; force loop exit */
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_data = p_data_end;
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
877d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    len = (uint16_t) (p - p_hci_len - 2);
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p_hci_len, len);
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len = len + 4;
8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
882a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d",
8838fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                        len, (L2CAP_CMD_OVERHEAD+L2CAP_CONFIG_RSP_LEN+rej_len));
8848fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_disc_req
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "disconnect request" message
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_send_peer_disc_req (tL2C_CCB *p_ccb)
8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf, *p_buf2;
901d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
903bf955cb7e50e1047452e741effa504c8aefc8a4fvenkata Jagadeesh    if ((!p_ccb) || (p_ccb->p_lcb == NULL))
904bf955cb7e50e1047452e741effa504c8aefc8a4fvenkata Jagadeesh    {
905bf955cb7e50e1047452e741effa504c8aefc8a4fvenkata Jagadeesh        L2CAP_TRACE_ERROR ("%s L2CAP - ccb or lcb invalid", __func__);
906bf955cb7e50e1047452e741effa504c8aefc8a4fvenkata Jagadeesh        return;
907bf955cb7e50e1047452e741effa504c8aefc8a4fvenkata Jagadeesh    }
908bf955cb7e50e1047452e741effa504c8aefc8a4fvenkata Jagadeesh
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb->id++;
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_id = p_ccb->p_lcb->id;
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9155738f83aeb59361a0a2eda2460113f6dc919427The 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)
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
917a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for disc_req");
9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
921d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->remote_cid);
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, p_ccb->local_cid);
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Move all queued data packets to the LCB. In FCR mode, assume the higher
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       layer checks that all buffers are sent before disconnecting.
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE)
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9311a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        while ((p_buf2 = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->xmit_hold_q)) != NULL)
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_set_acl_hci_header (p_buf2, p_ccb);
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_check_send_pkts (p_ccb->p_lcb, p_ccb, p_buf2);
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_disc_rsp
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "disconnect response" message
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This function is passed the parameters for the disconnect
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  response instead of the CCB address, as it may be called
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to send a disconnect response when there is no CCB.
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
956d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_disc_rsp (tL2C_LCB *p_lcb, uint8_t remote_id, uint16_t local_cid,
957d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                              uint16_t remote_cid)
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
960d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf=l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id)) == NULL)
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
964a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for disc_rsp");
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
968d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, local_cid);
9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, remote_cid);
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_echo_req
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "echo request" message
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer. Note that we do not currently allow
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  data in the echo request.
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
988d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_echo_req (tL2C_LCB *p_lcb, uint8_t *p_data, uint16_t data_len)
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
991d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_lcb, L2CAP_ADJ_ZERO_ID);  /* check for wrap to '0' */
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
996d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    if ((p_buf = l2cu_build_header(p_lcb, (uint16_t) (L2CAP_ECHO_REQ_LEN + data_len), L2CAP_CMD_ECHO_REQ, p_lcb->id)) == NULL)
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
998a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for echo_req");
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1002d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len)
10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ARRAY_TO_STREAM  (p, p_data, data_len);
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_echo_rsp
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "echo response" message
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1023d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, uint8_t id, uint8_t *p_data, uint16_t data_len)
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
1026d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
1027d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t maxlen;
10288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    /* Filter out duplicate IDs or if available buffers are low (intruder checking) */
10298fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (!id || id == p_lcb->cur_echo_id)
10308fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
10318fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        /* Dump this request since it is illegal */
1032a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP ignoring duplicate echo request (%d)", id);
10338fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        return;
10348fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
10358fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    else
10368fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        p_lcb->cur_echo_id = id;
10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
103830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson    uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic();
103930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson    uint16_t acl_packet_size = controller_get_interface()->get_acl_packet_size_classic();
10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Don't return data if it does not fit in ACL and L2CAP MTU */
10411d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov    maxlen = (L2CAP_CMD_BUF_SIZE > acl_packet_size) ?
1042d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen               acl_data_size : (uint16_t)L2CAP_CMD_BUF_SIZE;
1043d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    maxlen -= (uint16_t)(BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD +
10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                L2CAP_CMD_OVERHEAD + L2CAP_ECHO_RSP_LEN);
10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len > maxlen)
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        data_len = 0;
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1049d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    if ((p_buf = l2cu_build_header (p_lcb, (uint16_t)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP, id)) == NULL)
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1051a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for echo_rsp");
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1055d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (data_len)
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ARRAY_TO_STREAM  (p, p_data, data_len);
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_info_req
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "info request" message
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1075d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_info_req (tL2C_LCB *p_lcb, uint16_t info_type)
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
1078d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* check for wrap and/or BRCM ID */
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id(p_lcb, L2CAP_ADJ_ID);
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->id)) == NULL)
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1086a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for info_req");
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1090a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_EVENT ("l2cu_send_peer_info_req: type 0x%04x", info_type);
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1092d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET+HCI_DATA_PREAMBLE_SIZE +
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, info_type);
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1097d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_lcb->w4_info_rsp = true;
109878bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_set_on_queue(p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
109978bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                       l2c_info_resp_timer_timeout, p_lcb,
110078bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                       btu_general_alarm_queue);
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_info_rsp
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send an L2CAP "info response" message
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1116d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, uint8_t remote_id, uint16_t info_type)
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
1119d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
1120d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t len = L2CAP_INFO_RSP_LEN;
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_CONFORMANCE_TESTING == TRUE)
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (l2cb.test_info_resp & (L2CAP_EXTFEA_ENH_RETRANS   | L2CAP_EXTFEA_STREAM_MODE |
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_NO_CRC | L2CAP_EXTFEA_EXT_FLOW_SPEC |
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_FIXED_CHNLS | L2CAP_EXTFEA_EXT_WINDOW |
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   L2CAP_EXTFEA_UCD_RECEPTION )) )
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (L2CAP_EXTFEA_SUPPORTED_MASK & (L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE |
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                           L2CAP_EXTFEA_NO_CRC |L2CAP_EXTFEA_FIXED_CHNLS |
1132e6e73fa499d09696c33390e91ec17cba488e49cbAndre Eisenbach                                           L2CAP_EXTFEA_UCD_RECEPTION )) != 0 )
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_EXTENDED_FEATURES_ARRAY_SIZE;
11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_FIXED_CHNL_ARRAY_SIZE;
11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        len += L2CAP_CONNLESS_MTU_INFO_SIZE;
11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id)) == NULL)
11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1148a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no buffer for info_rsp");
11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1152d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, info_type);
11565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_CONFORMANCE_TESTING == TRUE)
11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (l2cb.test_info_resp & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                  | L2CAP_EXTFEA_UCD_RECEPTION )) )
11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && (L2CAP_EXTFEA_SUPPORTED_MASK & ( L2CAP_EXTFEA_ENH_RETRANS | L2CAP_EXTFEA_STREAM_MODE
1164e6e73fa499d09696c33390e91ec17cba488e49cbAndre Eisenbach                                          | L2CAP_EXTFEA_UCD_RECEPTION )) != 0 )
11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
11688fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_LE)
11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* optional data are not added for now */
11715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK);
11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1175d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (L2CAP_CONFORMANCE_TESTING == TRUE)
11765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, l2cb.test_info_resp);
11775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
11795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK | L2CAP_EXTFEA_FIXED_CHNLS);
11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
11815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT32_TO_STREAM (p, L2CAP_EXTFEA_SUPPORTED_MASK);
11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
11855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE)
11875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
11895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memset (p, 0, L2CAP_FIXED_CHNL_ARRAY_SIZE);
11905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p[0] = L2CAP_FIXED_CHNL_SIG_BIT;
11925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( L2CAP_EXTFEA_SUPPORTED_MASK & L2CAP_EXTFEA_UCD_RECEPTION )
11945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	p[0] |= L2CAP_FIXED_CHNL_CNCTLESS_BIT;
11955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
11975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
11985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            int xx;
11995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
1201693eee7bffb843ed8b0b0fa6cca4dfc9848f28bdyanlaijun            {
1202693eee7bffb843ed8b0b0fa6cca4dfc9848f28bdyanlaijun                /* Skip fixed channels not used on BR/EDR-ACL link */
1203693eee7bffb843ed8b0b0fa6cca4dfc9848f28bdyanlaijun                if((xx >= L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL) &&
1204693eee7bffb843ed8b0b0fa6cca4dfc9848f28bdyanlaijun                    (xx <= L2CAP_SMP_CID - L2CAP_FIRST_FIXED_CHNL))
1205693eee7bffb843ed8b0b0fa6cca4dfc9848f28bdyanlaijun                    continue;
1206693eee7bffb843ed8b0b0fa6cca4dfc9848f28bdyanlaijun
12075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
12088372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                   p[(xx + L2CAP_FIRST_FIXED_CHNL) / 8] |= 1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8);
1209693eee7bffb843ed8b0b0fa6cca4dfc9848f28bdyanlaijun            }
12105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
12125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE)
12145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
12165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_UCD_MTU);
12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
12195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED);  /* 'not supported' */
12215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
12245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
12275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_enqueue_ccb
12295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      queue CCB by priority. The first CCB is highest priority and
12315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is served at first. The CCB is queued to an LLCB or an LCB.
12325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
12345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
12365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_enqueue_ccb (tL2C_CCB *p_ccb)
12375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
12385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_ccb1;
12395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB_Q      *p_q = NULL;
12405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find out which queue the channel is on
12425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
12435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
12445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q = &p_ccb->p_lcb->ccb_queue;
12455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (!p_ccb->in_use) || (p_q == NULL) )
12475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1248a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("l2cu_enqueue_ccb  CID: 0x%04x ERROR in_use: %u  p_lcb: 0x%08x",
12495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb);
12505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
12515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1253a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_enqueue_ccb CID: 0x%04x  priority: %d",
12545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->local_cid, p_ccb->ccb_priority);
12555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the queue is empty, we go at the front */
12575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_q->p_first_ccb)
12585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_first_ccb  = p_q->p_last_ccb   = p_ccb;
12605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
12615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
12635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb1 = p_q->p_first_ccb;
12655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while (p_ccb1 != NULL)
12675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Insert new ccb at the end of the same priority. Lower number, higher priority */
12695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->ccb_priority < p_ccb1->ccb_priority)
12705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
12715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Are we at the head of the queue ? */
12725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_ccb1 == p_q->p_first_ccb)
12735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_q->p_first_ccb = p_ccb;
12745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
12755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_ccb1->p_prev_ccb->p_next_ccb  = p_ccb;
12765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_next_ccb  = p_ccb1;
12785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_prev_ccb  = p_ccb1->p_prev_ccb;
12795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb1->p_prev_ccb = p_ccb;
12805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
12815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
12825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb1 = p_ccb1->p_next_ccb;
12845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If we are lower then anyone in the list, we go at the end */
12875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_ccb1)
12885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* add new ccb at the end of the list */
12905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb->p_next_ccb = p_ccb;
12915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_next_ccb   = NULL;
12935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_prev_ccb   = p_q->p_last_ccb;
12945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb = p_ccb;
12955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
12995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Adding CCB into round robin service table of its LCB */
13005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
13015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if this is the first channel in this priority group */
13035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
13045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Set the first channel to this CCB */
13065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
13075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Set the next serving channel in this group to this CCB */
13085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
13095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* Initialize quota of this priority group based on its priority */
13105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
13115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* increase number of channels in this group */
13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb++;
13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
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**
13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_dequeue_ccb
13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      dequeue CCB from a queue
13245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          -
13265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
13285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
13295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB_Q      *p_q = NULL;
13315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1332a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_dequeue_ccb  CID: 0x%04x", p_ccb->local_cid);
13335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find out which queue the channel is on
13355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
13365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
13375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q = &p_ccb->p_lcb->ccb_queue;
13385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL) )
13405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1341a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("l2cu_dequeue_ccb  CID: 0x%04x ERROR in_use: %u  p_lcb: 0x%08x  p_q: 0x%08x  p_q->p_first_ccb: 0x%08x",
13425738f83aeb59361a0a2eda2460113f6dc919427The 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);
13435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
13445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
13475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Removing CCB from round robin service table of its LCB */
13485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->p_lcb != NULL)
13495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* decrease number of channels in this priority group */
13515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb--;
13525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if it was the last channel in the priority group */
13545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb == 0 )
13555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
13575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
13585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
13605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if it is the first channel of this group */
13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb == p_ccb )
13635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
13645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb->p_next_ccb;
13655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
13665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* if it is the next serving channel of this group */
13675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb == p_ccb )
13685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* simply, start serving from the first channel */
13705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb
13715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    = p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb;
13725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
13735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
13765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb == p_q->p_first_ccb)
13785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We are removing the first in a queue */
13805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_first_ccb = p_ccb->p_next_ccb;
13815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_q->p_first_ccb)
13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_first_ccb->p_prev_ccb = NULL;
13845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_q->p_last_ccb = NULL;
13865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb == p_q->p_last_ccb)
13885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We are removing the last in a queue */
13905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_last_ccb = p_ccb->p_prev_ccb;
13915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_q->p_last_ccb->p_next_ccb = NULL;
13925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
13945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* In the middle of a chain. */
13965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb->p_next_ccb = p_ccb->p_next_ccb;
13975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb->p_prev_ccb = p_ccb->p_prev_ccb;
13985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
14015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
14025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
14045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_change_pri_ccb
14065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description
14085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          -
14105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
14125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_change_pri_ccb (tL2C_CCB *p_ccb, tL2CAP_CHNL_PRIORITY priority)
14135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
14145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb->ccb_priority != priority)
14155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If CCB is not the only guy on the queue */
14175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL) )
14185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1419a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_DEBUG ("Update CCB list in logical link");
14205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Remove CCB from queue and re-queue it at new priority */
14225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_dequeue_ccb (p_ccb);
14235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->ccb_priority = priority;
14255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_enqueue_ccb (p_ccb);
14265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
14275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
14285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
14295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
14305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        	/* If CCB is the only guy on the queue, no need to re-enqueue */
14315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* update only round robin service data */
14325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 0;
14335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = NULL;
14345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = NULL;
14355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->ccb_priority = priority;
14375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_first_ccb = p_ccb;
14395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].p_serve_ccb = p_ccb;
14405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota = L2CAP_GET_PRIORITY_QUOTA(p_ccb->ccb_priority);
14415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].num_ccb = 1;
14425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
14435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
14445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
14465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
14485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_ccb
14505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function allocates a Channel Control Block and
14525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  attaches it to a link control block. The local CID
14535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is also assigned.
14545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB, or NULL if none
14565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1458d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, uint16_t cid)
14595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
14605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
14615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_prev;
14625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1463a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x", cid);
14645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!l2cb.p_free_ccb_first)
14665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
14675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If a CID was passed in, use that, else take the first free one */
14695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cid == 0)
14705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.p_free_ccb_first;
14725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
14735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
14755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_prev = NULL;
14775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = &l2cb.ccb_pool[cid - L2CAP_BASE_APPL_CID];
14795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb == l2cb.p_free_ccb_first)
14815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cb.p_free_ccb_first = p_ccb->p_next_ccb;
14825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
14835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
14845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (p_prev = l2cb.p_free_ccb_first; p_prev != NULL; p_prev = p_prev->p_next_ccb)
14855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
14865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_prev->p_next_ccb == p_ccb)
14875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
14885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_prev->p_next_ccb = p_ccb->p_next_ccb;
14895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if (p_ccb == l2cb.p_free_ccb_last)
14915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        l2cb.p_free_ccb_last = p_prev;
14925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
14945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
14955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
14965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_prev == NULL)
14975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
1498a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                L2CAP_TRACE_ERROR ("l2cu_allocate_ccb: could not find CCB for CID 0x%04x in the free list", cid);
14995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return NULL;
15005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
15015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
15025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_next_ccb = p_ccb->p_prev_ccb = NULL;
15055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1506d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_ccb->in_use = true;
15075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Get a CID for the connection */
1509d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_ccb->local_cid = L2CAP_BASE_APPL_CID + (uint16_t)(p_ccb - l2cb.ccb_pool);
15105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb = p_lcb;
15125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_rcb = NULL;
1513a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati    p_ccb->should_free_rcb = false;
15145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set priority then insert ccb into LCB queue (if we have an LCB) */
15165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ccb_priority = L2CAP_CHNL_PRIORITY_LOW;
15175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb)
15195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_enqueue_ccb (p_ccb);
15205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* clear what peer wants to configure */
15225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->peer_cfg_bits = 0;
15235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in default values for configuration */
15255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->our_cfg, 0, sizeof(tL2CAP_CFG_INFO));
15265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->peer_cfg, 0, sizeof(tL2CAP_CFG_INFO));
15275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put in default values for local/peer configurations */
15295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.flush_to              = p_ccb->peer_cfg.flush_to              = L2CAP_DEFAULT_FLUSH_TO;
15305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.mtu                   = p_ccb->peer_cfg.mtu                   = L2CAP_DEFAULT_MTU;
15315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.service_type      = p_ccb->peer_cfg.qos.service_type      = L2CAP_DEFAULT_SERV_TYPE;
15325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.token_rate        = p_ccb->peer_cfg.qos.token_rate        = L2CAP_DEFAULT_TOKEN_RATE;
15335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.token_bucket_size = p_ccb->peer_cfg.qos.token_bucket_size = L2CAP_DEFAULT_BUCKET_SIZE;
15345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.peak_bandwidth    = p_ccb->peer_cfg.qos.peak_bandwidth    = L2CAP_DEFAULT_PEAK_BANDWIDTH;
15355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.latency           = p_ccb->peer_cfg.qos.latency           = L2CAP_DEFAULT_LATENCY;
15365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.qos.delay_variation   = p_ccb->peer_cfg.qos.delay_variation   = L2CAP_DEFAULT_DELAY;
15375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->bypass_fcs = 0;
15395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO));
1540d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_ccb->peer_cfg_already_rejected = false;
15415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fcr_cfg_tries         = L2CAP_MAX_FCR_CFG_TRIES;
15425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
154378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_free(p_ccb->fcrb.ack_timer);
154478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    p_ccb->fcrb.ack_timer = alarm_new("l2c_fcrb.ack_timer");
15455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   /*  CSP408639 Fix: When L2CAP send amp move channel request or receive
15475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
15485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * request -> Stop retrans/monitor timer -> Change channel state to CST_AMP_MOVING. */
154978bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_free(p_ccb->fcrb.mon_retrans_timer);
155078bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    p_ccb->fcrb.mon_retrans_timer = alarm_new("l2c_fcrb.mon_retrans_timer");
15515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.preferred_mode  = L2CAP_FCR_BASIC_MODE;        /* Default mode for channel is basic mode */
15535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->ertm_info.allowed_modes   = L2CAP_FCR_CHAN_OPT_BASIC;    /* Default mode for channel is basic mode */
15541d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov    p_ccb->ertm_info.fcr_rx_buf_size = L2CAP_FCR_RX_BUF_SIZE;
15551d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov    p_ccb->ertm_info.fcr_tx_buf_size = L2CAP_FCR_TX_BUF_SIZE;
15561d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov    p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE;
15571d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov    p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
15585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->max_rx_mtu                = L2CAP_MTU_SIZE;
15591d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov    p_ccb->tx_mps                    = L2CAP_FCR_TX_BUF_SIZE - 32;
15605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15611a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_ccb->xmit_hold_q  = fixed_queue_new(SIZE_MAX);
15621a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_ccb->fcrb.srej_rcv_hold_q = fixed_queue_new(SIZE_MAX);
15631a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_ccb->fcrb.retrans_q = fixed_queue_new(SIZE_MAX);
15641a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_ccb->fcrb.waiting_for_ack_q = fixed_queue_new(SIZE_MAX);
15655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1566d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_ccb->cong_sent    = false;
15675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->buff_quota   = 2;                /* This gets set after config */
15685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If CCB was reserved Config_Done can already have some value */
15705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (cid == 0)
15715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->config_done  = 0;
15725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
15735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1574a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_allocate_ccb: cid 0x%04x config_done:0x%x", cid, p_ccb->config_done);
15755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->chnl_state   = CST_CLOSED;
15785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->flags        = 0;
15795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->tx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
15805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->rx_data_rate = L2CAP_CHNL_DATA_RATE_LOW;
15815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
1583d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_ccb->is_flushable = false;
15845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
15855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
158678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_free(p_ccb->l2c_ccb_timer);
158778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    p_ccb->l2c_ccb_timer = alarm_new("l2c.l2c_ccb_timer");
15885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_adjust_chnl_allocation ();
15905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_ccb);
15925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
15935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
15955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_start_post_bond_timer
15975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
15985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function starts the ACL Link inactivity timer after
15995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  dedicated bonding
16005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  This timer can be longer than the normal link inactivity
16015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  timer for some platforms.
16025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1603d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          bool     - true if idle timer started or disconnect initiated
1604d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen**                             false if there's one or more pending CCB's exist
16055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1607d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2cu_start_post_bond_timer (uint16_t handle)
16085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
16095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
16105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_lcb)
1612d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return (true);
16135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1614d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_lcb->is_bonding = false;
16155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Only start timer if no control blocks allocated */
16175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->ccb_queue.p_first_ccb != NULL)
1618d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return (false);
16195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If no channels on the connection, start idle timeout */
162178bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    if ((p_lcb->link_state == LST_CONNECTED) ||
162278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        (p_lcb->link_state == LST_CONNECTING) ||
162378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        (p_lcb->link_state == LST_DISCONNECTING)) {
162478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        period_ms_t timeout_ms = L2CAP_BONDING_TIMEOUT * 1000;
162578bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov
162678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        if (p_lcb->idle_timeout == 0) {
1627b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski            btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
1628b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski            p_lcb->link_state = LST_DISCONNECTING;
1629b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski            timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
16305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
163178bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms,
163278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                           l2c_lcb_timer_timeout, p_lcb,
163378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                           btu_general_alarm_queue);
1634d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return (true);
16355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1637d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    return (false);
16385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
16415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_ccb
16435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function releases a Channel Control Block. The timer
16455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is stopped, any attached buffers freed, and the CCB is removed
16465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  from the link control block.
16475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
16495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
16515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_ccb (tL2C_CCB *p_ccb)
16525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
16535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = p_ccb->p_lcb;
16545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = p_ccb->p_rcb;
16555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1656a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_release_ccb: cid 0x%04x  in_use: %u", p_ccb->local_cid, p_ccb->in_use);
16575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If already released, could be race condition */
16595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_ccb->in_use)
16605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
16615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_rcb && (p_rcb->psm != p_rcb->real_psm))
16635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btm_sec_clr_service_by_psm(p_rcb->psm);
16655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1666ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
1667a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati    if (p_ccb->should_free_rcb)
1668a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati    {
1669a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati        osi_free(p_rcb);
1670a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati        p_ccb->p_rcb = NULL;
1671a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati        p_ccb->should_free_rcb = false;
1672a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati    }
1673a3dd6f9607654a50195215deeb388919581752c7Sharvil Nanavati
1674ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr);
1675ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
167678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    /* Free the timer */
167778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_free(p_ccb->l2c_ccb_timer);
167878bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    p_ccb->l2c_ccb_timer = NULL;
16795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1680072bd753e6ac2a011421cd7e4a2e622ee7d052fcAndre Eisenbach    fixed_queue_free(p_ccb->xmit_hold_q, osi_free);
16811a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    p_ccb->xmit_hold_q = NULL;
16825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_cleanup (p_ccb);
16845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Channel may not be assigned to any LCB if it was just pre-reserved */
16865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_lcb) &&
16875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID)
16885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
16895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ||(p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID)
16905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
16915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         )
16925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       )
16935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_dequeue_ccb (p_ccb);
16955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Delink the CCB from the LCB */
16975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_lcb = NULL;
16985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Put the CCB back on the free pool */
17015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!l2cb.p_free_ccb_first)
17025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_first = p_ccb;
17045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last  = p_ccb;
17055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb     = NULL;
17065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb     = NULL;
17075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
17095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_next_ccb  = NULL;
17115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->p_prev_ccb  = l2cb.p_free_ccb_last;
17125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last->p_next_ccb = p_ccb;
17135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.p_free_ccb_last  = p_ccb;
17145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Flag as not in use */
1717d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_ccb->in_use = false;
17185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If no channels on the connection, start idle timeout */
17205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_lcb) && p_lcb->in_use && (p_lcb->link_state == LST_CONNECTED))
17215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_lcb->ccb_queue.p_first_ccb)
17235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
17245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2cu_no_dynamic_ccbs (p_lcb);
17255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
17265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
17275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
17285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Link is still active, adjust channel quotas. */
17295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            l2c_link_adjust_chnl_allocation ();
17305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
17315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_ccb_by_remote_cid
17375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active CCBs on a link for a match based
17395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  on the remote CID.
17405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched CCB, or NULL if no match
17425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1744d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, uint16_t remote_cid)
17455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
17475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If LCB is NULL, look through all active links */
17495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_lcb)
17505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return NULL;
17525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
17545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
17565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_ccb->in_use) && (p_ccb->remote_cid == remote_cid))
17575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_ccb);
17585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
17615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
17625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_allocate_rcb
17675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through the Registration Control Blocks for a free
17695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  one.
17705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to the RCB or NULL if not found
17725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1774d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_RCB *l2cu_allocate_rcb (uint16_t psm)
17755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
1777d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    xx;
17785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
17805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_rcb->in_use)
17825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1783d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_rcb->in_use = true;
17845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->psm    = psm;
17855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
17865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
17875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
17885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_rcb);
17895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
17905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no free RCB found */
17935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
17945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17966721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar/*******************************************************************************
17976721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
17986721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Function         l2cu_allocate_ble_rcb
17996721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
18006721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Description      Look through the BLE Registration Control Blocks for a free
18016721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**                  one.
18026721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
18036721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Returns          Pointer to the BLE RCB or NULL if not found
18046721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
18056721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar*******************************************************************************/
1806d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_RCB *l2cu_allocate_ble_rcb (uint16_t psm)
18076721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar{
18086721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    tL2C_RCB    *p_rcb = &l2cb.ble_rcb_pool[0];
1809d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    xx;
18106721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
18116721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++)
18126721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    {
18136721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        if (!p_rcb->in_use)
18146721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        {
1815d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_rcb->in_use = true;
18166721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            p_rcb->psm    = psm;
18176721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar#if (L2CAP_UCD_INCLUDED == TRUE)
18186721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            p_rcb->ucd.state = L2C_UCD_STATE_UNUSED;
18196721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar#endif
18206721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            return (p_rcb);
18216721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        }
18226721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    }
18236721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
18246721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    /* If here, no free RCB found */
18256721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    return (NULL);
18266721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar}
18275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_release_rcb
18315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Mark an RCB as no longet in use
18335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
18355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_release_rcb (tL2C_RCB *p_rcb)
18385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1839d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_rcb->in_use = false;
18405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_rcb->psm    = 0;
18415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_disconnect_chnl
18475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Disconnect a channel. Typically, this is due to either
18495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  receiving a bad configuration,  bad packet or max_retries expiring.
18505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_disconnect_chnl (tL2C_CCB *p_ccb)
18535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1854d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    local_cid = p_ccb->local_cid;
18555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (local_cid >= L2CAP_BASE_APPL_CID)
18575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        tL2CA_DISCONNECT_IND_CB   *p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb;
18595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1860a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - disconnect_chnl CID: 0x%04x", local_cid);
18615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_send_peer_disc_req (p_ccb);
18635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_release_ccb (p_ccb);
18655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1866d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        (*p_disc_cb)(local_cid, false);
18675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
18695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* failure on the AMP channel, probably need to disconnect ACL */
1871a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid);
18725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_rcb_by_psm
18795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through the Registration Control Blocks to see if
18815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  anyone registered to handle the PSM in question
18825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to the RCB or NULL if not found
18845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1886d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_RCB *l2cu_find_rcb_by_psm (uint16_t psm)
18875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
18885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_RCB    *p_rcb = &l2cb.rcb_pool[0];
1889d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    xx;
18905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_CLIENTS; xx++, p_rcb++)
18925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
18935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_rcb->in_use) && (p_rcb->psm == psm))
18945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_rcb);
18955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
18965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
18985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
18995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
19005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19016721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar/*******************************************************************************
19026721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
19036721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Function         l2cu_find_ble_rcb_by_psm
19046721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
19056721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Description      Look through the BLE Registration Control Blocks to see if
19066721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**                  anyone registered to handle the PSM in question
19076721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
19086721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Returns          Pointer to the BLE RCB or NULL if not found
19096721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
19106721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar*******************************************************************************/
1911d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_RCB *l2cu_find_ble_rcb_by_psm (uint16_t psm)
19126721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar{
19136721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    tL2C_RCB    *p_rcb = &l2cb.ble_rcb_pool[0];
1914d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    xx;
19156721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
19166721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    for (xx = 0; xx < BLE_MAX_L2CAP_CLIENTS; xx++, p_rcb++)
19176721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    {
19186721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        if ((p_rcb->in_use) && (p_rcb->psm == psm))
19196721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            return (p_rcb);
19206721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    }
19216721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
19226721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    /* If here, no match found */
19236721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    return (NULL);
19246721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar}
19255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
19275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_peer_cfg_req
19295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when the peer sends us a "config request"
19315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
19325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
19335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Note:  Negotiation of the FCR channel type is handled internally,
19355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                         all others are passed to the upper layer.
19365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1937d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          uint8_t - L2CAP_PEER_CFG_OK if passed to upper layer,
19385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                          L2CAP_PEER_CFG_UNACCEPTABLE if automatically responded to
19395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              because parameters are unnacceptable from a specification
19405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              point of view.
19415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                          L2CAP_PEER_CFG_DISCONNECT if no compatible channel modes
19425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                              between the two devices, and shall be closed.
19435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
19445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1945d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenuint8_t l2cu_process_peer_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
19465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1947d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    bool     mtu_ok      = true;
1948d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    bool     qos_type_ok = true;
1949d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    bool     flush_to_ok = true;
1950d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    bool     fcr_ok      = true;
1951d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t  fcr_status;
19525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Ignore FCR parameters for basic mode */
19545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_cfg->fcr_present)
19555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
19565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the MTU that our peer can receive */
19585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->mtu_present)
19595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Make sure MTU is at least the minimum */
19615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->mtu >= L2CAP_MIN_MTU)
19625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* In basic mode, limit the MTU to our buffer size */
1964d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            if ( (p_cfg->fcr_present == false) && (p_cfg->mtu > L2CAP_MTU_SIZE) )
19655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_cfg->mtu = L2CAP_MTU_SIZE;
19665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Save the accepted value in case of renegotiation */
19685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.mtu = p_cfg->mtu;
1969d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_ccb->peer_cfg.mtu_present = true;
19705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_MTU;
19715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Illegal MTU value */
19735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->mtu = L2CAP_MIN_MTU;
1975d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            mtu_ok     = false;
19765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload mtu from a previously accepted config request */
19795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.mtu_present)
19805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1981d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        p_cfg->mtu_present = true;
19825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu = p_ccb->peer_cfg.mtu;
19835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
19845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Verify that the flush timeout is a valid value (0 is illegal) */
19865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
19875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
19885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_cfg->flush_to)
19895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
19905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->flush_to = 0xFFFF;   /* Infinite retransmissions (spec default) */
1991d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            flush_to_ok     = false;
19925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Save the accepted value in case of renegotiation */
19945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1995d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_ccb->peer_cfg.flush_to_present = true;
19965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.flush_to = p_cfg->flush_to;
19975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FLUSH_TO;
19985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
19995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload flush_to from a previously accepted config request */
20015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.flush_to_present)
20025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2003d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        p_cfg->flush_to_present = true;
20045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->flush_to = p_ccb->peer_cfg.flush_to;
20055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the QOS settings the the peer is using */
20085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
20095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Make sure service type is not a reserved value; otherwise let upper
20115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project           layer decide if acceptable
20125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        */
20135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->qos.service_type <= GUARANTEED)
20145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.qos         = p_cfg->qos;
2016d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_ccb->peer_cfg.qos_present = true;
20175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_QOS;
20185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else    /* Illegal service type value */
20205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->qos.service_type = BEST_EFFORT;
2022d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            qos_type_ok             = false;
20235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Reload QOS from a previously accepted config request */
20265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_ccb->peer_cfg.qos_present)
20275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2028d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        p_cfg->qos_present = true;
20295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->qos         = p_ccb->peer_cfg.qos;
20305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((fcr_status = l2c_fcr_process_peer_cfg_req (p_ccb, p_cfg)) == L2CAP_PEER_CFG_DISCONNECT)
20335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Notify caller to disconnect the channel (incompatible modes) */
20355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->result = L2CAP_CFG_FAILED_NO_REASON;
20365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->mtu_present = p_cfg->qos_present = p_cfg->flush_to_present = 0;
20375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_DISCONNECT);
20395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    fcr_ok = (fcr_status == L2CAP_PEER_CFG_OK);
20425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Return any unacceptable parameters */
20445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (mtu_ok && flush_to_ok && qos_type_ok && fcr_ok)
20455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cu_adjust_out_mps (p_ccb);
20475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_OK);
20485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
20505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->result = L2CAP_CFG_UNACCEPTABLE_PARAMS;
20525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (mtu_ok)
2054d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_cfg->mtu_present = false;
20555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (flush_to_ok)
2056d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_cfg->flush_to_present = false;
20575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (qos_type_ok)
2058d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_cfg->qos_present = false;
20595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (fcr_ok)
2060d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_cfg->fcr_present = false;
20615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (L2CAP_PEER_CFG_UNACCEPTABLE);
20635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
20645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
20655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
20685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_peer_cfg_rsp
20705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when the peer sends us a "config response"
20725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
20735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
20745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
20765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
20775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
20785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_peer_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
20795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
20805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we wanted QoS and the peer sends us a positive response with QoS, use his values */
20815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_cfg->qos_present) && (p_ccb->our_cfg.qos_present) )
20825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos = p_cfg->qos;
20835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
20855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
20865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Save the retransmission and monitor timeout values */
20875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE)
20885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
20895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.fcr.rtrans_tout = p_cfg->fcr.rtrans_tout;
20905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->peer_cfg.fcr.mon_tout = p_cfg->fcr.mon_tout;
20915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
20925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
20935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Calculate the max number of packets for which we can delay sending an ack */
20945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.tx_win_sz < p_ccb->our_cfg.fcr.tx_win_sz)
20955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
20965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
20975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3;
20985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2099a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, max_held_acks: %d",
21005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks);
21015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
21035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
21055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_our_cfg_req
21075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when we send a "config request"
21095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
21105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
21115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
21135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
21155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_our_cfg_req (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
21165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
21175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb;
2118d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    hci_flush_to;
21195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Save the QOS settings we are using for transmit */
21215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->qos_present)
21225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2123d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        p_ccb->our_cfg.qos_present = true;
21245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.qos         = p_cfg->qos;
21255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->fcr_present)
21285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Override FCR options if attempting streaming or basic */
21305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE)
21315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memset(&p_cfg->fcr, 0, sizeof(tL2CAP_FCR_OPTS));
21325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
21335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* On BR/EDR, timer values are zero in config request */
21355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* On class 2 AMP, timer value in config request shall be non-0 processing time */
21365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*                 timer value in config response shall be greater than received processing time */
21375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_cfg->fcr.mon_tout = p_cfg->fcr.rtrans_tout = 0;
21385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE)
21405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0;
21415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Set the threshold to send acks (may be updated in the cfg response) */
21445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->fcrb.max_held_acks = p_cfg->fcr.tx_win_sz / 3;
21455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Include FCS option only if peer can handle it */
21475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_NO_CRC)
21485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* FCS check can be bypassed if peer also desires to bypass */
21505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->fcs_present && p_cfg->fcs == L2CAP_CFG_FCS_BYPASS)
21515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb->bypass_fcs |= L2CAP_CFG_FCS_OUR;
21525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
2154d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_cfg->fcs_present = false;
21555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
21575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE;
21595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.fcr.mode    = p_cfg->fcr.mode;
21625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->our_cfg.fcr_present = p_cfg->fcr_present;
21635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check the flush timeout. If it is lower than the current one used */
21655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* then we need to adjust the flush timeout sent to the controller   */
21665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_cfg->flush_to_present)
21675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
21685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_cfg->flush_to == 0)||(p_cfg->flush_to == L2CAP_NO_AUTOMATIC_FLUSH))
21695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* don't send invalid flush timeout */
21715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* SPEC: The sender of the Request shall specify its flush timeout value */
21725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /*       if it differs from the default value of 0xFFFF                  */
2173d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            p_cfg->flush_to_present = false;
21745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
21765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
21775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->our_cfg.flush_to = p_cfg->flush_to;
21785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb = p_ccb->p_lcb;
21795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_cfg->flush_to < p_lcb->link_flush_tout)
21815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
21825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_flush_tout = p_cfg->flush_to;
21835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If the timeout is within range of HCI, set the flush timeout */
21855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8))
21865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
21875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* Convert flush timeout to 0.625 ms units, with round */
21885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
21895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    btsnd_hcic_write_auto_flush_tout (p_lcb->handle, hci_flush_to);
21905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
21915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
21925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
21935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
21945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
21955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
21975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
21985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
21995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_our_cfg_rsp
22005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when we send the peer a "config response"
22025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  message. It extracts the configuration of interest and saves
22035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  it in the CCB.
22045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
22065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
22085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_our_cfg_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
22095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
22105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If peer wants QoS, we are allowed to change the values in a positive response */
22115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( (p_cfg->qos_present) && (p_ccb->peer_cfg.qos_present) )
22125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->peer_cfg.qos = p_cfg->qos;
22135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
2214d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        p_cfg->qos_present = false;
22155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_fcr_adj_our_rsp_options (p_ccb, p_cfg);
22175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
22185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
22215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_device_reset
22235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when reset of the device is
22255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  completed.  For all active connection simulate HCI_DISC
22265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
22285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
22305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_device_reset (void)
22315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
22325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
22335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
22345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
22365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
22375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->handle != HCI_INVALID_HANDLE))
22385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2239d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            l2c_link_hci_disc_comp (p_lcb->handle, (uint8_t) -1);
22405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
22415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2242d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    l2cb.is_ble_connecting = false;
22435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
22445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
22465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_create_conn
22485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initiates an acl connection via HCI
22505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2251d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          true if successful, false if get buffer fails.
22525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
22535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2254d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport)
22555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
22565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int             xx;
22575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB        *p_lcb_cur = &l2cb.lcb_pool[0];
2258d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (BTM_SCO_INCLUDED == TRUE)
2259d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    bool            is_sco_active;
22605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
22615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22620fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach    tBT_DEVICE_TYPE     dev_type;
22630fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach    tBLE_ADDR_TYPE      addr_type;
22640fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach
22650fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach
22660fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach    BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
22670fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach
22680fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach    if (transport == BT_TRANSPORT_LE)
22690fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach    {
227030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson        if (!controller_get_interface()->supports_ble())
2271d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            return false;
22723aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach
22730fc412c934cb930d5f5374ed53826c3bb01c25baAndre Eisenbach        p_lcb->ble_addr_type = addr_type;
22748fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        p_lcb->transport = BT_TRANSPORT_LE;
22755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (l2cble_create_conn(p_lcb));
22775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
22785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If there is a connection where we perform as a slave, try to switch roles
22805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project       for this connection */
22815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0, p_lcb_cur = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb_cur++)
22825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
22835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb_cur == p_lcb)
22845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
22855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb_cur->in_use) && (p_lcb_cur->link_role == HCI_ROLE_SLAVE))
22875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
22885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2289d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (BTM_SCO_INCLUDED == TRUE)
22905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* The LMP_switch_req shall be sent only if the ACL logical transport
22915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            is in active mode, when encryption is disabled, and all synchronous
22925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            logical transports on the same physical link are disabled." */
22935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
22945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Check if there is any SCO Active on this BD Address */
22955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            is_sco_active = btm_is_sco_active_by_bdaddr(p_lcb_cur->remote_bd_addr);
22965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2297a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_API ("l2cu_create_conn - btm_is_sco_active_by_bdaddr() is_sco_active = %s", \
2298d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                (is_sco_active == true) ? "true":"false");
22995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2300d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen            if (is_sco_active == true)
23015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue; /* No Master Slave switch not allowed when SCO Active */
23025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
23038fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            /*4_1_TODO check  if btm_cb.devcb.local_features to be used instead */
23043aa60544585b5fb0f35c1165539a4a859fc0f25cAndre Eisenbach            if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures()))
23055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
23065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* mark this lcb waiting for switch to be completed and
23075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   start switch on the other one */
23085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_state = LST_CONNECTING_WAIT_SWITCH;
23095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->link_role  = HCI_ROLE_MASTER;
23105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (BTM_SwitchRole (p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) == BTM_CMD_STARTED)
23125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
231378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                    alarm_set_on_queue(p_lcb->l2c_lcb_timer,
231478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                                       L2CAP_LINK_ROLE_SWITCH_TIMEOUT_MS,
231578bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                                       l2c_lcb_timer_timeout, p_lcb,
231678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                                       btu_general_alarm_queue);
2317d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    return (true);
23185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
23195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
23205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
23215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->link_state = LST_CONNECTING;
23245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (l2cu_create_conn_after_switch (p_lcb));
23265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
23275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
23295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_num_hi_priority
23315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Gets the number of high priority channels.
23335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns
23355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2337d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenuint8_t l2cu_get_num_hi_priority (void)
23385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2339d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t     no_hi = 0;
23405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
23415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
23425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
23445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
23455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
23465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
23475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            no_hi++;
23485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
23495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return no_hi;
23515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
23525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
23555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_create_conn_after_switch
23575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function initiates an acl connection via HCI
23595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  If switch required to create connection it is already done.
23605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2361d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          true if successful, false if get buffer fails.
23625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
23635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
23645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2365d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2cu_create_conn_after_switch (tL2C_LCB *p_lcb)
23665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2367d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t          allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
23685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_INQ_INFO    *p_inq_info;
2369d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t          page_scan_rep_mode;
2370d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t          page_scan_mode;
2371d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t         clock_offset;
2372d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t          *p_features;
2373d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t         num_acl = BTM_GetNumAclLinks();
23745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_lcb->remote_bd_addr);
2375d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t          no_hi_prio_chs = l2cu_get_num_hi_priority();
23765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_features = BTM_ReadLocalFeatures();
23785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2379a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_create_conn_after_switch :%d num_acl:%d no_hi: %d is_bonding:%d",
23805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.disallow_switch, num_acl, no_hi_prio_chs, p_lcb->is_bonding);
23815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* FW team says that we can participant in 4 piconets
23825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * typically 3 piconet + 1 for scanning.
23835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * We can enhance the code to count the number of piconets later. */
23845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( ((!l2cb.disallow_switch && (num_acl < 3)) || (p_lcb->is_bonding && (no_hi_prio_chs==0)))
23855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        && HCI_SWITCH_SUPPORTED(p_features))
23865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        allow_switch = HCI_CR_CONN_ALLOW_SWITCH;
23875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
23885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
23895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
23905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->link_state = LST_CONNECTING;
23915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
239286a56d303fdbed734549b181622ed74140113d2dZach Johnson    /* Check with the BT manager if details about remote device are known */
239386a56d303fdbed734549b181622ed74140113d2dZach Johnson    if ((p_inq_info = BTM_InqDbRead(p_lcb->remote_bd_addr)) != NULL)
23945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
239586a56d303fdbed734549b181622ed74140113d2dZach Johnson        page_scan_rep_mode = p_inq_info->results.page_scan_rep_mode;
239686a56d303fdbed734549b181622ed74140113d2dZach Johnson        page_scan_mode = p_inq_info->results.page_scan_mode;
2397d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        clock_offset = (uint16_t)(p_inq_info->results.clock_offset);
23985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
23995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
24005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
240186a56d303fdbed734549b181622ed74140113d2dZach Johnson        /* No info known. Use default settings */
240286a56d303fdbed734549b181622ed74140113d2dZach Johnson        page_scan_rep_mode = HCI_PAGE_SCAN_REP_MODE_R1;
240386a56d303fdbed734549b181622ed74140113d2dZach Johnson        page_scan_mode = HCI_MANDATARY_PAGE_SCAN_MODE;
24045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
240586a56d303fdbed734549b181622ed74140113d2dZach Johnson        clock_offset = (p_dev_rec) ? p_dev_rec->clock_offset : 0;
24065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
24075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2408b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski    btsnd_hcic_create_conn(p_lcb->remote_bd_addr,
2409b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski                           ( HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH1
2410b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski                           | HCI_PKT_TYPES_MASK_DM3 | HCI_PKT_TYPES_MASK_DH3
2411b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski                           | HCI_PKT_TYPES_MASK_DM5 | HCI_PKT_TYPES_MASK_DH5 ),
2412b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski                           page_scan_rep_mode,
2413b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski                           page_scan_mode,
2414b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski                           clock_offset,
2415b6ab9b3af6b8793ff781e0359a78611726ab2300Jakub Pawlowski                           allow_switch);
24165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
24185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
241978bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_set_on_queue(p_lcb->l2c_lcb_timer,
242078bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                       L2CAP_LINK_CONNECT_TIMEOUT_MS,
242178bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                       l2c_lcb_timer_timeout, p_lcb,
242278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                       btu_general_alarm_queue);
24235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2424d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    return (true);
24255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
24265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
24295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_state
24315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
24335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  LCB state.
24345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to first matched LCB, or NULL if no match
24365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
24385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state)
24395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2440d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    i;
24415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
24425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
24445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
24455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->link_state == state))
24465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
24485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
24495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
24505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
24525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
24535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
24545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
24575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_lcb_disconnecting
24595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      On each active lcb, check if the lcb is in disconnecting
24615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  state, or if there are no ccb's on the lcb (implying
24625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    idle timeout is running), or if last ccb on the link
24635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    is in disconnecting state.
24645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2465d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          true if any of above conditions met, false otherwise
24665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
24675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2468d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2cu_lcb_disconnecting (void)
24695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
24705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb;
24715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
2472d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t    i;
2473d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    bool        status = false;
24745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb = &l2cb.lcb_pool[0];
24765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++)
24785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
24795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb->in_use)
24805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
24815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* no ccbs on lcb, or lcb is in disconnecting state */
24825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((!p_lcb->ccb_queue.p_first_ccb) || (p_lcb->link_state == LST_DISCONNECTING))
24835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2484d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                status = true;
24855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
24865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
24875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* only one ccb left on lcb */
24885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if (p_lcb->ccb_queue.p_first_ccb == p_lcb->ccb_queue.p_last_ccb)
24895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
24905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb = p_lcb->ccb_queue.p_first_ccb;
24915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
24925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ((p_ccb->in_use) &&
24935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
24945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP)))
24955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
2496d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    status = true;
24975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
24985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
24995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
25005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
25015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
25035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
25075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_acl_priority
25095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Sets the transmission priority for a channel.
25115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  (For initial implementation only two values are valid.
25125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
25135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2514d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          true if a valid channel, else false
25155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
25175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2518d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2cu_set_acl_priority (BD_ADDR bd_addr, uint8_t priority, bool    reset_after_rs)
25195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB            *p_lcb;
2521d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t             *pp;
2522d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t              command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE];
2523d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t              vs_param;
25245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2525e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    APPL_TRACE_EVENT("SET ACL PRIORITY %d", priority);
25265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Find the link control block for the acl channel */
25288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
25295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2530a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("L2CAP - no LCB for L2CA_SetAclPriority");
2531d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return (false);
25325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
25335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (BTM_IS_BRCM_CONTROLLER())
25355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
25365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Called from above L2CAP through API; send VSC if changed */
25375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||
25385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              /* Called because of a master/slave role switch; if high resend VSC */
25395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ( reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH))
25405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
25415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            pp = command;
25425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            vs_param = (priority == L2CAP_PRIORITY_HIGH) ? HCI_BRCM_ACL_PRIORITY_HIGH : HCI_BRCM_ACL_PRIORITY_LOW;
25445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (pp, p_lcb->handle);
25465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT8_TO_STREAM  (pp, vs_param);
25475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            BTM_VendorSpecificCommand (HCI_BRCM_SET_ACL_PRIORITY, HCI_BRCM_ACL_PRIORITY_PARAM_SIZE, command, NULL);
25495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* Adjust lmp buffer allocation for this channel if priority changed */
25515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->acl_priority != priority)
25525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
25535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->acl_priority = priority;
25545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2c_link_adjust_allocation();
25555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
25565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
25575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2558d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    return(true);
25595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
25625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_non_flushable_pbf
25655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      set L2CAP_PKT_START_NON_FLUSHABLE if controller supoorts
25675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
25695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2571d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_set_non_flushable_pbf (bool    is_supported)
25725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (is_supported)
25745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.non_flushable_pbf = (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT);
25755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
25765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        l2cb.non_flushable_pbf = (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT);
25775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
25785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
25795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
25815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_resubmit_pending_sec_req
25835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called when required security procedures
25855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  are completed and any pending requests can be re-submitted.
25865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
25885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
25895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
25905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
25915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
25925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB        *p_lcb;
25935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_ccb;
25945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB        *p_next_ccb;
25955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int             xx;
25965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2597a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati    L2CAP_TRACE_DEBUG ("l2cu_resubmit_pending_sec_req  p_bda: 0x%08x", p_bda);
25985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
25995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we are called with a BDA, only resubmit for that BDA */
26005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_bda)
26015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26028fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
26035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If we don't have one, this is an error */
26055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_lcb)
26065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
26075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* For all channels, send the event through their FSMs */
26085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
26095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
26105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_next_ccb = p_ccb->p_next_ccb;
26115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
26125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
26135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
26155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2616a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_WARNING ("l2cu_resubmit_pending_sec_req - unknown BD_ADDR");
26175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
26205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* No BDA pasesed in, so check all links */
26225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for (xx = 0, p_lcb = &l2cb.lcb_pool[0]; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
26235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
26245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_lcb->in_use)
26255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
26265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* For all channels, send the event through their FSMs */
26275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_next_ccb)
26285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
26295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_next_ccb = p_ccb->p_next_ccb;
26305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    l2c_csm_execute (p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL);
26315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
26325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
26335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
26345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2637d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (L2CAP_CONFORMANCE_TESTING == TRUE)
26385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
26395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_info_rsp_mask
26415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function allows the script wrapper to change the
26435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  info resp mask for conformance testing.
26445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB, or NULL if none
26465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2648d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_set_info_rsp_mask (uint32_t mask)
26495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
26505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cb.test_info_resp = mask;
26515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif  /* L2CAP_CONFORMANCE_TESTING */
26535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
26555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_adjust_out_mps
26575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Sets our MPS based on current controller capabilities
26595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
26615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
26625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
26635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_adjust_out_mps (tL2C_CCB *p_ccb)
26645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2665d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t packet_size;
26665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* on the tx side MTU is selected based on packet size of the controller */
26685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    packet_size = btm_get_max_packet_size (p_ccb->p_lcb->remote_bd_addr);
26695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN))
26715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* something is very wrong */
2673a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_ERROR ("l2cu_adjust_out_mps bad packet size: %u  will use MPS: %u", packet_size, p_ccb->peer_cfg.fcr.mps);
26745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
26755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
26775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
26785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN);
26795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* We try to negotiate MTU that each packet can be split into whole
26815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        number of max packets.  For example if link is 1.2 max packet size is 339 bytes.
26825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        At first calculate how many whole packets it is.  MAX L2CAP is 1691 + 4 overhead.
26835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        1695, that will be 5 Dh5 packets.  Now maximum L2CAP packet is
26845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        5 * 339 = 1695. Minus 4 bytes L2CAP header 1691.
26855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        For EDR 2.0 packet size is 1027.  So we better send RFCOMM packet as 1 3DH5 packet
26875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        1 * 1027 = 1027.  Minus 4 bytes L2CAP header 1023.  */
26885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->peer_cfg.fcr.mps >= packet_size)
26895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps / packet_size * packet_size;
26905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
26915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps;
26925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2693a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_adjust_out_mps use %d   Based on peer_cfg.fcr.mps: %u  packet_size: %u",
26945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size);
26955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
26965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
26975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
26995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
27005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_initialize_fixed_ccb
27025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Initialize a fixed channel's CCB
27045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2705d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          true or false
27065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2708d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2cu_initialize_fixed_ccb (tL2C_LCB *p_lcb, uint16_t fixed_cid, tL2CAP_FCR_OPTS *p_fcr)
27095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
27105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
27115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
27125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If we already have a CCB, then simply return */
271491469270e26e4cfd5a77abbd20739045d04b5cafPavlin Radoslavov    p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
271591469270e26e4cfd5a77abbd20739045d04b5cafPavlin Radoslavov    if ((p_ccb != NULL) && p_ccb->in_use) {
271691469270e26e4cfd5a77abbd20739045d04b5cafPavlin Radoslavov        /*
271791469270e26e4cfd5a77abbd20739045d04b5cafPavlin Radoslavov         * NOTE: The "in_use" check is needed to ignore leftover entries
271891469270e26e4cfd5a77abbd20739045d04b5cafPavlin Radoslavov         * that have been already released by l2cu_release_ccb().
271991469270e26e4cfd5a77abbd20739045d04b5cafPavlin Radoslavov         */
2720d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return (true);
272191469270e26e4cfd5a77abbd20739045d04b5cafPavlin Radoslavov    }
27225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_ccb = l2cu_allocate_ccb (NULL, 0)) == NULL)
2724d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        return (false);
27255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
272678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    alarm_cancel(p_lcb->l2c_lcb_timer);
2727ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
27285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set CID for the connection */
27295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->local_cid  = fixed_cid;
27305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->remote_cid = fixed_cid;
27315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2732d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p_ccb->is_flushable = false;
27335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_fcr)
27355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
27365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Set the FCR parameters. For now, we will use default pools */
27375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->our_cfg.fcr = p_ccb->peer_cfg.fcr = *p_fcr;
27385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27391d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov        p_ccb->ertm_info.fcr_rx_buf_size  = L2CAP_FCR_RX_BUF_SIZE;
27401d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov        p_ccb->ertm_info.fcr_tx_buf_size  = L2CAP_FCR_TX_BUF_SIZE;
27411d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov        p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE;
27421d5b85924df3a114efe6588e857d0de3eb47b1d2Pavlin Radoslavov        p_ccb->ertm_info.user_tx_buf_size = L2CAP_USER_TX_BUF_SIZE;
27435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->fcrb.max_held_acks = p_fcr->tx_win_sz / 3;
27455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
27465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Link ccb to lcb and lcb to ccb */
27485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = p_ccb;
27495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->p_lcb = p_lcb;
27505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* There is no configuration, so if the link is up, the channel is up */
27525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->link_state == LST_CONNECTED)
27535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb->chnl_state = CST_OPEN;
27545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set the default idle timeout value to use */
27565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb->fixed_chnl_idle_tout = l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].default_idle_tout;
27575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
2758d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    return (true);
27595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
27605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
27625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_no_dynamic_ccbs
27645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Handles the case when there are no more dynamic CCBs. If there
27665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  are any fixed CCBs, start the longest of the fixed CCB timeouts,
27675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  otherwise start the default link idle timeout or disconnect.
27685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
27705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
27715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
27725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
27735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
27745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_STATUS     rc;
277578bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    period_ms_t     timeout_ms = p_lcb->idle_timeout * 1000;
277678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    bool            start_timeout = true;
27775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
27795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
27805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
27825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
278378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        if ((p_lcb->p_fixed_ccbs[xx] != NULL) &&
278478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000 > timeout_ms)) {
278578bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            timeout_ms = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000;
278678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        }
27875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
27885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
27895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the link is pairing, do not mess with the timeouts */
27915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcb->is_bonding)
27925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
27935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
279478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    if (timeout_ms == 0)
27955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2796a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG ("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link");
27975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
27985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
27995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (rc == BTM_CMD_STARTED)
28005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28018fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            l2cu_process_fixed_disc_cback(p_lcb);
28025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
280378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
28045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (rc == BTM_SUCCESS)
28065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28078fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            l2cu_process_fixed_disc_cback(p_lcb);
28085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* BTM SEC will make sure that link is release (probably after pairing is done) */
28095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
281078bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            start_timeout = false;
28115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2812763abdfe7983c8388c1fd0ce6aa05a44df11eacaJakub Pawlowski        else if (p_lcb->is_bonding)
28135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2814763abdfe7983c8388c1fd0ce6aa05a44df11eacaJakub Pawlowski            btsnd_hcic_disconnect(p_lcb->handle, HCI_ERR_PEER_USER);
28158fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            l2cu_process_fixed_disc_cback(p_lcb);
28165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->link_state = LST_DISCONNECTING;
281778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
28185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
28205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* probably no buffer to send disconnect */
282278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov            timeout_ms = BT_1SEC_TIMEOUT_MS;
28235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
282678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    if (start_timeout) {
282778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        L2CAP_TRACE_DEBUG("%s starting IDLE timeout: %d ms", __func__,
282878bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                          timeout_ms);
282978bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms,
283078bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                           l2c_lcb_timer_timeout, p_lcb,
283178bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov                           btu_general_alarm_queue);
283278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov    } else {
283378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov        alarm_cancel(p_lcb->l2c_lcb_timer);
28345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
28365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
28385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
28395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_process_fixed_chnl_resp
28415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      handle a fixed channel response (or lack thereof)
28435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  if the link failed, or a fixed channel response was
28445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  not received, the bitfield is all zeros.
28455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
28465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
28475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
28485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2849444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji     if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
2850444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji     {
2851444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji         /* ignore all not assigned BR/EDR channels */
2852444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji         p_lcb->peer_chnl_mask[0] &= (L2CAP_FIXED_CHNL_SIG_BIT| \
2853444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji                                      L2CAP_FIXED_CHNL_CNCTLESS_BIT| \
2854444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji                                      L2CAP_FIXED_CHNL_SMP_BR_BIT);
2855444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji     }
2856444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji     else
2857444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji         p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask;
28585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Tell all registered fixed channels about the connection */
28600b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji    for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
28615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
28628fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        /* skip sending LE fix channel callbacks on BR/EDR links */
28638fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
28648fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            xx + L2CAP_FIRST_FIXED_CHNL >= L2CAP_ATT_CID &&
28658fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            xx + L2CAP_FIRST_FIXED_CHNL <= L2CAP_SMP_CID)
28668fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            continue;
28675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
28685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
28698372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            if (p_lcb->peer_chnl_mask[(xx + L2CAP_FIRST_FIXED_CHNL) / 8]
28708372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                    & (1 << ((xx + L2CAP_FIRST_FIXED_CHNL) % 8)))
28715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
28725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_lcb->p_fixed_ccbs[xx])
28735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
28748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2875d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                        p_lcb->remote_bd_addr, true, 0, p_lcb->transport);
28765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2877ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            else
28785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
28798372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2880d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                        p_lcb->remote_bd_addr, false, p_lcb->disc_reason, p_lcb->transport);
2881ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
2882ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if (p_lcb->p_fixed_ccbs[xx])
2883ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
2884ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
2885ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    p_lcb->p_fixed_ccbs[xx] = NULL;
2886ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
28875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
28885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
28895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
28905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
28915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
28925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28938fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
28948fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta/*******************************************************************************
28958fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
28968fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Function         l2cu_process_fixed_disc_cback
28978fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
28988fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Description      send l2cap fixed channel disconnection callback to application
28998fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
29008fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
29018fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta** Returns          void
29028fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta**
29038fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta*******************************************************************************/
29048fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Battavoid l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
29058fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta{
29068fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#if (L2CAP_NUM_FIXED_CHNLS > 0)
29078fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
29080b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji    /* Select peer channels mask to use depending on transport */
2909d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t peer_channel_mask = p_lcb->peer_chnl_mask[0];
29100b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji
29110b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji    // For LE, reset the stored peer channel mask
29120b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji    if (p_lcb->transport == BT_TRANSPORT_LE)
29130b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji        p_lcb->peer_chnl_mask[0] = 0;
29140b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji
29150b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji    for (int xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
29168fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    {
29178fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_lcb->p_fixed_ccbs[xx])
29188fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        {
29197ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham            if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
29207ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham            {
29210b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji                tL2C_CCB *p_l2c_chnl_ctrl_block;
29220b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji                p_l2c_chnl_ctrl_block = p_lcb->p_fixed_ccbs[xx];
29237ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham                p_lcb->p_fixed_ccbs[xx] = NULL;
29240b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji                l2cu_release_ccb(p_l2c_chnl_ctrl_block);
29258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2926d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    p_lcb->remote_bd_addr, false, p_lcb->disc_reason, p_lcb->transport);
29277ae25156f4250af9d0e8cd8d559d916cfb847febPrerepa Viswanadham           }
29288fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        }
29290b47e0a35c16f5b7d77c30ec1c095ed92ff4fd74Satya Calloji        else if ( (peer_channel_mask & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
29308fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta               && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
29318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(xx + L2CAP_FIRST_FIXED_CHNL,
2932d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    p_lcb->remote_bd_addr, false, p_lcb->disc_reason, p_lcb->transport);
29338fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    }
29348fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta#endif
29358fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta}
29368fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
29375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
29385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_ble_par_req
29405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send a BLE parameter update request message
29425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
29435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
29455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2947d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_ble_par_req (tL2C_LCB *p_lcb, uint16_t min_int, uint16_t max_int,
2948d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        uint16_t latency, uint16_t timeout)
29495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
29505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
2951d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
29525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create an identifier for this packet */
29545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_lcb->id++;
29555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_adj_id (p_lcb, L2CAP_ADJ_ID);
29565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29578372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN,
29588372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                    L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->id)) == NULL )
29595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2960a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_req - no buffer");
29615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
29625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
29635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2964d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
29655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
29665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, min_int);
29685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, max_int);
29695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, latency);
29705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, timeout);
29715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
29735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
29745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
29765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_send_peer_ble_par_rsp
29785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Build and send a BLE parameter update response message
29805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to the peer.
29815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
29835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
29845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2985d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_ble_par_rsp (tL2C_LCB *p_lcb, uint16_t reason, uint8_t rem_id)
29865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
29875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR  *p_buf;
2988d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
29895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
29908372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz    if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN,
29918372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz                    L2CAP_CMD_BLE_UPDATE_RSP, rem_id)) == NULL )
29925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2993a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_par_rsp - no buffer");
29945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
29955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
29965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2997d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
29985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
29995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16_TO_STREAM (p, reason);
30015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
30035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
30045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
30056721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar/*******************************************************************************
30066721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30076721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Function         l2cu_send_peer_ble_credit_based_conn_req
30086721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30096721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Description      Build and send a BLE packet to establish LE connection oriented
30106721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**                  L2CAP channel.
30116721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30126721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Returns          void
30136721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30146721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar*******************************************************************************/
30156721232129f137ab024d9b95fc1094a714bc4c01Navin Kocharvoid l2cu_send_peer_ble_credit_based_conn_req (tL2C_CCB *p_ccb)
30166721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar{
30176721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    BT_HDR  *p_buf;
3018d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
30196721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    tL2C_LCB *p_lcb = NULL;
3020d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t mtu;
3021d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t mps;
3022d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint16_t initial_credit;
30236721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30246721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if (!p_ccb)
30256721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
30266721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_lcb = p_ccb->p_lcb;
30276721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30286721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    /* Create an identifier for this packet */
30296721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_ccb->p_lcb->id++;
30306721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
30316721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30326721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_ccb->local_id = p_ccb->p_lcb->id;
30336721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30346721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN,
30356721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ, p_lcb->id)) == NULL )
30366721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    {
30376721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
30386721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
30396721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    }
30406721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
3041d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
30426721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
30436721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30446721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    mtu = p_ccb->local_conn_cfg.mtu;
30456721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    mps = p_ccb->local_conn_cfg.mps;
30466721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    initial_credit = p_ccb->local_conn_cfg.credits;
30476721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30486721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    L2CAP_TRACE_DEBUG ("l2cu_send_peer_ble_credit_based_conn_req PSM:0x%04x local_cid:%d\
30496721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                mtu:%d mps:%d initial_credit:%d", p_ccb->p_rcb->real_psm,\
30506721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                p_ccb->local_cid, mtu, mps, initial_credit);
30516721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30526721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->p_rcb->real_psm);
30536721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->local_cid);
30546721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, mtu);
30556721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, mps);
30566721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, initial_credit);
30576721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30586721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
30596721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar}
30606721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30616721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar/*******************************************************************************
30626721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30636721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Function         l2cu_reject_ble_connection
30646721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30656721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Description      Build and send an L2CAP "Credit based connection res" message
30666721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**                  to the peer. This function is called for non-success cases.
30676721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30686721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Returns          void
30696721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30706721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar*******************************************************************************/
3071d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_reject_ble_connection (tL2C_LCB *p_lcb, uint8_t rem_id, uint16_t result)
30726721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar{
30736721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    BT_HDR  *p_buf;
3074d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
30756721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30766721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if ((p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
30776721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, rem_id)) == NULL )
30786721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    {
30796721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        L2CAP_TRACE_WARNING ("l2cu_reject_ble_connection - no buffer");
30806721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
30816721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    }
30826721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
3083d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
30846721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
30856721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30866721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, 0);                    /* Local CID of 0   */
30876721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, 0);                    /* MTU */
30886721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, 0);                    /* MPS */
30896721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, 0);                    /* initial credit */
30906721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, result);
30916721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30926721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
30936721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar}
30946721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
30956721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar/*******************************************************************************
30966721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30976721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Function         l2cu_send_peer_ble_credit_based_conn_res
30986721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
30996721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Description      Build and send an L2CAP "Credit based connection res" message
31006721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**                  to the peer. This function is called in case of success.
31016721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31026721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Returns          void
31036721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31046721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar*******************************************************************************/
3105d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_ble_credit_based_conn_res (tL2C_CCB *p_ccb, uint16_t result)
31066721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar{
31076721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    BT_HDR  *p_buf;
3108d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
31096721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31106721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    L2CAP_TRACE_DEBUG ("l2cu_send_peer_ble_credit_based_conn_res");
31116721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if ((p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN,
31126721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id)) == NULL )
31136721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    {
31146721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_res - no buffer");
31156721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
31166721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    }
31176721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
3118d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
31196721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
31206721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31216721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->local_cid);                      /* Local CID */
31226721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->local_conn_cfg.mtu);             /* MTU */
31236721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->local_conn_cfg.mps);             /* MPS */
31246721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->local_conn_cfg.credits);         /* initial credit */
31256721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, result);
31266721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31276721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
31286721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar}
31296721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31306721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar/*******************************************************************************
31316721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31326721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Function         l2cu_send_peer_ble_flow_control_credit
31336721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31346721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Description      Build and send a BLE packet to give credits to peer device
31356721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**                  for LE connection oriented L2CAP channel.
31366721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31376721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Returns          void
31386721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31396721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar*******************************************************************************/
3140d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid l2cu_send_peer_ble_flow_control_credit(tL2C_CCB *p_ccb, uint16_t credit_value)
31416721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar{
31426721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    BT_HDR  *p_buf;
3143d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
31446721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    tL2C_LCB *p_lcb = NULL;
31456721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31466721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if (!p_ccb)
31476721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
31486721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_lcb = p_ccb->p_lcb;
31496721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31506721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    /* Create an identifier for this packet */
31516721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_ccb->p_lcb->id++;
31526721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
31536721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31546721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_ccb->local_id = p_ccb->p_lcb->id;
31556721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31566721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if ((p_buf = l2cu_build_header (p_lcb, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN,
31576721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    L2CAP_CMD_BLE_FLOW_CTRL_CREDIT, p_lcb->id)) == NULL )
31586721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    {
31596721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_conn_req - no buffer");
31606721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
31616721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    }
31626721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
3163d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
31646721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
31656721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31666721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->local_cid);
31676721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, credit_value);
31686721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31696721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
31706721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar}
31716721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31726721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar/*******************************************************************************
31736721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31746721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Function         l2cu_send_peer_ble_credit_based_conn_req
31756721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31766721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Description      Build and send a BLE packet to disconnect LE connection oriented
31776721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**                  L2CAP channel.
31786721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31796721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar** Returns          void
31806721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar**
31816721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar*******************************************************************************/
31826721232129f137ab024d9b95fc1094a714bc4c01Navin Kocharvoid l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB *p_ccb)
31836721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar{
31846721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    BT_HDR  *p_buf;
3185d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t *p;
31866721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    tL2C_LCB *p_lcb = NULL;
31876721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    L2CAP_TRACE_DEBUG ("%s",__func__);
31886721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31896721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if (!p_ccb)
31906721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
31916721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_lcb = p_ccb->p_lcb;
31926721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31936721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    /* Create an identifier for this packet */
31946721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_ccb->p_lcb->id++;
31956721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2cu_adj_id(p_ccb->p_lcb, L2CAP_ADJ_ID);
31966721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
31976721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    p_ccb->local_id = p_ccb->p_lcb->id;
31986721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar     if ((p_buf = l2cu_build_header (p_lcb, L2CAP_DISC_REQ_LEN,
31996721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    L2CAP_CMD_DISC_REQ, p_lcb->id)) == NULL )
32006721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    {
32016721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        L2CAP_TRACE_WARNING ("l2cu_send_peer_ble_credit_based_disconn_req - no buffer");
32026721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        return;
32036721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    }
32046721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
3205d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE +
32066721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                               L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD;
32076721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
32086721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p, p_ccb->remote_cid);
32096721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    UINT16_TO_STREAM (p,p_ccb->local_cid);
32106721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
32116721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    l2c_link_check_send_pkts (p_lcb, NULL, p_buf);
32126721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar}
32135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
32165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Functions used by both Full and Light Stack
32175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project********************************************************************************/
32185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
32205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_lcb_by_handle
32225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active LCBs for a match based on the
32245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  HCI handle.
32255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched LCB, or NULL if no match
32275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3229d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_LCB  *l2cu_find_lcb_by_handle (uint16_t handle)
32305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
32315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
32325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
32335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
32355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->in_use) && (p_lcb->handle == handle))
32375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (p_lcb);
32395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
32415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If here, no match found */
32435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (NULL);
32445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
32455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
32475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_find_ccb_by_cid
32495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Look through all active CCBs on a link for a match based
32515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  on the local CID. If passed the link pointer is NULL, all
32525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  active links are searched.
32535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to matched CCB, or NULL if no match
32555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
32565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3257d19e0785e662e640191a075eda07acce61c2aedaMarie JanssentL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, uint16_t local_cid)
32585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
32595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb = NULL;
32605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
3261d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t xx;
32625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
32635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (local_cid >= L2CAP_BASE_APPL_CID)
32655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* find the associated CCB by "index" */
32675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        local_cid -= L2CAP_BASE_APPL_CID;
32685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (local_cid >= MAX_L2CAP_CHANNELS)
32705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
32715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.ccb_pool + local_cid;
32735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
32745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* make sure the CCB is in use */
32755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_ccb->in_use)
32765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = NULL;
32785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* make sure it's for the same LCB */
32805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else if (p_lcb && p_lcb != p_ccb->p_lcb)
32815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = NULL;
32835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
32855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
32865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
32875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
32885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* searching fixed channel */
32895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_ccb = l2cb.ccb_pool;
32905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for ( xx = 0; xx < MAX_L2CAP_CHANNELS; xx++ )
32915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
32925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_ccb->local_cid == local_cid)
32935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              &&(p_ccb->in_use)
32945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              &&(p_lcb == p_ccb->p_lcb))
32955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
32965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
32975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_ccb++;
32985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
32995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( xx >= MAX_L2CAP_CHANNELS )
33005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
33015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
33025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
33035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_ccb);
33055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
33065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
33085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
33105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_channel_in_rr
33125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next channel to send on a link. It also adjusts the
33145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB queue to do a basic priority and round-robin scheduling.
33155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB or NULL
33175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
33185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
33195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tL2C_CCB *l2cu_get_next_channel_in_rr(tL2C_LCB *p_lcb)
33205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
33215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_serve_ccb = NULL;
33225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
33235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i, j;
33255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* scan all of priority until finding a channel to serve */
33275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for ( i = 0; (i < L2CAP_NUM_CHNL_PRIORITY)&&(!p_serve_ccb); i++ )
33285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
33295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* scan all channel within serving priority group until finding a channel to serve */
33305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for ( j = 0; (j < p_lcb->rr_serv[p_lcb->rr_pri].num_ccb)&&(!p_serve_ccb); j++)
33315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
33325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* scaning from next serving channel */
33335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb;
33345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (!p_ccb)
33365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3337a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                L2CAP_TRACE_ERROR("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri);
33385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return NULL;
33395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
33405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3341a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati            L2CAP_TRACE_DEBUG("RR scan pri=%d, lcid=0x%04x, q_cout=%d",
33421a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                              p_ccb->ccb_priority, p_ccb->local_cid,
33431a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                              fixed_queue_length(p_ccb->xmit_hold_q));
33445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* store the next serving channel */
33465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* this channel is the last channel of its priority group */
33475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (( p_ccb->p_next_ccb == NULL )
33485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              ||( p_ccb->p_next_ccb->ccb_priority != p_ccb->ccb_priority ))
33495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
33505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* next serving channel is set to the first channel in the group */
33515738f83aeb59361a0a2eda2460113f6dc919427The 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;
33525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
33535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else
33545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
33555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* next serving channel is set to the next channel in the group */
33565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb = p_ccb->p_next_ccb;
33575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
33585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->chnl_state != CST_OPEN)
33605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue;
33615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33626721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
33635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
33646721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                L2CAP_TRACE_DEBUG("%s : Connection oriented channel",__func__);
33656721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
33665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
33675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33686721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            }
33696721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            else
33706721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            {
33716721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                /* eL2CAP option in use */
33726721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
33735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
33746721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
33755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
33765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33776721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
33786721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    {
33796721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                        if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
33806721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                            continue;
33816721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
33826721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                        /* If in eRTM mode, check for window closure */
33836721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                        if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
33846721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                            continue;
33856721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    }
33866721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                }
33876721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                else
33886721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                {
33896721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                    if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
33905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        continue;
33915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
33925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
33935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
33945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* found a channel to serve */
33955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_serve_ccb = p_ccb;
33965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* decrease quota of its priority group */
33975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_serv[p_lcb->rr_pri].quota--;
33985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
33995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if there is no more quota of the priority group or no channel to have data to send */
34015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_lcb->rr_serv[p_lcb->rr_pri].quota == 0)||(!p_serve_ccb))
34025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
34035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* serve next priority group */
34045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_pri = (p_lcb->rr_pri + 1) % L2CAP_NUM_CHNL_PRIORITY;
34055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* initialize its quota */
34065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_lcb->rr_serv[p_lcb->rr_pri].quota = L2CAP_GET_PRIORITY_QUOTA(p_lcb->rr_pri);
34075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
34085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
34095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_serve_ccb)
34115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3412a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati        L2CAP_TRACE_DEBUG("RR service pri=%d, quota=%d, lcid=0x%04x",
34135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_serve_ccb->ccb_priority,
34145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota,
34155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            p_serve_ccb->local_cid );
34165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
34175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_serve_ccb;
34195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
34205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
34225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
34245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_channel
34265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next channel to send on a link bassed on priority
34285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  scheduling.
34295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to CCB or NULL
34315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
34335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tL2C_CCB *l2cu_get_next_channel(tL2C_LCB *p_lcb)
34345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
34355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
34365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Get the first CCB with data to send.
34385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
34395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
34405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
34415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->chnl_state != CST_OPEN)
34425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
34435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
34455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
34465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34471a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        if (!fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
34485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return p_ccb;
34495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34501a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
34515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
34525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If in eRTM mode, check for window closure */
34545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
34555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
34565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If here, we found someone */
34585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return p_ccb;
34595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
34605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
34625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
34635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
34645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
34665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_get_next_buffer_to_send
34685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      get the next buffer to send on a link. It also adjusts the
34705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  CCB queue to do a basic priority and round-robin scheduling.
34715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          pointer to buffer or NULL
34735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
34745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
34755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
34765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
34775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tL2C_CCB    *p_ccb;
34785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR      *p_buf;
34795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Highest priority are fixed channels */
34815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0)
34825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int         xx;
34835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
34855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
34865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_ccb = p_lcb->p_fixed_ccbs[xx]) == NULL)
34875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            continue;
34885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* eL2CAP option in use */
34905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
34915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
34925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (p_ccb->fcrb.wait_ack || p_ccb->fcrb.remote_busy)
34935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                continue;
34945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
34955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* No more checks needed if sending from the reatransmit queue */
34961a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            if (fixed_queue_is_empty(p_ccb->fcrb.retrans_q))
34975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
34981a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                if (fixed_queue_is_empty(p_ccb->xmit_hold_q))
34995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
35005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* If in eRTM mode, check for window closure */
35025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) && (l2c_fcr_is_flow_controlled (p_ccb)) )
35035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    continue;
35045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
35055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) != NULL)
35075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3508493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                l2cu_check_channel_congestion (p_ccb);
35095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_set_acl_hci_header (p_buf, p_ccb);
35105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_buf);
35115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
35125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
35135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
35145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
35151a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            if (!fixed_queue_is_empty(p_ccb->xmit_hold_q))
35165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
35171a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
3518ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if(NULL == p_buf)
3519ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
3520a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati                    L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
3521ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    return (NULL);
3522ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
3523444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji                /* send tx complete */
3524444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji                if (l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)
3525444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji                    (*l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)(p_ccb->local_cid, 1);
3526444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
3527493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                l2cu_check_channel_congestion (p_ccb);
35285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                l2cu_set_acl_hci_header (p_buf, p_ccb);
35295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return (p_buf);
35305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
35315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
35325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
35335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
35345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
35365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* get next serving channel in round-robin */
35375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb  = l2cu_get_next_channel_in_rr( p_lcb );
35385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
35395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_ccb  = l2cu_get_next_channel( p_lcb );
35405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
35415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Return if no buffer */
35435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_ccb == NULL)
35445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (NULL);
35455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35466721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar    if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
35475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
35486721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        /* Check credits */
35496721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        if(p_ccb->peer_conn_cfg.credits == 0)
35506721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        {
35516721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            L2CAP_TRACE_DEBUG("%s No credits to send packets",__func__);
35526721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            return NULL;
35536721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        }
35546721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        if ((p_buf = l2c_lcc_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL)
35555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (NULL);
35566721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar
35576721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        p_ccb->peer_conn_cfg.credits--;
35585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
35595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
35605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
35616721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
3562ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
35636721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            if ((p_buf = l2c_fcr_get_next_xmit_sdu_seg(p_ccb, 0)) == NULL)
35646721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                return (NULL);
35656721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        }
35666721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        else
35676721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar        {
35686721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
35696721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            if(NULL == p_buf)
35706721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            {
35716721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send() #2: No data to be sent");
35726721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar                return (NULL);
35736721232129f137ab024d9b95fc1094a714bc4c01Navin Kochar            }
3574ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
35755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
35765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35775738f83aeb59361a0a2eda2460113f6dc919427The 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) )
35785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, 1);
35795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_check_channel_congestion (p_ccb);
35825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    l2cu_set_acl_hci_header (p_buf, p_ccb);
35845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (p_buf);
35865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
35875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
35885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
35895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
35905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_set_acl_hci_header
35915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
35925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Set HCI handle for ACL packet
35935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
35945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
35955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
35965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
35975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb)
35985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3599d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t     *p;
36005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
36015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Set the pointer to the beginning of the data minus 4 bytes for the packet header */
3602d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    p = (uint8_t *)(p_buf + 1) + p_buf->offset - HCI_DATA_PREAMBLE_SIZE;
36035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
36048fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
36055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3606eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT));
3607eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh
360830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson        uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_ble();
36095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The HCI transport will segment the buffers. */
361030e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson        if (p_buf->len > acl_data_size)
36115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
361230e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson            UINT16_TO_STREAM (p, acl_data_size);
36135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
36145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
36155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
36165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, p_buf->len);
36175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
361884baa7f16e830394408278dbb8c508dd9fa02887Myles Watson    }
36195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
36205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3621eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
3622eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        if ( (((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_CH_BASED) && (p_ccb->is_flushable))
3623eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh                || ((p_buf->layer_specific & L2CAP_FLUSHABLE_MASK) == L2CAP_FLUSHABLE_PKT) )
3624eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        {
3625eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh            UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3626eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        }
3627eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        else
3628eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        {
3629eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh            UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | l2cb.non_flushable_pbf);
3630eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        }
3631eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#else
3632eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh        UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
3633eb29aed689d70decec163e41c68200bf8fb3d9afRichie Hsieh#endif
36345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
363530e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson        uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic();
36365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* The HCI transport will segment the buffers. */
363730e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson        if (p_buf->len > acl_data_size)
36385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
363930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson            UINT16_TO_STREAM (p, acl_data_size);
36405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
36415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
36425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
36435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            UINT16_TO_STREAM (p, p_buf->len);
36445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
36455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
36465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->offset -= HCI_DATA_PREAMBLE_SIZE;
36475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf->len    += HCI_DATA_PREAMBLE_SIZE;
36485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
36495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
36505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
36515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
36525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         l2cu_check_channel_congestion
36535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
36545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      check if any change in congestion status
36555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
36565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          None
36575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
36585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
36595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
36605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
36611a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    size_t q_count = fixed_queue_length(p_ccb->xmit_hold_q);
36625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
36635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
36645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
36655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
36661a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        q_count += fixed_queue_length(p_ccb->p_lcb->ucd_out_sec_pending_q);
36675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
36685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
36695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the CCB queue limit is subject to a quota, check for congestion */
36705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* if this channel has outgoing traffic */
3671493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach    if (p_ccb->buff_quota != 0)
36725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
36735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If this channel was congested */
36745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ( p_ccb->cong_sent )
36755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
36765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* If the channel is not congested now, tell the app */
36775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (q_count <= (p_ccb->buff_quota / 2))
36785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3679d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                p_ccb->cong_sent = false;
3680493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
36815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3682d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (false), CID: 0x%04x  xmit_hold_q.count: %u  buff_quota: %u",
36835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      p_ccb->local_cid, q_count, p_ccb->buff_quota);
36845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
36855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    /* Prevent recursive calling */
3686d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    l2cb.is_cong_cback_context = true;
3687d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, false);
3688d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    l2cb.is_cong_cback_context = false;
36895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
36905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
3691493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
36925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
36935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
36945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3695d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                        L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (false), SecPendingQ:%u,XmitQ:%u,Quota:%u",
36961a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                                           fixed_queue_length(p_ccb->p_lcb->ucd_out_sec_pending_q),
36971a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                                           fixed_queue_length(p_ccb->xmit_hold_q),
36981a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                                           p_ccb->buff_quota);
3699d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, false );
37005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
37015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
37025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3703493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#if (L2CAP_NUM_FIXED_CHNLS > 0)
3704493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else
3705493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                {
3706d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    uint8_t xx;
3707493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
3708493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    {
3709493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
3710493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        {
3711493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3712d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                                (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, false);
3713493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            break;
3714493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        }
3715493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    }
3716493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                }
3717493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#endif
37185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
37195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
37205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
37215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
37225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* If this channel was not congested but it is congested now, tell the app */
37235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (q_count > p_ccb->buff_quota)
37245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3725d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                p_ccb->cong_sent = true;
3726493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
37275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3728d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (true),CID:0x%04x,XmitQ:%u,Quota:%u",
37295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        p_ccb->local_cid, q_count, p_ccb->buff_quota);
37305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3731d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, true);
37325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
37335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_UCD_INCLUDED == TRUE)
3734493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
37355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
37365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
37375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3738d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                        L2CAP_TRACE_DEBUG("L2CAP - Calling UCD CongestionStatus_Cb (true), SecPendingQ:%u,XmitQ:%u,Quota:%u",
37391a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                                          fixed_queue_length(p_ccb->p_lcb->ucd_out_sec_pending_q),
37401a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                                          fixed_queue_length(p_ccb->xmit_hold_q),
37411a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                                          p_ccb->buff_quota);
3742d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                        p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, true );
37435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
37445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
37455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
3746493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#if (L2CAP_NUM_FIXED_CHNLS > 0)
3747493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                else
3748493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                {
3749d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                    uint8_t xx;
3750493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
3751493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    {
3752493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
3753493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        {
3754493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
3755d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen                                (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, true);
3756493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                            break;
3757493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                        }
3758493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                    }
3759493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach                }
3760493a98a8de29a35808db28470736819af5fd22d2Andre Eisenbach#endif
37615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
37625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
37635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
37645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
37655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3766494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai/*******************************************************************************
3767494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai**
3768494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai** Function         l2cu_is_ccb_active
3769494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai**
3770494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai** Description      Check if Channel Control Block is in use or released
3771494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai**
3772d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen** Returns          bool    - true if Channel Control Block is in use
3773d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen**                            false if p_ccb is null or is released.
3774494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai**
3775494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai*******************************************************************************/
3776d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenbool    l2cu_is_ccb_active (tL2C_CCB *p_ccb)
3777494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai{
3778494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai    return (p_ccb && p_ccb->in_use);
3779494b510b9bdf5bf9bb8b74181a8f640e54e6cd40Gurpreet Ghai}
3780