15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2003-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 module contains action functions of the link control state machine. 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h> 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avct_api.h" 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "avct_int.h" 28258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h" 29911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_target.h" 30911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_types.h" 31911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "bt_utils.h" 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h" 33d7ffd64accbd50a27289a388856e56244ccbb5daMyles Watson#include "osi/include/osi.h" 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* packet header length lookup table */ 36911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonconst uint8_t avct_lcb_pkt_type_len[] = {AVCT_HDR_LEN_SINGLE, 37911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_HDR_LEN_START, AVCT_HDR_LEN_CONT, 38911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_HDR_LEN_END}; 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 41ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 42ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_msg_asmbl 43ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 44ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Reassemble incoming message. 45ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 46ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 47ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Pointer to reassembled message; NULL if no message 48ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * available. 49ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 50ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 51911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) { 52911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t* p; 53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t pkt_type; 54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BT_HDR* p_ret; 55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* parse the message header */ 57911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p = (uint8_t*)(p_buf + 1) + p_buf->offset; 58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pkt_type = AVCT_PKT_TYPE(p); 59911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* quick sanity check on length */ 61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_buf->len < avct_lcb_pkt_type_len[pkt_type]) { 62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free(p_buf); 63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("Bad length during reassembly"); 64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ret = NULL; 65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* single packet */ 67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else if (pkt_type == AVCT_PKT_TYPE_SINGLE) { 68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if reassembly in progress drop message and process new single */ 69911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_lcb->p_rx_msg != NULL) 70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("Got single during reassembly"); 71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free_and_reset((void**)&p_lcb->p_rx_msg); 73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ret = p_buf; 75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* start packet */ 77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else if (pkt_type == AVCT_PKT_TYPE_START) { 78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if reassembly in progress drop message and process new start */ 79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_lcb->p_rx_msg != NULL) 80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("Got start during reassembly"); 81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free(p_lcb->p_rx_msg); 83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* 85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * Allocate bigger buffer for reassembly. As lower layers are 86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * not aware of possible packet size after reassembly, they 87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * would have allocated smaller buffer. 88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson */ 89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); 90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy(p_lcb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len); 91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* Free original buffer */ 93911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free(p_buf); 94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* update p to point to new buffer */ 96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p = (uint8_t*)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset; 97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* copy first header byte over nosp */ 99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson *(p + 1) = *p; 100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* set offset to point to where to copy next */ 102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg->offset += p_lcb->p_rx_msg->len; 103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* adjust length for packet header */ 105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg->len -= 1; 106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ret = NULL; 108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* continue or end */ 110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else { 111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if no reassembly in progress drop message */ 112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_lcb->p_rx_msg == NULL) { 113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free(p_buf); 114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("Pkt type=%d out of order", pkt_type); 115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ret = NULL; 116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* get size of buffer holding assembled message */ 118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* 119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * NOTE: The buffer is allocated above at the beginning of the 120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE. 121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson */ 122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR); 123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 124911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* adjust offset and len of fragment for header byte */ 125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->offset += AVCT_HDR_LEN_CONT; 126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->len -= AVCT_HDR_LEN_CONT; 127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* verify length */ 129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len) { 130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* won't fit; free everything */ 131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("%s: Fragmented message too big!", __func__); 132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free_and_reset((void**)&p_lcb->p_rx_msg); 133cceb430489a70add1b996d54289867c17f4ac0fdPavlin Radoslavov osi_free(p_buf); 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ret = NULL; 135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* copy contents of p_buf to p_rx_msg */ 137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy((uint8_t*)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset, 138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len); 139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (pkt_type == AVCT_PKT_TYPE_END) { 141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg->offset -= p_lcb->p_rx_msg->len; 142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg->len += p_buf->len; 143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ret = p_lcb->p_rx_msg; 144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg = NULL; 145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg->offset += p_buf->len; 147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->p_rx_msg->len += p_buf->len; 148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ret = NULL; 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free(p_buf); 151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return p_ret; 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 158ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 159ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_chnl_open 160ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 161ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Open L2CAP channel to peer 162ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 163ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 164ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 165ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 166ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_chnl_open(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { 168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t result = AVCT_RESULT_FAIL; 169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BTM_SetOutService(p_lcb->peer_addr, BTM_SEC_SERVICE_AVCTP, 0); 171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* call l2cap connect req */ 172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->ch_state = AVCT_CH_CONN; 173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->ch_lcid = L2CA_ConnectReq(AVCT_PSM, p_lcb->peer_addr); 174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_lcb->ch_lcid == 0) { 175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if connect req failed, send ourselves close event */ 176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&result); 177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 181ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 182ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_unbind_disc 183ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 184ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Deallocate ccb and call callback with disconnect event. 185ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 186ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 187ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 188ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 189ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_unbind_disc(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_ccb_dealloc(p_data->p_ccb, AVCT_DISCONNECT_CFM_EVT, 0, NULL); 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 195ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 196ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_open_ind 197ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 198ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Handle an LL_OPEN event. For each allocated ccb already 199ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * bound to this lcb, send a connect event. For each 200ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * unbound ccb with a new PID, bind that ccb to this lcb and 201ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * send a connect event. 202ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 203ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 204ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 205ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 206ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int i; 210911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool bind = false; 211911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if ccb allocated and */ 214911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->allocated) { 215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if bound to this lcb send connect confirm event */ 216911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->p_lcb == p_lcb) { 217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bind = true; 218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH); 219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT, 0, 220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->peer_addr); 221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if unbound acceptor and lcb doesn't already have a ccb for this PID */ 223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP) && 224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (avct_lcb_has_pid(p_lcb, p_ccb->cc.pid) == NULL)) { 225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* bind ccb to lcb and send connect ind event */ 226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bind = true; 227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ccb->p_lcb = p_lcb; 228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH); 229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT, 0, 230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->peer_addr); 231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if no ccbs bound to this lcb, disconnect */ 236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (bind == false) { 237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data); 238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 242ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 243ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_open_fail 244ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 245ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description L2CAP channel open attempt failed. Deallocate any ccbs 246ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * on this lcb and send connect confirm event with failure. 247ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 248ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 249ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 250ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 251ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_open_fail(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int i; 255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_ccb_dealloc(p_ccb, AVCT_CONNECT_CFM_EVT, p_data->result, 259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->peer_addr); 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 265ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 266ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_close_ind 267ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 268ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description L2CAP channel closed by peer. Deallocate any initiator 269ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * ccbs on this lcb and send disconnect ind event. 270ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 271ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 272ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 273ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 274ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_close_ind(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { 276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int i; 278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->cc.role == AVCT_INT) { 282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT, 0, p_lcb->peer_addr); 283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ccb->p_lcb = NULL; 285911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), 286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_DISCONNECT_IND_EVT, 0, p_lcb->peer_addr); 287911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 293ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 294ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_close_cfm 295ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 296ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description L2CAP channel closed by us. Deallocate any initiator 297ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * ccbs on this lcb and send disconnect ind or cfm event. 298ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 299ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 300ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 301ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 302ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_close_cfm(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int i; 306911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t event; 307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 309911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if this ccb initiated close send disconnect cfm otherwise ind */ 311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->ch_close) { 312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ccb->ch_close = false; 313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson event = AVCT_DISCONNECT_CFM_EVT; 314911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson event = AVCT_DISCONNECT_IND_EVT; 316911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 317911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 318911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->cc.role == AVCT_INT) { 319911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_ccb_dealloc(p_ccb, event, p_data->result, p_lcb->peer_addr); 320911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 321911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ccb->p_lcb = NULL; 322911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result, 323911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->peer_addr); 324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 326911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 330ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 331ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_bind_conn 332ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 333ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Bind ccb to lcb and send connect cfm event. 334ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 335ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 336ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 337ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 338ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_bind_conn(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 340911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->p_ccb->p_lcb = p_lcb; 341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb), 342911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_CONNECT_CFM_EVT, 0, p_lcb->peer_addr); 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 346ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 347ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_chk_disc 348ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 349ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description A ccb wants to close; if it is the last ccb on this lcb, 350ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * close channel. Otherwise just deallocate and call 351ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * callback. 352ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 353ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 354ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 355ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 356ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 357911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_chk_disc(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 358911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("%s", __func__); 359911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 360911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_close_bcb(p_lcb, p_data); 361911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (avct_lcb_last_ccb(p_lcb, p_data->p_ccb)) { 362911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("%s: closing", __func__); 363911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->p_ccb->ch_close = true; 364911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data); 365911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 366911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("%s: dealloc ccb", __func__); 367911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_lcb_unbind_disc(p_lcb, p_data); 368911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 372ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 373ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_chnl_disc 374ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 375ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Disconnect L2CAP channel. 376ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 377ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 378ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 379ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 380ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 381911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_chnl_disc(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { 382911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson L2CA_DisconnectReq(p_lcb->ch_lcid); 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 386ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 387ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_bind_fail 388ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 389ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Deallocate ccb and call callback with connect event 390ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * with failure result. 391ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 392ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 393ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 394ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 395ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 396911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_bind_fail(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 397911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson avct_ccb_dealloc(p_data->p_ccb, AVCT_CONNECT_CFM_EVT, AVCT_RESULT_FAIL, NULL); 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 401ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 402ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_cong_ind 403ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 404ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Handle congestion indication from L2CAP. 405ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 406ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 407ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 408ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 409ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 410911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_cong_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 411911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 412911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson int i; 413911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t event; 414911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BT_HDR* p_buf; 415911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 416911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* set event */ 417911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson event = (p_data->cong) ? AVCT_CONG_IND_EVT : AVCT_UNCONG_IND_EVT; 418911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->cong = p_data->cong; 419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_lcb->cong == false && !fixed_queue_is_empty(p_lcb->tx_q)) { 420911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (!p_lcb->cong && 421911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_lcb->tx_q)) != NULL) { 422911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) { 423911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->cong = true; 424911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 426911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 428911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* send event to all ccbs on this lcb */ 429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 431911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0, 432911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->peer_addr); 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 438ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 439ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_discard_msg 440ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 441ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Discard a message sent in from the API. 442ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 443ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 444ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 445ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 446ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 447911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_discard_msg(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 448911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("%s Dropping message", __func__); 449911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free_and_reset((void**)&p_data->ul_msg.p_buf); 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 453ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 454ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_send_msg 455ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 456ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Build and send an AVCTP message. 457ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 458ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 459ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 460ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 461ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 462911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_send_msg(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 463911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t curr_msg_len; 464911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t pkt_type; 465911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t hdr_len; 466911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t* p; 467911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t nosp = 0; /* number of subsequent packets */ 468911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t temp; 469911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t buf_size = p_lcb->peer_mtu + L2CAP_MIN_OFFSET + BT_HDR_SIZE; 470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 471911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* store msg len */ 472911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson curr_msg_len = p_data->ul_msg.p_buf->len; 473911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 474911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* initialize packet type and other stuff */ 475911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (curr_msg_len <= (p_lcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) { 476911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pkt_type = AVCT_PKT_TYPE_SINGLE; 477911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 478911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pkt_type = AVCT_PKT_TYPE_START; 479911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson temp = (curr_msg_len + AVCT_HDR_LEN_START - p_lcb->peer_mtu); 480911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nosp = temp / (p_lcb->peer_mtu - 1) + 1; 481911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((temp % (p_lcb->peer_mtu - 1)) != 0) nosp++; 482911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 483911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 484911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* while we haven't sent all packets */ 485911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (curr_msg_len != 0) { 486911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BT_HDR* p_buf; 487911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 488911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* set header len */ 489911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson hdr_len = avct_lcb_pkt_type_len[pkt_type]; 490911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 491911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if remaining msg must be fragmented */ 492911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_data->ul_msg.p_buf->len > (p_lcb->peer_mtu - hdr_len)) { 493911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* get a new buffer for fragment we are sending */ 494911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf = (BT_HDR*)osi_malloc(buf_size); 495911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 496911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* copy portion of data from current message to new buffer */ 497911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->offset = L2CAP_MIN_OFFSET + hdr_len; 498911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->len = p_lcb->peer_mtu - hdr_len; 499911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 500911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson memcpy( 501911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (uint8_t*)(p_buf + 1) + p_buf->offset, 502911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (uint8_t*)(p_data->ul_msg.p_buf + 1) + p_data->ul_msg.p_buf->offset, 503911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->len); 504911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->ul_msg.p_buf->offset += p_buf->len; 506911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->ul_msg.p_buf->len -= p_buf->len; 507911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 508911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf = p_data->ul_msg.p_buf; 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 511911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson curr_msg_len -= p_buf->len; 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 513911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* set up to build header */ 514911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->len += hdr_len; 515911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->offset -= hdr_len; 516911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p = (uint8_t*)(p_buf + 1) + p_buf->offset; 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 518911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* build header */ 519911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_BUILD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr); 520911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (pkt_type == AVCT_PKT_TYPE_START) { 521911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UINT8_TO_STREAM(p, nosp); 522911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 523911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if ((pkt_type == AVCT_PKT_TYPE_START) || 524911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (pkt_type == AVCT_PKT_TYPE_SINGLE)) { 525911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid); 526911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_lcb->cong == true) { 529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fixed_queue_enqueue(p_lcb->tx_q, p_buf); 530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 532911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* send message to L2CAP */ 533911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson else { 534911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) { 535911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_lcb->cong = true; 536911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 537911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 539911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* update pkt type for next packet */ 540911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (curr_msg_len > (p_lcb->peer_mtu - AVCT_HDR_LEN_END)) { 541911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pkt_type = AVCT_PKT_TYPE_CONT; 542911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 543911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson pkt_type = AVCT_PKT_TYPE_END; 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 545911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 546911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_DEBUG("%s tx_q_count:%d", __func__, 547911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fixed_queue_length(p_lcb->tx_q)); 548911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return; 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 552ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 553ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_free_msg_ind 554ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 555ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Discard an incoming AVCTP message. 556ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 557ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 558ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 559ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 560ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 561911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_free_msg_ind(UNUSED_ATTR tAVCT_LCB* p_lcb, 562911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tAVCT_LCB_EVT* p_data) { 563911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_data == NULL) return; 56420524d393e8b3bea4c573f7980cd843500b0e6a4Pavlin Radoslavov 565911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free_and_reset((void**)&p_data->p_buf); 5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 569ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 570ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function avct_lcb_msg_ind 571ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 572ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description Handle an incoming AVCTP message. 573ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 574ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 575ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns Nothing. 576ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * 577ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 578911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 579911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t* p; 580911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t label, type, cr_ipid; 581911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t pid; 582911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson tAVCT_CCB* p_ccb; 583911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 584911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* this p_buf is to be reported through p_msg_cback. The layer_specific 585911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * needs to be set properly to indicate that it is received through 586911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * control channel */ 587911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->p_buf->layer_specific = AVCT_DATA_CTRL; 588911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 589911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* reassemble message; if no message available (we received a fragment) return 590911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson */ 591911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->p_buf = avct_lcb_msg_asmbl(p_lcb, p_data->p_buf); 592911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_data->p_buf == NULL) { 593911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return; 594911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 596911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset; 5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 598911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* parse header byte */ 599911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_PARSE_HDR(p, label, type, cr_ipid); 6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 601911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* check for invalid cr_ipid */ 602911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (cr_ipid == AVCT_CR_IPID_INVALID) { 603911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid); 604911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free_and_reset((void**)&p_data->p_buf); 605911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return; 606911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 607911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 608911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* parse and lookup PID */ 609911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BE_STREAM_TO_UINT16(pid, p); 610911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_ccb = avct_lcb_has_pid(p_lcb, pid); 611911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (p_ccb) { 612911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* PID found; send msg up, adjust bt hdr and call msg callback */ 613911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE; 614911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE; 615911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid, 616911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_data->p_buf); 617911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return; 618911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 619911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 620911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* PID not found; drop message */ 621911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_TRACE_WARNING("No ccb for PID=%x", pid); 622911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson osi_free_and_reset((void**)&p_data->p_buf); 623911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 624911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* if command send reject */ 625911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (cr_ipid == AVCT_CMD) { 626911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVCT_CMD_BUF_SIZE); 627911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->len = AVCT_HDR_LEN_SINGLE; 628911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE; 629911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson p = (uint8_t*)(p_buf + 1) + p_buf->offset; 630911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ); 631911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson UINT16_TO_BE_STREAM(p, pid); 632911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson L2CA_DataWrite(p_lcb->ch_lcid, p_buf); 633911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 635