15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2004-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 the L2CAP 1.2 Flow Control and retransmissions 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * functions 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h> 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h> 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h> 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.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 "l2c_api.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 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Flag passed to retransmit_i_frames() when all packets should be retransmitted */ 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define L2C_FCR_RETX_ALL_PKTS 0xFF 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BT_TRACE_VERBOSE == TRUE 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic char *SAR_types[] = { "Unsegmented", "Start", "End", "Continuation" }; 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic char *SUP_types[] = { "RR", "REJ", "RNR", "SREJ" }; 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Look-up table for the CRC calculation */ 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const unsigned short crctab[256] = { 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040, 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static local functions 885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN process_reqseq (tL2C_CCB *p_ccb, UINT16 ctrl_word); 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_s_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf, UINT16 ctrl_word); 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_i_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf, UINT16 ctrl_word, BOOLEAN delay_ack); 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN retransmit_i_frames (tL2C_CCB *p_ccb, UINT8 tx_seq); 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void prepare_I_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf, BOOLEAN is_retransmission); 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_stream_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf); 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN do_sar_reassembly (tL2C_CCB *p_ccb, BT_HDR *p_buf, UINT16 ctrl_word); 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORRUPT_ERTM_PKTS == TRUE 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN l2c_corrupt_the_fcr_packet (tL2C_CCB *p_ccb, BT_HDR *p_buf, 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN is_rx, UINT16 ctrl_word); 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN l2c_bypass_sframe_packet (tL2C_CCB *p_ccb); 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void l2c_fcr_collect_ack_delay (tL2C_CCB *p_ccb, UINT8 num_bufs_acked); 1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_updcrc 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function computes the CRC using the look-up table. 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns CRC 1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectunsigned short l2c_fcr_updcrc(unsigned short icrc, unsigned char *icp, int icnt) 1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project register unsigned short crc = icrc; 1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project register unsigned char *cp = icp; 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project register int cnt = icnt; 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (cnt--) 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project crc = ((crc >> 8) & 0xff) ^ crctab[(crc & 0xff) ^ *cp++]; 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return(crc); 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_tx_get_fcs 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function computes the CRC for a frame to be TXed. 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns CRC 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 l2c_fcr_tx_get_fcs (BT_HDR *p_buf) 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p = ((UINT8 *) (p_buf + 1)) + p_buf->offset; 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (l2c_fcr_updcrc (L2CAP_FCR_INIT_CRC, p, p_buf->len)); 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_rx_get_fcs 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function computes the CRC for a received frame. 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns CRC 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 l2c_fcr_rx_get_fcs (BT_HDR *p_buf) 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p = ((UINT8 *) (p_buf + 1)) + p_buf->offset; 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* offset points past the L2CAP header, but the CRC check includes it */ 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p -= L2CAP_PKT_OVERHEAD; 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (l2c_fcr_updcrc (L2CAP_FCR_INIT_CRC, p, p_buf->len + L2CAP_PKT_OVERHEAD)); 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_start_timer 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function starts the (monitor or retransmission) timer. 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_start_timer (tL2C_CCB *p_ccb) 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 tout; 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* The timers which are in milliseconds */ 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.wait_ack) 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tout = (UINT32)p_ccb->our_cfg.fcr.mon_tout; 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tout = (UINT32)p_ccb->our_cfg.fcr.rtrans_tout; 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* 189a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_start_timer Tout: %u Already Running: %u wait_ack: %u ack_q_count: %u", 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tout, p_ccb->timer_entry.in_use, p_ccb->fcrb.wait_ack, p_ccb->fcrb.waiting_for_ack_q.count); 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Only start a timer that was not started */ 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.mon_retrans_timer.in_use == 0) 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_start_quick_timer (&p_ccb->fcrb.mon_retrans_timer, BTU_TTYPE_L2CAP_CHNL, tout*QUICK_TIMER_TICKS_PER_SEC/1000); 1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_stop_timer 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function stops the (monitor or transmission) timer. 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_stop_timer (tL2C_CCB *p_ccb) 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.mon_retrans_timer.in_use) 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* 211a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_stop_timer wait_ack: %u ack_q_count: %u", 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.wait_ack, p_ccb->fcrb.waiting_for_ack_q.count); 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer); 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_cleanup 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function cleans up the variable used for flow-control/retrans. 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_cleanup (tL2C_CCB *p_ccb) 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCRB *p_fcrb = &p_ccb->fcrb; 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_stop_timer (p_ccb); 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->p_rx_sdu) 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_fcrb->p_rx_sdu); 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_fcrb->waiting_for_ack_q.p_first) 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (GKI_dequeue (&p_fcrb->waiting_for_ack_q)); 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_fcrb->srej_rcv_hold_q.p_first) 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (GKI_dequeue (&p_fcrb->srej_rcv_hold_q)); 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_fcrb->retrans_q.p_first) 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (GKI_dequeue (&p_fcrb->retrans_q)); 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_stop_quick_timer (&p_fcrb->ack_timer); 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer); 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID) && (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) ) 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 dur = GKI_get_os_tick_count() - p_ccb->fcrb.connect_tick_count; 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project char *p_str = (char *)GKI_getbuf(120); 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 i; 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 throughput_avg, ack_delay_avg, ack_q_count_avg; 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project dur = GKI_OS_TICKS_TO_MS(dur); 2570212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "--- L2CAP ERTM Stats for CID: 0x%04x Duration: %08ums", p_ccb->local_cid, dur); 2590212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "Retransmissions:%08u Times Flow Controlled:%08u Retrans Touts:%08u Ack Touts:%08u", 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.pkts_retransmitted, p_ccb->fcrb.xmit_window_closed, p_ccb->fcrb.retrans_touts, p_ccb->fcrb.xmit_ack_touts); 2620212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "Times there is less than 2 packets in controller when flow controlled:%08u", p_ccb->fcrb.controller_idle); 2640212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "max_held_acks:%08u, in_cfg.fcr.tx_win_sz:%08u", p_ccb->fcrb.max_held_acks, p_ccb->peer_cfg.fcr.tx_win_sz ); 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_str) 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sprintf(p_str, "Sent Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u", 2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_pkt_counts[0], p_ccb->fcrb.ertm_byte_counts[0], 2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[0] * 100) / (dur / 10) : 0), 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.s_frames_sent[0], p_ccb->fcrb.s_frames_sent[1], p_ccb->fcrb.s_frames_sent[2], p_ccb->fcrb.s_frames_sent[3]); 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2730212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, "%s", p_str); 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sprintf(p_str, "Rcvd Pkts:%08u Bytes:%10u(%06u/sec) RR:%08u REJ:%08u RNR:%08u SREJ:%08u", 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_pkt_counts[1], p_ccb->fcrb.ertm_byte_counts[1], 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (dur >= 10 ? (p_ccb->fcrb.ertm_byte_counts[1] * 100) / (dur / 10) : 0), 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.s_frames_rcvd[0], p_ccb->fcrb.s_frames_rcvd[1], p_ccb->fcrb.s_frames_rcvd[2], p_ccb->fcrb.s_frames_rcvd[3]); 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2800212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, "%s", p_str); 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project throughput_avg = 0; 2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ack_delay_avg = 0; 2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ack_q_count_avg = 0; 2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (i = 0; i < L2CAP_ERTM_STATS_NUM_AVG; i++ ) 2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (i == p_ccb->fcrb.ack_delay_avg_index ) 2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2900212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "[%02u] collecting data ...", i ); 2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project continue; 2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sprintf(p_str, "[%02u] throughput: %5u, ack_delay avg:%3u, min:%3u, max:%3u, ack_q_count avg:%3u, min:%3u, max:%3u", 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project i, p_ccb->fcrb.throughput[i], 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg[i], p_ccb->fcrb.ack_delay_min[i], p_ccb->fcrb.ack_delay_max[i], 2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_avg[i], p_ccb->fcrb.ack_q_count_min[i], p_ccb->fcrb.ack_q_count_max[i] ); 2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3000212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, "%s", p_str); 3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project throughput_avg += p_ccb->fcrb.throughput[i]; 3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ack_delay_avg += p_ccb->fcrb.ack_delay_avg[i]; 3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ack_q_count_avg += p_ccb->fcrb.ack_q_count_avg[i]; 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project throughput_avg /= (L2CAP_ERTM_STATS_NUM_AVG - 1); 3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ack_delay_avg /= (L2CAP_ERTM_STATS_NUM_AVG - 1); 3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ack_q_count_avg /= (L2CAP_ERTM_STATS_NUM_AVG - 1); 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3110212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "throughput_avg: %8u (kbytes/sec), ack_delay_avg: %8u ms, ack_q_count_avg: %8u", 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project throughput_avg, ack_delay_avg, ack_q_count_avg ); 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_str); 3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3180212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "---"); 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (p_fcrb, 0, sizeof (tL2C_FCRB)); 3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_clone_buf 3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function allocates and copies requested part of a buffer 3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** at a new-offset. 3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns pointer to new buffer 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_HDR *l2c_fcr_clone_buf (BT_HDR *p_buf, UINT16 new_offset, UINT16 no_of_bytes, UINT8 pool) 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf2; 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If using the common pool, should be at least 10% free. */ 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (pool == HCI_ACL_POOL_ID) && (GKI_poolutilization (pool) > 90) ) 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 343a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CAP - failed to clone buffer on HCI_ACL_POOL_ID Utilization: %u", GKI_poolutilization(pool)); 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_buf2 = (BT_HDR *)GKI_getpoolbuf(pool)) != NULL) 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 pool_buf_size = GKI_get_pool_bufsize (pool); 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Make sure buffer fits into buffer pool */ 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((no_of_bytes + sizeof(BT_HDR) + new_offset) > pool_buf_size) 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 354a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR("##### l2c_fcr_clone_buf (NumBytes %d) -> Exceeds poolsize %d [bytes %d + BT_HDR %d + offset %d]", 3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (no_of_bytes + sizeof(BT_HDR) + new_offset), 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pool_buf_size, no_of_bytes, sizeof(BT_HDR), 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project new_offset); 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf2); 3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf2->offset = new_offset; 3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf2->len = no_of_bytes; 3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy (((UINT8 *)(p_buf2 + 1)) + p_buf2->offset, 3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ((UINT8 *)(p_buf + 1)) + p_buf->offset, 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project no_of_bytes); 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 372a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CAP - failed to clone buffer, Pool: %u Count: %u", pool, GKI_poolfreecount(pool)); 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_buf2); 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_is_flow_controlled 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function checks if the CCB is flow controlled by peer. 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns The control word 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2c_fcr_is_flow_controlled (tL2C_CCB *p_ccb) 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if remote side flowed us off or the transmit window is full */ 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_ccb->fcrb.remote_busy == TRUE) 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_ccb->fcrb.waiting_for_ack_q.count >= p_ccb->peer_cfg.fcr.tx_win_sz) ) 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->xmit_hold_q.count != 0) 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.xmit_window_closed++; 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_ccb->p_lcb->sent_not_acked < 2)&&(l2cb.controller_xmit_window > 0)) 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.controller_idle++; 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (TRUE); 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function prepare_I_frame 4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function sets the FCR variables in an I-frame that is 4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** about to be sent to HCI for transmission. This may be the 4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** first time the I-frame is sent, or a retransmission 4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void prepare_I_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf, BOOLEAN is_retransmission) 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCRB *p_fcrb = &p_ccb->fcrb; 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 fcs; 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 ctrl_word; 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN set_f_bit = p_fcrb->send_f_rsp; 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->send_f_rsp = FALSE; 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (is_retransmission) 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the old control word and clear out the old req_seq and F bits */ 4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf+1)) + p_buf->offset + L2CAP_PKT_OVERHEAD; 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word &= ~(L2CAP_FCR_REQ_SEQ_BITS + L2CAP_FCR_F_BIT); 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word = p_buf->layer_specific & L2CAP_FCR_SEG_BITS; /* SAR bits */ 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word |= (p_fcrb->next_tx_seq << L2CAP_FCR_TX_SEQ_BITS_SHIFT); /* Tx Seq */ 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->next_tx_seq = (p_fcrb->next_tx_seq + 1) & L2CAP_FCR_SEQ_MODULO; 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Set the F-bit and reqseq only if using re-transmission mode */ 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (set_f_bit) 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word |= L2CAP_FCR_F_BIT; 4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word |= (p_fcrb->next_seq_expected) << L2CAP_FCR_REQ_SEQ_BITS_SHIFT; 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->last_ack_sent = p_ccb->fcrb.next_seq_expected; 4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.ack_timer.in_use) 4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_stop_quick_timer (&p_ccb->fcrb.ack_timer); 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Set the control word */ 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf+1)) + p_buf->offset + L2CAP_PKT_OVERHEAD; 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, ctrl_word); 4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Compute the FCS and add to the end of the buffer if not bypassed */ 4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) 4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* length field in l2cap header has to include FCS length */ 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf+1)) + p_buf->offset; 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, p_buf->len + L2CAP_FCS_LEN - L2CAP_PKT_OVERHEAD); 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Calculate the FCS */ 4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcs = l2c_fcr_tx_get_fcs(p_buf); 4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Point to the end of the buffer and put the FCS there */ 4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf+1)) + p_buf->offset + p_buf->len; 4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, fcs); 4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len += L2CAP_FCS_LEN; 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BT_TRACE_VERBOSE == TRUE 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (is_retransmission) 4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 488a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("L2CAP eRTM ReTx I-frame CID: 0x%04x Len: %u SAR: %s TxSeq: %u ReqSeq: %u F: %u", 4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_buf->len, 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SAR_types[(ctrl_word & L2CAP_FCR_SAR_BITS) >> L2CAP_FCR_SAR_BITS_SHIFT], 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 497a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("L2CAP eRTM Tx I-frame CID: 0x%04x Len: %u SAR: %-12s TxSeq: %u ReqSeq: %u F: %u", 4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_buf->len, 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SAR_types[(ctrl_word & L2CAP_FCR_SAR_BITS) >> L2CAP_FCR_SAR_BITS_SHIFT], 5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Start the retransmission timer if not already running */ 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_start_timer (p_ccb); 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_send_S_frame 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function formats and sends an S-frame for transmission. 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_send_S_frame (tL2C_CCB *p_ccb, UINT16 function_code, UINT16 pf_bit) 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf; 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 ctrl_word; 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 fcs; 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORRUPT_ERTM_PKTS == TRUE 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Only used for conformance testing */ 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2c_bypass_sframe_packet (p_ccb)) 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((!p_ccb->in_use) || (p_ccb->chnl_state != CST_OPEN)) 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.s_frames_sent[function_code]++; 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (pf_bit == L2CAP_FCR_P_BIT) 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.wait_ack = TRUE; 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_stop_timer (p_ccb); /* Restart the monitor timer */ 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_start_timer (p_ccb); 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Create the control word to use */ 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word = (function_code << L2CAP_FCR_SUP_SHIFT) | L2CAP_FCR_S_FRAME_BIT; 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word |= (p_ccb->fcrb.next_seq_expected << L2CAP_FCR_REQ_SEQ_BITS_SHIFT); 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word |= pf_bit; 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID)) != NULL) 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset = HCI_DATA_PREAMBLE_SIZE; 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len = L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD; 5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Set the pointer to the beginning of the data */ 5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (UINT8 *)(p_buf + 1) + p_buf->offset; 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Put in the L2CAP header */ 5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, L2CAP_FCR_OVERHEAD + L2CAP_FCS_LEN); 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, p_ccb->remote_cid); 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, ctrl_word); 5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Compute the FCS and add to the end of the buffer if not bypassed */ 5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) 5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcs = l2c_fcr_tx_get_fcs (p_buf); 5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, fcs); 5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len += L2CAP_FCS_LEN; 5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* rewrite the length without FCS length */ 5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p -= 6; 5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, L2CAP_FCR_OVERHEAD); 5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORRUPT_ERTM_PKTS == TRUE 5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get out if packet was dropped */ 5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2c_corrupt_the_fcr_packet (p_ccb, p_buf, FALSE, ctrl_word)) 5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Now, the HCI transport header */ 5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->layer_specific = L2CAP_NON_FLUSHABLE_PKT; 5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_set_acl_hci_header (p_buf, p_ccb); 5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BT_TRACE_VERBOSE == TRUE 5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 1) 5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 3)) 5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 593a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP eRTM Tx S-frame CID: 0x%04x ctrlword: 0x%04x Type: %s ReqSeq: %u P: %u F: %u", 5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, ctrl_word, 5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], 5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_P_BIT) >> L2CAP_FCR_P_BIT_SHIFT, 5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 599a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING (" Buf Len: %u", p_buf->len); 6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 603a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("L2CAP eRTM Tx S-frame CID: 0x%04x ctrlword: 0x%04x Type: %s ReqSeq: %u P: %u F: %u", 6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, ctrl_word, 6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], 6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_P_BIT) >> L2CAP_FCR_P_BIT_SHIFT, 6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 609a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT (" Buf Len: %u", p_buf->len); 6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* BT_TRACE_VERBOSE */ 6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf); 6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.last_ack_sent = p_ccb->fcrb.next_seq_expected; 6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.ack_timer.in_use) 6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_stop_quick_timer (&p_ccb->fcrb.ack_timer); 6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 622a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("l2c_fcr_send_S_frame(No Resources) cid 0x%04x, Type: 0x%4x", 6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, function_code); 6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_proc_pdu 6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is the entry point for processing of a 6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** received PDU when in flow control and/or retransmission modes. 6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_proc_pdu (tL2C_CCB *p_ccb, BT_HDR *p_buf) 6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 fcs; 6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 min_pdu_len; 6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 ctrl_word; 6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check the length */ 6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project min_pdu_len = (p_ccb->bypass_fcs == L2CAP_BYPASS_FCS) ? 6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (UINT16)L2CAP_FCR_OVERHEAD : (UINT16)(L2CAP_FCS_LEN + L2CAP_FCR_OVERHEAD); 6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf->len < min_pdu_len) 6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 651a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("Rx L2CAP PDU: CID: 0x%04x Len too short: %u", p_ccb->local_cid, p_buf->len); 6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_STREAM_MODE) 6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project process_stream_frame (p_ccb, p_buf); 6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BT_TRACE_VERBOSE == TRUE 6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the control word */ 6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf+1)) + p_buf->offset; 6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_S_FRAME_BIT) 6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 1) 6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 3)) 6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* REJ or SREJ */ 673a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP eRTM Rx S-frame: cid: 0x%04x Len: %u Type: %s ReqSeq: %u P: %u F: %u", 6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_buf->len, 6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], 6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_P_BIT) >> L2CAP_FCR_P_BIT_SHIFT, 6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 682a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("L2CAP eRTM Rx S-frame: cid: 0x%04x Len: %u Type: %s ReqSeq: %u P: %u F: %u", 6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_buf->len, 6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], 6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_P_BIT) >> L2CAP_FCR_P_BIT_SHIFT, 6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 692a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("L2CAP eRTM Rx I-frame: cid: 0x%04x Len: %u SAR: %-12s TxSeq: %u ReqSeq: %u F: %u", 6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_buf->len, 6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SAR_types[(ctrl_word & L2CAP_FCR_SAR_BITS) >> L2CAP_FCR_SAR_BITS_SHIFT], 6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, 6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 700a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT (" eRTM Rx Nxt_tx_seq %u, Lst_rx_ack %u, Nxt_seq_exp %u, Lst_ack_snt %u, wt_q.cnt %u, tries %u", 7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.next_tx_seq, p_ccb->fcrb.last_rx_ack, p_ccb->fcrb.next_seq_expected, 7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.last_ack_sent, p_ccb->fcrb.waiting_for_ack_q.count, p_ccb->fcrb.num_tries); 7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* BT_TRACE_VERBOSE */ 7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORRUPT_ERTM_PKTS == TRUE 7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf+1)) + p_buf->offset; 7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get out if packet was dropped */ 7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2c_corrupt_the_fcr_packet (p_ccb, p_buf, TRUE, ctrl_word)) 7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* L2CAP_CORRUPT_ERTM_PKTS */ 7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Verify FCS if using */ 7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) 7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf+1)) + p_buf->offset + p_buf->len - L2CAP_FCS_LEN; 7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Extract and drop the FCS from the packet */ 7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (fcs, p); 7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len -= L2CAP_FCS_LEN; 7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2c_fcr_rx_get_fcs(p_buf) != fcs) 7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 726a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("Rx L2CAP PDU: CID: 0x%04x BAD FCS", p_ccb->local_cid); 7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf); 7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the control word */ 7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf+1)) + p_buf->offset; 7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len -= L2CAP_FCR_OVERHEAD; 7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset += L2CAP_FCR_OVERHEAD; 7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we had a poll bit outstanding, check if we got a final response */ 7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.wait_ack) 7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If final bit not set, ignore the frame unless it is a polled S-frame */ 7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( !(ctrl_word & L2CAP_FCR_F_BIT) ) 7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (ctrl_word & L2CAP_FCR_P_BIT) && (ctrl_word & L2CAP_FCR_S_FRAME_BIT) ) 7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.srej_sent) 7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_SREJ, L2CAP_FCR_F_BIT); 7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_ccb->fcrb.local_busy) 7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, L2CAP_FCR_F_BIT); 7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_F_BIT); 7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Got a poll while in wait_ack state, so re-start our timer with 1-second */ 7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* This is a small optimization... the monitor timer is 12 secs, but we saw */ 7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* that if the other side sends us a poll when we are waiting for a final, */ 7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* then it speeds up recovery significantly if we poll him back soon after his poll. */ 7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_start_quick_timer (&p_ccb->fcrb.mon_retrans_timer, BTU_TTYPE_L2CAP_CHNL, QUICK_TIMER_TICKS_PER_SEC); 7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.wait_ack = FALSE; 7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* P and F are mutually exclusive */ 7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_S_FRAME_BIT) 7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word &= ~L2CAP_FCR_P_BIT; 7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.waiting_for_ack_q.count == 0) 7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.num_tries = 0; 7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_stop_timer (p_ccb); 7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Otherwise, ensure the final bit is ignored */ 7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word &= ~L2CAP_FCR_F_BIT; 7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Process receive sequence number */ 7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!process_reqseq (p_ccb, ctrl_word)) 7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Process based on whether it is an S-frame or an I-frame */ 7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_S_FRAME_BIT) 7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project process_s_frame (p_ccb, p_buf, ctrl_word); 7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project process_i_frame (p_ccb, p_buf, ctrl_word, FALSE); 7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Return if the channel got disconnected by a bad packet or max retransmissions */ 7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (!p_ccb->in_use) || (p_ccb->chnl_state != CST_OPEN) ) 7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we have some buffers held while doing SREJ, and SREJ has cleared, process them now */ 8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (!p_ccb->fcrb.local_busy) && (!p_ccb->fcrb.srej_sent) && (p_ccb->fcrb.srej_rcv_hold_q.count > 0) ) 8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BUFFER_Q temp_q = p_ccb->fcrb.srej_rcv_hold_q; 8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_init_q (&p_ccb->fcrb.srej_rcv_hold_q); 8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while ((p_buf = (BT_HDR *)GKI_dequeue (&temp_q)) != NULL) 8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->in_use && (p_ccb->chnl_state == CST_OPEN)) 8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the control word */ 8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf+1)) + p_buf->offset - L2CAP_FCR_OVERHEAD; 8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 815a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_proc_pdu() CID: 0x%04x Process Buffer from SREJ_Hold_Q TxSeq: %u Expected_Seq: %u", 8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, 8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.next_seq_expected); 8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Process the SREJ held I-frame, but do not send an RR for each individual frame */ 8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project process_i_frame (p_ccb, p_buf, ctrl_word, TRUE); 8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If more frames were lost during SREJ, send a REJ */ 8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.rej_after_srej) 8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.rej_after_srej = FALSE; 8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.rej_sent = TRUE; 8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_REJ, 0); 8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Now, if needed, send one RR for the whole held queue */ 8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (!p_ccb->fcrb.local_busy) && (!p_ccb->fcrb.rej_sent) && (!p_ccb->fcrb.srej_sent) 8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_ccb->fcrb.next_seq_expected != p_ccb->fcrb.last_ack_sent) ) 8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, 0); 8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 841a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_proc_pdu() not sending RR CID: 0x%04x local_busy:%d rej_sent:%d srej_sent:%d Expected_Seq:%u Last_Ack:%u", 8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_ccb->fcrb.local_busy, p_ccb->fcrb.rej_sent, p_ccb->fcrb.srej_sent, p_ccb->fcrb.next_seq_expected, 8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.last_ack_sent); 8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If a window has opened, check if we can send any more packets */ 8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_ccb->fcrb.retrans_q.count || p_ccb->xmit_hold_q.count) 8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_ccb->fcrb.wait_ack == FALSE) 8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (l2c_fcr_is_flow_controlled (p_ccb) == FALSE) ) 8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); 8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_proc_tout 8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Handle a timeout. We should be in error recovery state. 8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_proc_tout (tL2C_CCB *p_ccb) 8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 867a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_proc_tout: CID: 0x%04x num_tries: %u (max: %u) wait_ack: %u ack_q_count: %u", 8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_ccb->fcrb.num_tries, p_ccb->peer_cfg.fcr.max_transmit, 8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.wait_ack, p_ccb->fcrb.waiting_for_ack_q.count); 8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.retrans_touts++; 8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_ccb->peer_cfg.fcr.max_transmit != 0) && (++p_ccb->fcrb.num_tries > p_ccb->peer_cfg.fcr.max_transmit) ) 8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_disconnect_chnl (p_ccb); 8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_ccb->fcrb.srej_sent && !p_ccb->fcrb.rej_sent) 8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.local_busy) 8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, L2CAP_FCR_P_BIT); 8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_P_BIT); 8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_proc_ack_tout 8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Send RR/RNR if we have not acked I frame 8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_proc_ack_tout (tL2C_CCB *p_ccb) 9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 903a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_proc_ack_tout: CID: 0x%04x State: %u Wack:%u Rq:%d Acked:%d", p_ccb->local_cid, 9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->chnl_state, p_ccb->fcrb.wait_ack, p_ccb->fcrb.next_seq_expected, p_ccb->fcrb.last_ack_sent); 9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_ccb->chnl_state == CST_OPEN) && (!p_ccb->fcrb.wait_ack) 9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_ccb->fcrb.last_ack_sent != p_ccb->fcrb.next_seq_expected) ) 9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.xmit_ack_touts++; 9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.local_busy) 9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, 0); 9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, 0); 9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function process_reqseq 9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Handle receive sequence number 9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN process_reqseq (tL2C_CCB *p_ccb, UINT16 ctrl_word) 9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCRB *p_fcrb = &p_ccb->fcrb; 9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 req_seq, num_bufs_acked, xx; 9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 ls; 9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 full_sdus_xmitted; 9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Receive sequence number does not ack anything for SREJ with P-bit set to zero */ 9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (ctrl_word & L2CAP_FCR_S_FRAME_BIT) 9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && ((ctrl_word & L2CAP_FCR_SUP_BITS) == (L2CAP_FCR_SUP_SREJ << L2CAP_FCR_SUP_SHIFT)) 9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && ((ctrl_word & L2CAP_FCR_P_BIT) == 0) ) 9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If anything still waiting for ack, restart the timer if it was stopped */ 9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->waiting_for_ack_q.count) 9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_start_timer (p_ccb); 9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (TRUE); 9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Extract the receive sequence number from the control word */ 9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project req_seq = (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT; 9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_bufs_acked = (req_seq - p_fcrb->last_rx_ack) & L2CAP_FCR_SEQ_MODULO; 9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Verify the request sequence is in range before proceeding */ 9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (num_bufs_acked > p_fcrb->waiting_for_ack_q.count) 9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* The channel is closed if ReqSeq is not in range */ 957a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP eRTM Frame BAD Req_Seq - ctrl_word: 0x%04x req_seq 0x%02x last_rx_ack: 0x%02x QCount: %u", 9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ctrl_word, req_seq, p_fcrb->last_rx_ack, p_fcrb->waiting_for_ack_q.count); 9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_disconnect_chnl (p_ccb); 9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* 965a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("L2CAP process_reqseq 0x%02x last_rx_ack: 0x%02x QCount: %u", 9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project req_seq, p_fcrb->last_rx_ack, p_fcrb->waiting_for_ack_q.count); 9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->last_rx_ack = req_seq; 9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Now we can release all acknowledged frames, and restart the retransmission timer if needed */ 9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (num_bufs_acked != 0) 9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->num_tries = 0; 9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project full_sdus_xmitted = 0; 9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_collect_ack_delay (p_ccb, num_bufs_acked); 9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (xx = 0; xx < num_bufs_acked; xx++) 9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ls = ((BT_HDR *)(p_fcrb->waiting_for_ack_q.p_first))->layer_specific & L2CAP_FCR_SAR_BITS; 9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (ls == L2CAP_FCR_UNSEG_SDU) || (ls == L2CAP_FCR_END_SDU) ) 9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project full_sdus_xmitted++; 9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (GKI_dequeue (&p_fcrb->waiting_for_ack_q)); 9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we are still in a wait_ack state, do not mess with the timer */ 9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_ccb->fcrb.wait_ack) 9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_stop_timer (p_ccb); 9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if we need to call the "packet_sent" callback */ 9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_TxComplete_Cb) && (full_sdus_xmitted) ) 9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Special case for eRTM, if all packets sent, send 0xFFFF */ 9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_fcrb->waiting_for_ack_q.count == 0) && (p_ccb->xmit_hold_q.count == 0) ) 9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project full_sdus_xmitted = 0xFFFF; 10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, full_sdus_xmitted); 10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If anything still waiting for ack, restart the timer if it was stopped */ 10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->waiting_for_ack_q.count) 10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_start_timer (p_ccb); 10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (TRUE); 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 process_s_frame 10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Process an S frame 10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_s_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf, UINT16 ctrl_word) 10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCRB *p_fcrb = &p_ccb->fcrb; 10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 s_frame_type = (ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT; 10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN remote_was_busy; 10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN all_ok = TRUE; 10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf->len != 0) 10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1031a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("Incorrect S-frame Length (%d)", p_buf->len); 10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1034a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("process_s_frame ctrl_word 0x%04x fcrb_remote_busy:%d", ctrl_word, p_fcrb->remote_busy); 10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.s_frames_rcvd[s_frame_type]++; 10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_P_BIT) 10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->rej_sent = FALSE; /* After checkpoint, we can send anoher REJ */ 10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->send_f_rsp = TRUE; /* Set a flag in case an I-frame is pending */ 10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch (s_frame_type) 10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case L2CAP_FCR_SUP_RR: 10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project remote_was_busy = p_fcrb->remote_busy; 10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->remote_busy = FALSE; 10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (ctrl_word & L2CAP_FCR_F_BIT) || (remote_was_busy) ) 10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project all_ok = retransmit_i_frames (p_ccb, L2C_FCR_RETX_ALL_PKTS); 10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case L2CAP_FCR_SUP_REJ: 10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->remote_busy = FALSE; 10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project all_ok = retransmit_i_frames (p_ccb, L2C_FCR_RETX_ALL_PKTS); 10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case L2CAP_FCR_SUP_RNR: 10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->remote_busy = TRUE; 10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_stop_timer (p_ccb); 10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case L2CAP_FCR_SUP_SREJ: 10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->remote_busy = FALSE; 10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project all_ok = retransmit_i_frames (p_ccb, (UINT8)((ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT)); 10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (all_ok) 10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If polled, we need to respond with F-bit. Note, we may have sent a I-frame with the F-bit */ 10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->send_f_rsp) 10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->srej_sent) 10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_SREJ, L2CAP_FCR_F_BIT); 10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_fcrb->local_busy) 10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, L2CAP_FCR_F_BIT); 10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, L2CAP_FCR_F_BIT); 10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->send_f_rsp = FALSE; 10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1089a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("process_s_frame hit_max_retries"); 10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function process_i_frame 10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Process an I frame 11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_i_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf, UINT16 ctrl_word, BOOLEAN delay_ack) 11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCRB *p_fcrb = &p_ccb->fcrb; 11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 tx_seq, num_lost, num_to_ack, next_srej; 11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we were doing checkpoint recovery, first retransmit all unacked I-frames */ 11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_F_BIT) 11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!retransmit_i_frames (p_ccb, L2C_FCR_RETX_ALL_PKTS)) 11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf); 11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_pkt_counts[1]++; 11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_byte_counts[1] += p_buf->len; 11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Extract the sequence number */ 11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tx_seq = (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT; 11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we have flow controlled the peer, ignore any bad I-frames from him */ 11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (tx_seq != p_fcrb->next_seq_expected) && (p_fcrb->local_busy) ) 11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1131a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("Dropping bad I-Frame since we flowed off, tx_seq:%u", tx_seq); 11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, 0); 11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf); 11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If there are no free buffers in the user Rx queue, drop the */ 11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* received buffer now before we update any sequence numbers */ 11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (GKI_poolfreecount (p_ccb->ertm_info.user_rx_pool_id) == 0) 11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1141a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP CID: 0x%04x Dropping I-Frame seq: %u User RX Pool: %u (Size: %u) has no free buffers!!", 11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, tx_seq, p_ccb->ertm_info.user_rx_pool_id, 11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_poolcount (p_ccb->ertm_info.user_rx_pool_id)); 11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf); 11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if tx-sequence is the expected one */ 11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (tx_seq != p_fcrb->next_seq_expected) 11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_lost = (tx_seq - p_fcrb->next_seq_expected) & L2CAP_FCR_SEQ_MODULO; 11525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Is the frame a duplicate ? If so, just drop it */ 11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (num_lost >= p_ccb->our_cfg.fcr.tx_win_sz) 11555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Duplicate - simply drop it */ 1157a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("process_i_frame() Dropping Duplicate Frame tx_seq:%u ExpectedTxSeq %u", tx_seq, p_fcrb->next_seq_expected); 11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf); 11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1162a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("process_i_frame() CID: 0x%04x Lost: %u tx_seq:%u ExpTxSeq %u Rej: %u SRej: %u", 11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, num_lost, tx_seq, p_fcrb->next_seq_expected, p_fcrb->rej_sent, p_fcrb->srej_sent); 11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->srej_sent) 11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If SREJ sent, save the frame for later processing as long as it is in sequence */ 11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project next_srej = (((BT_HDR *)p_fcrb->srej_rcv_hold_q.p_last)->layer_specific + 1) & L2CAP_FCR_SEQ_MODULO; 11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (tx_seq == next_srej) && (p_fcrb->srej_rcv_hold_q.count < p_ccb->our_cfg.fcr.tx_win_sz) ) 11715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If user gave us a pool for held rx buffers, use that */ 11735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->ertm_info.fcr_rx_pool_id != HCI_ACL_POOL_ID) 11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf2; 11765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Adjust offset and len so that control word is copied */ 11785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset -= L2CAP_FCR_OVERHEAD; 11795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len += L2CAP_FCR_OVERHEAD; 11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf2 = l2c_fcr_clone_buf (p_buf, p_buf->offset, p_buf->len, p_ccb->ertm_info.fcr_rx_pool_id); 11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf2) 11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 11855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 11865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = p_buf2; 11875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 11885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset += L2CAP_FCR_OVERHEAD; 11895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len -= L2CAP_FCR_OVERHEAD; 11905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1191a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("process_i_frame() Lost: %u tx_seq:%u ExpTxSeq %u Rej: %u SRej1", 11925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_lost, tx_seq, p_fcrb->next_seq_expected, p_fcrb->rej_sent); 11935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->layer_specific = tx_seq; 11955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_enqueue (&p_fcrb->srej_rcv_hold_q, p_buf); 11965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 11975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 11985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1199a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("process_i_frame() CID: 0x%04x frame dropped in Srej Sent next_srej:%u hold_q.count:%u win_sz:%u", 12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, next_srej, p_fcrb->srej_rcv_hold_q.count, p_ccb->our_cfg.fcr.tx_win_sz); 12015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->rej_after_srej = TRUE; 12035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 12045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_fcrb->rej_sent) 12075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1208a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("process_i_frame() CID: 0x%04x Lost: %u tx_seq:%u ExpTxSeq %u Rej: 1 SRej: %u", 12095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, num_lost, tx_seq, p_fcrb->next_seq_expected, p_fcrb->srej_sent); 12105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If REJ sent, just drop the frame */ 12125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 12135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 12155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1216a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("process_i_frame() CID: 0x%04x tx_seq:%u ExpTxSeq %u Rej: %u", 12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, tx_seq, p_fcrb->next_seq_expected, p_fcrb->rej_sent); 12185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If only one lost, we will send SREJ, otherwise we will send REJ */ 12205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (num_lost > 1) 12215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->rej_sent = TRUE; 12245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_REJ, 0); 12255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 12275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 12285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->srej_rcv_hold_q.count != 0) 12295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1230a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("process_i_frame() CID: 0x%04x sending SREJ tx_seq:%d hold_q.count:%u", 12315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, tx_seq, p_fcrb->srej_rcv_hold_q.count); 12325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->layer_specific = tx_seq; 12345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_enqueue (&p_fcrb->srej_rcv_hold_q, p_buf); 12355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->srej_sent = TRUE; 12365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_SREJ, 0); 12375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_stop_quick_timer (&p_ccb->fcrb.ack_timer); 12395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 12425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Seq number is the next expected. Clear possible reject exception in case it occured */ 12455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->rej_sent = p_fcrb->srej_sent = FALSE; 12465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Adjust the next_seq, so that if the upper layer sends more data in the callback 12485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project context, the received frame is acked by an I-frame. */ 12495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->next_seq_expected = (tx_seq + 1) & L2CAP_FCR_SEQ_MODULO; 12505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If any SAR problem in eRTM mode, spec says disconnect. */ 12525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!do_sar_reassembly (p_ccb, p_buf, ctrl_word)) 12535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1254a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("process_i_frame() CID: 0x%04x reassembly failed", p_ccb->local_cid); 12555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_disconnect_chnl (p_ccb); 12565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 12575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* RR optimization - if peer can still send us more, then start an ACK timer */ 12605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_to_ack = (p_fcrb->next_seq_expected - p_fcrb->last_ack_sent) & L2CAP_FCR_SEQ_MODULO; 12615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (num_to_ack < p_ccb->fcrb.max_held_acks) && (!p_fcrb->local_busy) ) 12635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project delay_ack = TRUE; 12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We should neve never ack frame if we are not in OPEN state */ 12665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((num_to_ack != 0) && p_ccb->in_use && (p_ccb->chnl_state == CST_OPEN)) 12675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 12685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If no frames are awaiting transmission or are held, send an RR or RNR S-frame for ack */ 12695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (delay_ack) 12705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 12715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If it is the first I frame we did not ack, start ack timer */ 12725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_ccb->fcrb.ack_timer.in_use) 12735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 12745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_start_quick_timer (&p_ccb->fcrb.ack_timer, BTU_TTYPE_L2CAP_FCR_ACK, 12755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (L2CAP_FCR_ACK_TOUT*QUICK_TIMER_TICKS_PER_SEC)/1000); 12765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ( ((p_ccb->xmit_hold_q.count == 0) || (l2c_fcr_is_flow_controlled (p_ccb))) 12795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_ccb->fcrb.srej_rcv_hold_q.count == 0) ) 12805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 12815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->local_busy) 12825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RNR, 0); 12835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 12845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, L2CAP_FCR_SUP_RR, 0); 12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 12875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 12885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 12915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 12925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function process_stream_frame 12935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 12945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function processes frames in streaming mode 12955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 12965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns - 12975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 12985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 12995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_stream_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf) 13005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 13015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 ctrl_word; 13025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 fcs; 13035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 13045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 tx_seq; 13055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Verify FCS if using */ 13075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) 13085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 13095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf+1)) + p_buf->offset + p_buf->len - L2CAP_FCS_LEN; 13105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Extract and drop the FCS from the packet */ 13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (fcs, p); 13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len -= L2CAP_FCS_LEN; 13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2c_fcr_rx_get_fcs(p_buf) != fcs) 13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1317a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("Rx L2CAP PDU: CID: 0x%04x BAD FCS", p_ccb->local_cid); 13185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf); 13195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 13205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the control word */ 13245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf+1)) + p_buf->offset; 13255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 13275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len -= L2CAP_FCR_OVERHEAD; 13295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset += L2CAP_FCR_OVERHEAD; 13305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Make sure it is an I-frame */ 13325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_S_FRAME_BIT) 13335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1334a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("Rx L2CAP PDU: CID: 0x%04x BAD S-frame in streaming mode ctrl_word: 0x%04x", p_ccb->local_cid, ctrl_word); 13355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 13365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 13375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BT_TRACE_VERBOSE == TRUE 1340a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("L2CAP eRTM Rx I-frame: cid: 0x%04x Len: %u SAR: %-12s TxSeq: %u ReqSeq: %u F: %u", 13415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_buf->len, 13425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project SAR_types[(ctrl_word & L2CAP_FCR_SAR_BITS) >> L2CAP_FCR_SAR_BITS_SHIFT], 13435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, 13445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, 13455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); 13465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 13475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Extract the sequence number */ 13495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tx_seq = (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT; 13505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if tx-sequence is the expected one */ 13525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (tx_seq != p_ccb->fcrb.next_seq_expected) 13535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1354a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("Rx L2CAP PDU: CID: 0x%04x Lost frames Exp: %u Got: %u p_rx_sdu: 0x%08x", 13555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_ccb->fcrb.next_seq_expected, tx_seq, p_ccb->fcrb.p_rx_sdu); 13565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Lost one or more packets, so flush the SAR queue */ 13585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.p_rx_sdu != NULL) 13595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 13605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_ccb->fcrb.p_rx_sdu); 13615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.p_rx_sdu = NULL; 13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.next_seq_expected = (tx_seq + 1) & L2CAP_FCR_SEQ_MODULO; 13665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!do_sar_reassembly (p_ccb, p_buf, ctrl_word)) 13685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Some sort of SAR error, so flush the SAR queue */ 13705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.p_rx_sdu != NULL) 13715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 13725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_ccb->fcrb.p_rx_sdu); 13735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.p_rx_sdu = NULL; 13745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 13805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 13815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function do_sar_reassembly 13825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Process SAR bits and re-assemble frame 13845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE if all OK, else FALSE 13865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 13875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 13885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN do_sar_reassembly (tL2C_CCB *p_ccb, BT_HDR *p_buf, UINT16 ctrl_word) 13895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 13905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCRB *p_fcrb = &p_ccb->fcrb; 13915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 sar_type = ctrl_word & L2CAP_FCR_SEG_BITS; 13925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN packet_ok = TRUE; 13935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 13945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if the SAR state is correct */ 13965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((sar_type == L2CAP_FCR_UNSEG_SDU) || (sar_type == L2CAP_FCR_START_SDU)) 13975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 13985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->p_rx_sdu != NULL) 13995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1400a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("SAR - got unexpected unsegmented or start SDU Expected len: %u Got so far: %u", 14015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->rx_sdu_len, p_fcrb->p_rx_sdu->len); 14025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_ok = FALSE; 14045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check the length of the packet */ 14065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (sar_type == L2CAP_FCR_START_SDU) && (p_buf->len < L2CAP_SDU_LEN_OVERHEAD) ) 14075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1408a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("SAR start packet too short: %u", p_buf->len); 14095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_ok = FALSE; 14105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 14135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->p_rx_sdu == NULL) 14155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1416a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("SAR - got unexpected cont or end SDU"); 14175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_ok = FALSE; 14185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (packet_ok) && (sar_type != L2CAP_FCR_UNSEG_SDU) ) 14225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *)(p_buf + 1)) + p_buf->offset; 14245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* For start SDU packet, extract the SDU length */ 14265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (sar_type == L2CAP_FCR_START_SDU) 14275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the SDU length */ 14295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (p_fcrb->rx_sdu_len, p); 14305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset += 2; 14315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len -= 2; 14325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcrb->rx_sdu_len > p_ccb->max_rx_mtu) 14345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1435a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("SAR - SDU len: %u larger than MTU: %u", p_fcrb->rx_sdu_len, p_fcrb->rx_sdu_len); 14365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_ok = FALSE; 14375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ((p_fcrb->p_rx_sdu = (BT_HDR *)GKI_getpoolbuf (p_ccb->ertm_info.user_rx_pool_id)) == NULL) 14395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1440a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("SAR - no buffer for SDU start user_rx_pool_id:%d", p_ccb->ertm_info.user_rx_pool_id); 14415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_ok = FALSE; 14425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 14445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->p_rx_sdu->offset = 4; /* this is the minimal offset required by OBX to process incoming packets */ 14465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->p_rx_sdu->len = 0; 14475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (packet_ok) 14515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_fcrb->p_rx_sdu->len + p_buf->len) > p_fcrb->rx_sdu_len) 14535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1454a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("SAR - SDU len exceeded Type: %u Lengths: %u %u %u", 14555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sar_type, p_fcrb->p_rx_sdu->len, p_buf->len, p_fcrb->rx_sdu_len); 14565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_ok = FALSE; 14575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ( (sar_type == L2CAP_FCR_END_SDU) && ((p_fcrb->p_rx_sdu->len + p_buf->len) != p_fcrb->rx_sdu_len) ) 14595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1460a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("SAR - SDU end rcvd but SDU incomplete: %u %u %u", 14615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->p_rx_sdu->len, p_buf->len, p_fcrb->rx_sdu_len); 14625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_ok = FALSE; 14635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 14655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy (((UINT8 *) (p_fcrb->p_rx_sdu + 1)) + p_fcrb->p_rx_sdu->offset + p_fcrb->p_rx_sdu->len, p, p_buf->len); 14675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->p_rx_sdu->len += p_buf->len; 14695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 14715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = NULL; 14725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (sar_type == L2CAP_FCR_END_SDU) 14745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = p_fcrb->p_rx_sdu; 14765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcrb->p_rx_sdu = NULL; 14775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 14825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (packet_ok == FALSE) 14835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 14855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_buf != NULL) 14875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 14885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_NUM_FIXED_CHNLS > 0) 1489ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (p_ccb->local_cid < L2CAP_BASE_APPL_CID && 1490ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL && p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL)) 1491ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta { 1492ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb) 1493ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(p_ccb->p_lcb->remote_bd_addr, p_buf); 1494ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta } 14955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 14965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 14975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DATA, p_buf); 14985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 14995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (packet_ok); 15015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 15025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 15055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 15065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function retransmit_i_frames 15075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 15085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function retransmits i-frames awaiting acks. 15095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 15105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns BOOLEAN - TRUE if retransmitted 15115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 15125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 15135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN retransmit_i_frames (tL2C_CCB *p_ccb, UINT8 tx_seq) 15145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 15155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf, *p_buf2; 15165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 15175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 buf_seq; 15185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 ctrl_word; 15195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_ccb->fcrb.waiting_for_ack_q.p_first) 15215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_ccb->peer_cfg.fcr.max_transmit != 0) 15225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_ccb->fcrb.num_tries >= p_ccb->peer_cfg.fcr.max_transmit) ) 15235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1524a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("Max Tries Exceeded: (last_acq: %d CID: 0x%04x num_tries: %u (max: %u) ack_q_count: %u", 15255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.last_rx_ack, p_ccb->local_cid, p_ccb->fcrb.num_tries, p_ccb->peer_cfg.fcr.max_transmit, 15265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.waiting_for_ack_q.count); 15275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_disconnect_chnl (p_ccb); 15295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 15305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* tx_seq indicates whether to retransmit a specific sequence or all (if == L2C_FCR_RETX_ALL_PKTS) */ 15335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (tx_seq != L2C_FCR_RETX_ALL_PKTS) 15345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 15355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If sending only one, the sequence number tells us which one. Look for it. 15365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 15375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (p_buf = (BT_HDR *)p_ccb->fcrb.waiting_for_ack_q.p_first; p_buf; p_buf = (BT_HDR *)GKI_getnext (p_buf)) 15385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 15395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the old control word */ 15405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf+1)) + p_buf->offset + L2CAP_PKT_OVERHEAD; 15415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 15435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project buf_seq = (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT; 15455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1546a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("retransmit_i_frames() cur seq: %u looking for: %u", buf_seq, tx_seq); 15475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (tx_seq == buf_seq) 15495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 15505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_buf) 15535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1554a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("retransmit_i_frames() UNKNOWN seq: %u q_count: %u", tx_seq, p_ccb->fcrb.waiting_for_ack_q.count); 15555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (TRUE); 15565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 15595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 15605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Retransmitting everything. Flush buffers we already put in the link xmit queue. 15615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 15625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)p_ccb->p_lcb->link_xmit_data_q.p_first; 15635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_buf != NULL) 15655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 15665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Do not flush other CIDs or partial segments */ 15675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_buf->layer_specific == 0) && (p_buf->event == p_ccb->local_cid) ) 15685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 15695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf2 = p_buf; 15705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)GKI_getnext (p_buf); 15715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_remove_from_queue (&p_ccb->p_lcb->link_xmit_data_q, p_buf2); 15735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf2); 15745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 15765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)GKI_getnext (p_buf); 15775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Also flush our retransmission queue */ 15805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_ccb->fcrb.retrans_q.p_first) 15815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (GKI_dequeue (&p_ccb->fcrb.retrans_q)); 15825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)p_ccb->fcrb.waiting_for_ack_q.p_first; 15845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_buf != NULL) 15875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 15885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf2 = l2c_fcr_clone_buf (p_buf, p_buf->offset, p_buf->len, p_ccb->ertm_info.fcr_tx_pool_id); 15895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf2) 15915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 15925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf2->layer_specific = p_buf->layer_specific; 15935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_enqueue (&p_ccb->fcrb.retrans_q, p_buf2); 15955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 15965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (tx_seq != L2C_FCR_RETX_ALL_PKTS) || (p_buf2 == NULL) ) 15985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 15995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 16005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)GKI_getnext (p_buf); 16015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 16025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL); 16045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.waiting_for_ack_q.count) 16065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 16075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.num_tries++; 16085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_start_timer (p_ccb); 16095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 16105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (TRUE); 16125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 16135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 16165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 16175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_get_next_xmit_sdu_seg 16185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 16195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Get the next SDU segment to transmit. 16205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 16215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns pointer to buffer with segment or NULL 16225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 16235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 16245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBT_HDR *l2c_fcr_get_next_xmit_sdu_seg (tL2C_CCB *p_ccb, UINT16 max_packet_length) 16255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 16265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN first_seg = FALSE, /* The segment is the first part of data */ 16275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project mid_seg = FALSE, /* The segment is the middle part of data */ 16285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project last_seg = FALSE; /* The segment is the last part of data */ 1629ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta UINT16 sdu_len = 0; 16305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf, *p_xmit; 16315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 16325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 max_pdu = p_ccb->tx_mps /* Needed? - L2CAP_MAX_HEADER_FCS*/; 16335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If there is anything in the retransmit queue, that goes first 16355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 16365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.retrans_q.p_first) 16375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 16385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->fcrb.retrans_q); 16395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Update Rx Seq and FCS if we acked some packets while this one was queued */ 16415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project prepare_I_frame (p_ccb, p_buf, TRUE); 16425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->event = p_ccb->local_cid; 16445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORRUPT_ERTM_PKTS == TRUE 16465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Use sdu_len to hold the control word */ 16475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf+1)) + p_buf->offset + L2CAP_PKT_OVERHEAD; 16485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (sdu_len, p); 16495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get out if packet was dropped; just pretend it went out */ 16515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2c_corrupt_the_fcr_packet (p_ccb, p_buf, FALSE, sdu_len)) 16525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 16535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* L2CAP_CORRUPT_ERTM_PKTS */ 16545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 16565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.pkts_retransmitted++; 16575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_pkt_counts[0]++; 16585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_byte_counts[0] += (p_buf->len - 8); 16595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 16605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_buf); 16615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 16625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* For BD/EDR controller, max_packet_length is set to 0 */ 16645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* For AMP controller, max_packet_length is set by available blocks */ 16655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (max_packet_length > L2CAP_MAX_HEADER_FCS) 16665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (max_pdu + L2CAP_MAX_HEADER_FCS > max_packet_length) ) 16675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 16685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project max_pdu = max_packet_length - L2CAP_MAX_HEADER_FCS; 16695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 16705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)p_ccb->xmit_hold_q.p_first; 16725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If there is more data than the MPS, it requires segmentation */ 16745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf->len > max_pdu) 16755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 16765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We are using the "event" field to tell is if we already started segmentation */ 16775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf->event == 0) 16785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 16795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project first_seg = TRUE; 16805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sdu_len = p_buf->len; 16815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 16825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 16835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project mid_seg = TRUE; 16845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get a new buffer and copy the data that can be sent in a PDU */ 16865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit = l2c_fcr_clone_buf (p_buf, L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET, 16875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project max_pdu, p_ccb->ertm_info.fcr_tx_pool_id); 16885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_xmit != NULL) 16905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 16915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->event = p_ccb->local_cid; 16925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->event = p_ccb->local_cid; 16935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len -= max_pdu; 16955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset += max_pdu; 16965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 16975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* copy PBF setting */ 16985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->layer_specific = p_buf->layer_specific; 16995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* Should never happen if the application has configured buffers correctly */ 17015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1702a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CAP - cannot get buffer, for segmentation, pool: %u", p_ccb->ertm_info.fcr_tx_pool_id); 17035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 17045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* Use the original buffer if no segmentation, or the last segment */ 17075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 17085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_hold_q); 17095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_xmit->event != 0) 17115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project last_seg = TRUE; 17125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->event = p_ccb->local_cid; 17145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Step back to add the L2CAP headers */ 17175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->offset -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD); 17185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->len += L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD; 17195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (first_seg) 17215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 17225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->offset -= L2CAP_SDU_LEN_OVERHEAD; 17235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->len += L2CAP_SDU_LEN_OVERHEAD; 17245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Set the pointer to the beginning of the data */ 17275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (UINT8 *)(p_xmit + 1) + p_xmit->offset; 17285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Now the L2CAP header */ 17305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Note: if FCS has to be included then the length is recalculated later */ 17325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, p_xmit->len - L2CAP_PKT_OVERHEAD); 17335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, p_ccb->remote_cid); 17355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (first_seg) 17375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 17385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Skip control word and add SDU length */ 17395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p += 2; 17405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, sdu_len); 17415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We will store the SAR type in layer-specific */ 17435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* layer_specific is shared with flushable flag(bits 0-1), don't clear it */ 17445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->layer_specific |= L2CAP_FCR_START_SDU; 17455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project first_seg = FALSE; 17475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (mid_seg) 17495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->layer_specific |= L2CAP_FCR_CONT_SDU; 17505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (last_seg) 17515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->layer_specific |= L2CAP_FCR_END_SDU; 17525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 17535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->layer_specific |= L2CAP_FCR_UNSEG_SDU; 17545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project prepare_I_frame (p_ccb, p_xmit, FALSE); 17565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) 17585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 17595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_wack = l2c_fcr_clone_buf (p_xmit, HCI_DATA_PREAMBLE_SIZE, p_xmit->len, p_ccb->ertm_info.fcr_tx_pool_id); 17605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_wack) 17625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1763a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CAP - no buffer for xmit cloning, CID: 0x%04x Pool: %u Count: %u", 17645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->local_cid, p_ccb->ertm_info.fcr_tx_pool_id, GKI_poolfreecount(p_ccb->ertm_info.fcr_tx_pool_id)); 17655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We will not save the FCS in case we reconfigure and change options */ 17675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) 17685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_xmit->len -= L2CAP_FCS_LEN; 17695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Pretend we sent it and it got lost */ 17715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_enqueue (&p_ccb->fcrb.waiting_for_ack_q, p_xmit); 17725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 17735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 17755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 17765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 17775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* set timestamp at the end of tx I-frame to get acking delay */ 17785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_wack+1)) + p_wack->offset + p_wack->len; 17795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32_TO_STREAM (p, GKI_get_os_tick_count()); 17805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 17815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We will not save the FCS in case we reconfigure and change options */ 17825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) 17835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_wack->len -= L2CAP_FCS_LEN; 17845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_wack->layer_specific = p_xmit->layer_specific; 17865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_enqueue (&p_ccb->fcrb.waiting_for_ack_q, p_wack); 17875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORRUPT_ERTM_PKTS == TRUE 17905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 17915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 ctrl_word; 17925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_xmit+1)) + p_xmit->offset + L2CAP_PKT_OVERHEAD; 17935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (ctrl_word, p); 17945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 17955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get out if packet was dropped; pretend it was sent */ 17965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2c_corrupt_the_fcr_packet (p_ccb, p_xmit, FALSE, ctrl_word)) 17975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 17985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 17995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 18005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 18015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_pkt_counts[0]++; 18025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ertm_byte_counts[0] += (p_xmit->len - 8); 18035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 18045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 18065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_xmit); 18085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 18095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 18125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Configuration negotiation functions 18135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** The following functions are used in negotiating channel modes during 18155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** configuration 18165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project********************************************************************************/ 18175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 18195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_chk_chan_modes 18215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Validates and adjusts if necessary, the FCR options 18235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** based on remote EXT features. 18245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Note: This assumes peer EXT Features have been received. 18265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Basic mode is used if FCR Options have not been received 18275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns UINT8 - nonzero if can continue, '0' if no compatible channels 18295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 18315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 l2c_fcr_chk_chan_modes (tL2C_CCB *p_ccb) 18325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 18335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Remove nonbasic options that the peer does not support */ 18345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_ENH_RETRANS)) 18355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->ertm_info.allowed_modes &= ~L2CAP_FCR_CHAN_OPT_ERTM; 18365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_STREAM_MODE)) 18385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->ertm_info.allowed_modes &= ~L2CAP_FCR_CHAN_OPT_STREAM; 18395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* At least one type needs to be set (Basic, ERTM, STM) to continue */ 18415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_ccb->ertm_info.allowed_modes) 18425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1843a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP - Peer does not support our desired channel types"); 18445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 18455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_ccb->ertm_info.allowed_modes); 18475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 18485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 18505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_adj_our_req_options 18525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Validates and sets up the FCR options passed in from 18545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** L2CA_ConfigReq based on remote device's features. 18555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE if no errors, Otherwise FALSE 18575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 18585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 18595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2c_fcr_adj_our_req_options (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) 18605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 18615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2CAP_FCR_OPTS *p_fcr = &p_cfg->fcr; 18625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcr->mode != p_ccb->ertm_info.preferred_mode) 18645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1865a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("l2c_fcr_adj_our_req_options - preferred_mode (%d), does not match mode (%d)", 18665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->ertm_info.preferred_mode, p_fcr->mode); 18675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* The preferred mode is passed in through tL2CAP_ERTM_INFO, so override this one */ 18695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcr->mode = p_ccb->ertm_info.preferred_mode; 18705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 18715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If upper layer did not request eRTM mode, BASIC must be used */ 18735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->ertm_info.allowed_modes == L2CAP_FCR_CHAN_OPT_BASIC) 18745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 18755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcr_present && p_fcr->mode != L2CAP_FCR_BASIC_MODE) 18765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1877a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("l2c_fcr_adj_our_req_options (mode %d): ERROR: No FCR options set using BASIC mode", p_fcr->mode); 18785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 18795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcr->mode = L2CAP_FCR_BASIC_MODE; 18805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 18815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Process the FCR options if initial channel bring-up (not a reconfig request) 18835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Determine initial channel mode to try based on our options and remote's features 18845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 18855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcr_present && !(p_ccb->config_done & RECONFIG_FLAG)) 18865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 18875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We need to have at least one mode type common with the peer */ 18885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!l2c_fcr_chk_chan_modes(p_ccb)) 18895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 18905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Two channels have incompatible supported types */ 18915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_disconnect_chnl (p_ccb); 18925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 18935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 18945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 18955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Basic is the only common channel mode between the two devices */ 18965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_ccb->ertm_info.allowed_modes == L2CAP_FCR_CHAN_OPT_BASIC) 18975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 18985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We only want to try Basic, so bypass sending the FCR options entirely */ 18995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr_present = FALSE; 19005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcs_present = FALSE; /* Illegal to use FCS option in basic mode */ 19015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->ext_flow_spec_present = FALSE; /* Illegal to use extended flow spec in basic mode */ 19025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We have at least one non-basic mode available 19055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Override mode from available mode options based on preference, if needed 19065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 19075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 19085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If peer does not support STREAMING, try ERTM */ 19105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcr->mode == L2CAP_FCR_STREAM_MODE && !(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_STREAM)) 19115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1912a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("L2C CFG: mode is STREAM, but peer does not support; Try ERTM"); 19135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcr->mode = L2CAP_FCR_ERTM_MODE; 19145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If peer does not support ERTM, try BASIC (will support this if made it here in the code) */ 19175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcr->mode == L2CAP_FCR_ERTM_MODE && !(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_ERTM)) 19185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1919a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("L2C CFG: mode is ERTM, but peer does not support; Try BASIC"); 19205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcr->mode = L2CAP_FCR_BASIC_MODE; 19215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcr->mode != L2CAP_FCR_BASIC_MODE) 19255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* MTU must be smaller than buffer size */ 19275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_cfg->mtu_present) && (p_cfg->mtu > p_ccb->max_rx_mtu) ) 19285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1929a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP - MTU: %u larger than buf size: %u", p_cfg->mtu, p_ccb->max_rx_mtu); 19305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 19315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* application want to use the default MPS */ 19345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcr->mps == L2CAP_DEFAULT_ERM_MPS) 19355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcr->mps = L2CAP_MPS_OVER_BR_EDR; 19375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* MPS must be less than MTU */ 19395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_fcr->mps > p_ccb->max_rx_mtu) 19405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1941a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP - MPS %u invalid MTU: %u", p_fcr->mps, p_ccb->max_rx_mtu); 19425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 19435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We always initially read into the HCI buffer pool, so make sure it fits */ 19465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_fcr->mps > (L2CAP_MTU_SIZE - L2CAP_MAX_HEADER_FCS)) 19475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_fcr->mps = L2CAP_MTU_SIZE - L2CAP_MAX_HEADER_FCS; 19485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 19505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcs_present = FALSE; /* Illegal to use FCS option in basic mode */ 19525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->ext_flow_spec_present = FALSE; /* Illegal to use extended flow spec in basic mode */ 19535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr = *p_fcr; 19565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* Not sure how to send a reconfiguration(??) should fcr be included? */ 19585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr_present = FALSE; 19605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (TRUE); 19635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 19645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 19675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 19685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_adj_monitor_retran_timeout 19695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 19705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Overrides monitor/retrans timer value based on controller 19715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 19725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 19735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 19745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 19755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_adj_monitor_retran_timeout (tL2C_CCB *p_ccb) 19765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 19775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* adjust our monitor/retran timeout */ 19785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->out_cfg_fcr_present) 19795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* 19815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** if we requestd ERTM or accepted ERTM 19825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** We may accept ERTM even if we didn't request ERTM, in case of requesting STREAM 19835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 19845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_ccb->our_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) 19855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ||(p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)) 19865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* upper layer setting is ignored */ 19885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.mon_tout = L2CAP_MIN_MONITOR_TOUT; 19895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.rtrans_tout = L2CAP_MIN_RETRANS_TOUT; 19905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 19925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 19935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.mon_tout = 0; 19945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.rtrans_tout = 0; 19955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 19965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1997a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_adj_monitor_retran_timeout: mon_tout:%d, rtrans_tout:%d", 19985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.mon_tout, p_ccb->our_cfg.fcr.rtrans_tout); 19995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 20005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 20015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 20025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_adj_our_rsp_options 20045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Overrides any neccesary FCR options passed in from 20065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** L2CA_ConfigRsp based on our FCR options. 20075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Only makes adjustments if channel is in ERTM mode. 20085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 20105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 20125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid l2c_fcr_adj_our_rsp_options (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) 20135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 20145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* adjust our monitor/retran timeout */ 20155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_adj_monitor_retran_timeout(p_ccb); 20165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr_present = p_ccb->out_cfg_fcr_present; 20185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcr_present) 20205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 20215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific ++ 20225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Temporary - until a better algorithm is implemented */ 20235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If peer's tx_wnd_sz requires too many buffers for us to support, then adjust it. For now, respond with our own tx_wnd_sz. */ 20245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Note: peer is not guaranteed to obey our adjustment */ 20255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->peer_cfg.fcr.tx_win_sz > p_ccb->our_cfg.fcr.tx_win_sz) 20265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2027a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("%s: adjusting requested tx_win_sz from %i to %i", __FUNCTION__, p_ccb->peer_cfg.fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz); 20285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->peer_cfg.fcr.tx_win_sz = p_ccb->our_cfg.fcr.tx_win_sz; 20295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 20305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// btla-specific -- 20315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.mode = p_ccb->peer_cfg.fcr.mode; 20335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.tx_win_sz = p_ccb->peer_cfg.fcr.tx_win_sz; 20345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.max_transmit = p_ccb->peer_cfg.fcr.max_transmit; 20355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.mps = p_ccb->peer_cfg.fcr.mps; 20365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.rtrans_tout = p_ccb->our_cfg.fcr.rtrans_tout; 20375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.mon_tout = p_ccb->our_cfg.fcr.mon_tout; 20385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 20395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 20405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 20425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_renegotiate_chan 20445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Called upon unsuccessful peer response to config request. 20465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** If the error is because of the channel mode, it will try 20475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** to resend using another supported optional channel. 20485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE if resent configuration, False if channel matches or 20505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** cannot match. 20515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 20525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 20535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN l2c_fcr_renegotiate_chan(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) 20545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 20555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 peer_mode = p_ccb->our_cfg.fcr.mode; 20565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN can_renegotiate; 20575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Skip if this is a reconfiguration from OPEN STATE or if FCR is not returned */ 20595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_cfg->fcr_present || (p_ccb->config_done & RECONFIG_FLAG)) 20605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 20615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Only retry if there are more channel options to try */ 20635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->result == L2CAP_CFG_UNACCEPTABLE_PARAMS) 20645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 20655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project peer_mode = (p_cfg->fcr_present) ? p_cfg->fcr.mode : L2CAP_FCR_BASIC_MODE; 20665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->our_cfg.fcr.mode != peer_mode) 20685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 20695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((--p_ccb->fcr_cfg_tries) == 0) 20715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 20725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->result = L2CAP_CFG_FAILED_NO_REASON; 2073a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("l2c_fcr_renegotiate_chan (Max retries exceeded)"); 20745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 20755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project can_renegotiate = FALSE; 20775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Try another supported mode if available based on our last attempted channel */ 20795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch (p_ccb->our_cfg.fcr.mode) 20805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 20815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Our Streaming mode request was unnacceptable; try ERTM or Basic */ 20825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case L2CAP_FCR_STREAM_MODE: 20835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Peer wants ERTM and we support it */ 20845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (peer_mode == L2CAP_FCR_ERTM_MODE) && (p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_ERTM) ) 20855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2086a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_renegotiate_chan(Trying ERTM)"); 20875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.mode = L2CAP_FCR_ERTM_MODE; 20885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project can_renegotiate = TRUE; 20895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 20905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* Falls through */ 20915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 20925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case L2CAP_FCR_ERTM_MODE: 20935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 20945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We can try basic for any other peer mode if we support it */ 20955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_BASIC) 20965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2097a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("l2c_fcr_renegotiate_chan(Trying Basic)"); 20985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project can_renegotiate = TRUE; 20995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.mode = L2CAP_FCR_BASIC_MODE; 21005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 21035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project default: 21055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* All other scenarios cannot be renegotiated */ 21065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 21075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (can_renegotiate) 21105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 21115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr_present = TRUE; 21125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->our_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) 21145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 21155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcs_present = FALSE; 21165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.ext_flow_spec_present = FALSE; 21175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Basic Mode uses ACL Data Pool, make sure the MTU fits */ 21195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_cfg->mtu_present) && (p_cfg->mtu > L2CAP_MTU_SIZE) ) 21205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2121a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CAP - adjust MTU: %u too large", p_cfg->mtu); 21225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->mtu = L2CAP_MTU_SIZE; 21235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_process_our_cfg_req (p_ccb, &p_ccb->our_cfg); 21275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_send_peer_config_req (p_ccb, &p_ccb->our_cfg); 21285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_L2CAP_CHNL, L2CAP_CHNL_CFG_TIMEOUT); 21295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (TRUE); 21305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Disconnect if the channels do not match */ 21355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->our_cfg.fcr.mode != peer_mode) 21365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2137a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2C CFG: Channels incompatible (local %d, peer %d)", 21385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.mode, peer_mode); 21395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2cu_disconnect_chnl (p_ccb); 21405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (FALSE); 21435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 21445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 21475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 21485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_process_peer_cfg_req 21495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 21505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is called to process the FCR options passed 21515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** in the peer's configuration request. 21525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 21535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns UINT8 - L2CAP_PEER_CFG_OK, L2CAP_PEER_CFG_UNACCEPTABLE, 21545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** or L2CAP_PEER_CFG_DISCONNECT. 21555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 21565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 21575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 l2c_fcr_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg) 21585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 21595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 max_retrans_size; 21605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 fcr_ok = L2CAP_PEER_CFG_OK; 21615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->p_lcb->w4_info_rsp = FALSE; /* Handles T61x SonyEricsson Bug in Info Request */ 21635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2164a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_EVENT ("l2c_fcr_process_peer_cfg_req() CFG fcr_present:%d fcr.mode:%d CCB FCR mode:%d preferred: %u allowed:%u", 21655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr_present, p_cfg->fcr.mode, p_ccb->our_cfg.fcr.mode, p_ccb->ertm_info.preferred_mode, 21665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->ertm_info.allowed_modes); 21675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If Peer wants basic, we are done (accept it or disconnect) */ 21695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcr.mode == L2CAP_FCR_BASIC_MODE) 21705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 21715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we do not allow basic, disconnect */ 21725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( !(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_BASIC) ) 21735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcr_ok = L2CAP_PEER_CFG_DISCONNECT; 21745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Need to negotiate if our modes are not the same */ 21775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_cfg->fcr.mode != p_ccb->ertm_info.preferred_mode) 21785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 21795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If peer wants a mode that we don't support then retry our mode (ex. rtx/flc), OR 21805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** If we want ERTM and they wanted streaming retry our mode. 21815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Note: If we have already determined they support our mode previously 21825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** from their EXF mask. 21835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 21845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (((1 << p_cfg->fcr.mode) & L2CAP_FCR_CHAN_OPT_ALL_MASK) == 0) 21855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_ccb->ertm_info.preferred_mode == L2CAP_FCR_ERTM_MODE) ) 21865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 21875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.mode = p_ccb->our_cfg.fcr.mode; 21885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.tx_win_sz = p_ccb->our_cfg.fcr.tx_win_sz; 21895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.max_transmit = p_ccb->our_cfg.fcr.max_transmit; 21905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcr_ok = L2CAP_PEER_CFG_UNACCEPTABLE; 21915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 21925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 21935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we wanted basic, then try to renegotiate it */ 21945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_ccb->ertm_info.preferred_mode == L2CAP_FCR_BASIC_MODE) 21955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 21965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.mode = L2CAP_FCR_BASIC_MODE; 21975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.max_transmit = p_cfg->fcr.tx_win_sz = 0; 21985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.rtrans_tout = p_cfg->fcr.mon_tout = p_cfg->fcr.mps = 0; 21995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->our_cfg.fcr.rtrans_tout = p_ccb->our_cfg.fcr.mon_tout = p_ccb->our_cfg.fcr.mps = 0; 22005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcr_ok = L2CAP_PEER_CFG_UNACCEPTABLE; 22015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Only other valid case is if they want ERTM and we wanted STM which should be 22045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project accepted if we support it; otherwise the channel should be disconnected */ 22055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ( (p_cfg->fcr.mode != L2CAP_FCR_ERTM_MODE) 22065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || !(p_ccb->ertm_info.allowed_modes & L2CAP_FCR_CHAN_OPT_ERTM) ) 22075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 22085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcr_ok = L2CAP_PEER_CFG_DISCONNECT; 22095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Configuration for FCR channels so make any adjustments and fwd to upper layer */ 22135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (fcr_ok == L2CAP_PEER_CFG_OK) 22145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 22155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* by default don't need to send params in the response */ 22165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->out_cfg_fcr_present = FALSE; 22175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Make any needed adjustments for the response to the peer */ 22195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcr_present && p_cfg->fcr.mode != L2CAP_FCR_BASIC_MODE) 22205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 22215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Peer desires to bypass FCS check, and streaming or ERTM mode */ 22225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcs_present) 22235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 22245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->peer_cfg.fcs = p_cfg->fcs; 22255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FCS; 22265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_cfg->fcs == L2CAP_CFG_FCS_BYPASS) 22275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->bypass_fcs |= L2CAP_CFG_FCS_PEER; 22285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project max_retrans_size = GKI_get_pool_bufsize (p_ccb->ertm_info.fcr_tx_pool_id) - sizeof(BT_HDR) 22315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project - L2CAP_MIN_OFFSET - L2CAP_SDU_LEN_OFFSET - L2CAP_FCS_LEN; 22325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Ensure the MPS is not bigger than the MTU */ 22345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_cfg->fcr.mps == 0) || (p_cfg->fcr.mps > p_ccb->peer_cfg.mtu) ) 22355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 22365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.mps = p_ccb->peer_cfg.mtu; 22375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->out_cfg_fcr_present = TRUE; 22385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Ensure the MPS is not bigger than our retransmission buffer */ 22415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcr.mps > max_retrans_size) 22425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2243a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG("CFG: Overriding MPS to %d (orig %d)", max_retrans_size, p_cfg->fcr.mps); 22445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->fcr.mps = max_retrans_size; 22465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->out_cfg_fcr_present = TRUE; 22475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22498fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE || p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE) 22505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 22515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Always respond with FCR ERTM parameters */ 22525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->out_cfg_fcr_present = TRUE; 22535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Everything ok, so save the peer's adjusted fcr options */ 22575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->peer_cfg.fcr = p_cfg->fcr; 22585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->fcr_present) 22605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->peer_cfg_bits |= L2CAP_CH_CFG_MASK_FCR; 22615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (fcr_ok == L2CAP_PEER_CFG_UNACCEPTABLE) 22635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 22645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Allow peer only one retry for mode */ 22655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->peer_cfg_already_rejected) 22665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project fcr_ok = L2CAP_PEER_CFG_DISCONNECT; 22675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 22685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->peer_cfg_already_rejected = TRUE; 22695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 22705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (fcr_ok); 22725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 22735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORRUPT_ERTM_PKTS == TRUE 22765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 22775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Functions used for testing ERTM mode 22785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 22795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* If FALSE, will also corrupt cid, length, control word, etc. */ 22805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef L2CAP_CORR_FCS_ONLY 22815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define L2CAP_CORR_FCS_ONLY TRUE 22825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 22835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 22845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define L2C_DISP_FRAME_SIZE 16 22855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 22865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 22875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_corrupt_the_fcr_packet 22885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 22895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is used for testing purposes only. 22905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** It systematically or randomly corrupts packets used with 22915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** ERTM channels. 22925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 22935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns BOOLEAN TRUE if packet was dropped, 22945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** FALSE if fcs corrupted or no corruption 22955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 22965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 22975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN l2c_corrupt_the_fcr_packet (tL2C_CCB *p_ccb, BT_HDR *p_buf, 22985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN is_rx, UINT16 ctrl_word) 22995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 23005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCR_TEST_CFG *p_cfg; 23015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 tc; 23025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 23035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 xx; 23045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project char buf[L2C_DISP_FRAME_SIZE]; 23055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_ccb || !p_ccb->fcrb.test_cb.cfg.in_use) 23075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 23085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Prepare bad FCS */ 23105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf + 1)) + p_buf->offset; 23115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tc = GKI_get_os_tick_count(); 23125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tc ^= p[p_buf->len - 1]; 23135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project xx = tc % 47; 23145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg = &p_ccb->fcrb.test_cb.cfg; 23165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if 0 2317a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_DEBUG ("testcfg: type: %d, freq: %d (NRM-0, RDM-1), is_rx: %d, count: %d", 23185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cfg->type, p_cfg->freq, p_cfg->is_rx, p_cfg->count); 23195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 23205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If not time to corrupt get out */ 23215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cfg->freq == L2CAP_FCR_FREQ_RANDOM) 23225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (xx != 0) 23245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 23255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* check test criteria before corrupting */ 23275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( (p_cfg->count == 0) 23295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_cfg->is_rx != is_rx) 23305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || ((UINT8)(ctrl_word & L2CAP_FCR_S_FRAME_BIT) != p_cfg->type) ) 23315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 23335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Turn off if done */ 23365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (--(p_cfg->count) == 0) 23375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.test_cb.cfg.in_use = FALSE; 23395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if L2CAP_CORR_FCS_ONLY == TRUE 23435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Corrupt the FCS check */ 23445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p[p_buf->len - 1] = p[p_buf->len - 2] = 0; 23455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 23465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If made it this far packet needs to be corrupted */ 23475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project xx = tc % p_buf->len; 23485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Make sure the value was changed */ 23505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p[xx + 1] == 0) 23515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p[xx + 1] = 0x5A; 23525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p[xx] = p[xx] ^ p[xx + 1]; 23545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if 1 /* Enable if not wishing to corrupting frame type */ 23565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p_temp = ((UINT8 *) (p_buf + 1)) + p_buf->offset; 23585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_temp += L2CAP_PKT_OVERHEAD; 23595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((UINT16)((*p_temp) & 0x01) != (ctrl_word & 0x0001)) 23605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (*p_temp) |= (UINT8)(ctrl_word & 0x0001); 23625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 23655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 23665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (is_rx) 23685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_S_FRAME_BIT) 23705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BCM_STRCPY_S(buf, L2C_DISP_FRAME_SIZE, "Rx S-Frame"); 23715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 23725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BCM_STRCPY_S(buf, L2C_DISP_FRAME_SIZE, "Rx I-Frame"); 23735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 23755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 23765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ctrl_word & L2CAP_FCR_S_FRAME_BIT) 23775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BCM_STRCPY_S(buf, L2C_DISP_FRAME_SIZE, "Tx S-Frame"); 23785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 23795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BCM_STRCPY_S(buf, L2C_DISP_FRAME_SIZE, "Tx I-Frame"); 23805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Lastly, just drop packet if FCS is not being used or if Tx */ 23835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!is_rx || p_ccb->bypass_fcs == L2CAP_BYPASS_FCS) 23845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2385a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("-=-=-=-=-=-=-=- Dropping %s packet (0x%04x) tc: %u Buf Len: %u xx: %u count: %d", 23865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project buf, (UINT32)p_buf, tc, p_buf->len, xx, p_cfg->count); 23875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf(p_buf); 23885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 23895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 23915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2392a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("-=-=-=-=-=-=-=- Corrupting %s packet (0x%04x) tc: %u Buf Len: %u xx: %u count: %d", 23935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project buf, (UINT32)p_buf, tc, p_buf->len, xx, p_cfg->count); 23945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 23955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 23975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 23985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 23995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 24015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function L2CA_SetupErtmTest 24035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is used for testing purposes only. 24055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** It corrupts or drops one or more packets used with ERTM channels. 24065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters 24085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** cid - channel ID (0 uses RFCOMM PSM's CID) 24095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** type - type of test to run (L2CAP_FCR_TTYPE_CORR_IFRAMES 24115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** L2CAP_FCR_TTYPE_CORR_SFRAME 24125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** L2CAP_FCR_TTYPE_STOP_TEST 24135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** L2CAP_FCR_TTYPE_GET_CID - returns rfcomm cid only) 24145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** is_rx - TRUE to corrupt Rx packet, FALSE for Tx packet) 24165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** freq - L2CAP_FCR_FREQ_RANDOM (turns on random corruptions/drops) 24185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** L2CAP_FCR_FREQ_NORMAL (turns on test with "count" corruptions/drops) 24195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** count - number of packets in a row to drop or corrupt 24215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns CID of channel running test 24235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 24245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 24255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT16 L2CA_SetupErtmTest (UINT16 cid, UINT8 type, BOOLEAN is_rx, UINT8 freq, UINT16 count) 24265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 24275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_CCB *p_ccb = NULL; 24285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_CCB *p_temp_ccb; 24295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCR_TEST_CB *p_test_cb; 24305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 xx; 24315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If '0' tests run on top of RFCOMM CID if active */ 24335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (cid == 0) 24345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 24355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_temp_ccb = l2cb.ccb_pool; 24365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (xx = 0; xx < MAX_L2CAP_CHANNELS; xx++, p_temp_ccb++) 24375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 24385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Fixed channels don't have p_rcb's */ 24395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_temp_ccb->in_use && p_temp_ccb->p_rcb && p_temp_ccb->p_rcb->psm == BT_PSM_RFCOMM) 24405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 24415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb = p_temp_ccb; 24425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project cid = L2CAP_BASE_APPL_CID + xx; 24435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 24445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 24485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb = l2cu_find_ccb_by_cid (NULL, cid); 24495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_ccb || type == L2CAP_FCR_TTYPE_GET_CID) 24515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 24525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (type == L2CAP_FCR_TTYPE_GET_CID) 24535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2454a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_API ("L2CA_SetupErtmTest (GET_CID): cid = 0x%04x", cid); 24555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (cid); 24575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb = &p_ccb->fcrb.test_cb; 24605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Turn off the current test */ 24625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (type == L2CAP_FCR_TTYPE_STOP_TEST) 24635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 24645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_test_cb->cfg.in_use) 24655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2466a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CA_SetupErtmTest (OFF): cid 0x%04x", cid); 24675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->cfg.in_use = FALSE; 24695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->cfg.count = 0; 24705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Process the new request */ 24735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (!p_test_cb->cfg.in_use) 24745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 24755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* count must be positive unless random is used */ 24765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!count && freq != L2CAP_FCR_FREQ_RANDOM) 24775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2478a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CA_SetupErtmTest (FAIL): Count = 0, freq = %d", freq); 24795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (cid); 24805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2482a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CA_SetupErtmTest (START): cid 0x%04x, type %d, is_rx %d, freq %d, count %d", 24835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project cid, type, is_rx, freq, count); 24845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->cfg.in_use = TRUE; 24865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->cfg.freq = freq; 24875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->cfg.type = type; 24885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->cfg.is_rx = is_rx; 24895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->cfg.count = count; 24905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /* Test already in progress so ignore */ 24925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2493a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CA_SetupErtmTest (ignoring): cid 0x%04x, type %d, is_rx %d, freq %d, count %d", 24945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project cid, type, is_rx, freq, count); 24955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 24965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (cid); 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** The following routines are only used in conjunction with Conformance testing 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** Function L2CA_SendPolledSFrame 25085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is used for testing purposes only. 25105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** It Sends a Polled RR or RNR to the peer 25115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters 25135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** cid - channel ID 25145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** sup_type - (L2CAP_FCR_SUP_RR or L2CAP_FCR_SUP_RNR) 25165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns void 25185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 25205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid L2CA_SendPolledSFrame (UINT16 cid, UINT16 sup_type) 25215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 25225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_CCB *p_ccb = l2cu_find_ccb_by_cid (NULL, cid); 25235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb && (sup_type == L2CAP_FCR_SUP_RR || sup_type == L2CAP_FCR_SUP_RNR)) 25255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 25265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project l2c_fcr_send_S_frame (p_ccb, sup_type, L2CAP_FCR_P_BIT); 25275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 25285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 25295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2530a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("L2CA_SendPolledSFrame(ERROR): sup_type %u, p_ccb 0x%07x", 25315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sup_type, (UINT32)p_ccb); 25325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 25335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 25345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 25365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_bypass_sframe_packet 25385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is used for testing purposes only. 25405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** It returns TRUE if S-Frame should be bypassed. 25415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns void 25435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 25455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN l2c_bypass_sframe_packet (tL2C_CCB *p_ccb) 25465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 25475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb && p_ccb->fcrb.test_cb.cfm.in_use) 25485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 25495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.test_cb.cfm.skip_sframe_count > 0) 25505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2551a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_ERROR ("l2c_bypass_sframe_packet (count %d)", 25525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.test_cb.cfm.skip_sframe_count); 25535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (--p_ccb->fcrb.test_cb.cfm.skip_sframe_count == 0) 25555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.test_cb.cfm.in_use = FALSE; 25565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Bypass sending S-Frame */ 25585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 25595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 25605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 25615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.test_cb.cfm.in_use = FALSE; 25625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 25635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 25655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 25665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 25685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function L2CA_BypassSFrame 25705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is used for testing purposes only. 25725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** It skips sending 'count' S-Frames. 25735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters 25755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** cid - channel ID 25765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** count - Number of S-Frames to skip sending 25785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns void 25805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 25815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 25825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid L2CA_BypassSFrame (UINT16 cid, UINT8 count) 25835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 25845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_CCB *p_ccb = l2cu_find_ccb_by_cid (NULL, cid); 25855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tL2C_FCR_CFM_TEST_CB *p_test_cb; 25865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_ccb) 25885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2589a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CA_BypassSFrame(ERROR): no p_ccb (0x%07x)", (UINT32)p_ccb); 25905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 25915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 25925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb = &p_ccb->fcrb.test_cb.cfm; 25945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 25955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Initiate test if not active */ 25965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_test_cb->in_use) 25975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 25985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->in_use = TRUE; 25995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_test_cb->skip_sframe_count = count; 26005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 26015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 26025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2603a51c9d9d225e41fe36a0133f1c17fd981ea59c1dSharvil Nanavati L2CAP_TRACE_WARNING ("L2CA_BypassSFrame(ERROR): already in use (ignoring...)"); 26045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 26055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 26065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif /* L2CAP_CORRUPT_ERTM_PKTS == TRUE */ 26085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (L2CAP_ERTM_STATS == TRUE) 26105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 26115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 26125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function l2c_fcr_collect_ack_delay 26135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 26145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description collect throughput, delay, queue size of waiting ack 26155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 26165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters 26175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** tL2C_CCB 26185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 26195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns void 26205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 26215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 26225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void l2c_fcr_collect_ack_delay (tL2C_CCB *p_ccb, UINT8 num_bufs_acked) 26235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 26245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 index; 26255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf; 26265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 *p; 26275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 timestamp, delay; 26285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 xx; 26295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 str[120]; 26305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project index = p_ccb->fcrb.ack_delay_avg_index; 26325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* update sum, max and min of waiting for ack queue size */ 26345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_avg[index] += p_ccb->fcrb.waiting_for_ack_q.count; 26355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( p_ccb->fcrb.waiting_for_ack_q.count > p_ccb->fcrb.ack_q_count_max[index] ) 26375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_max[index] = p_ccb->fcrb.waiting_for_ack_q.count; 26385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( p_ccb->fcrb.waiting_for_ack_q.count < p_ccb->fcrb.ack_q_count_min[index] ) 26405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_min[index] = p_ccb->fcrb.waiting_for_ack_q.count; 26415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* update sum, max and min of round trip delay of acking */ 26435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (BT_HDR *)(p_ccb->fcrb.waiting_for_ack_q.p_first); 26445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (xx = 0; (xx < num_bufs_acked)&&(p_buf); xx++) 26455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 26465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* adding up length of acked I-frames to get throughput */ 26475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.throughput[index] += p_buf->len - 8; 26485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( xx == num_bufs_acked - 1 ) 26505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 26515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* get timestamp from tx I-frame that receiver is acking */ 26525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((UINT8 *) (p_buf+1)) + p_buf->offset + p_buf->len; 26535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->bypass_fcs != L2CAP_BYPASS_FCS) 26545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 26555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p += L2CAP_FCS_LEN; 26565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 26575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT32 (timestamp, p); 26595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project delay = GKI_get_os_tick_count() - timestamp; 26605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg[index] += delay; 26625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( delay > p_ccb->fcrb.ack_delay_max[index] ) 26635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_max[index] = delay; 26645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ( delay < p_ccb->fcrb.ack_delay_min[index] ) 26655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_min[index] = delay; 26665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 26675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = GKI_getnext(p_buf); 26695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 26705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg_count++; 26725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* calculate average and initialize next avg, min and max */ 26745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_ccb->fcrb.ack_delay_avg_count > L2CAP_ERTM_STATS_AVG_NUM_SAMPLES) 26755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 26765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg_count = 0; 26775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_avg[index] /= L2CAP_ERTM_STATS_AVG_NUM_SAMPLES; 26795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg[index] /= L2CAP_ERTM_STATS_AVG_NUM_SAMPLES; 26805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* calculate throughput */ 26825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project timestamp = GKI_get_os_tick_count(); 26835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (timestamp - p_ccb->fcrb.throughput_start > 0 ) 26845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.throughput[index] /= (timestamp - p_ccb->fcrb.throughput_start); 26855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.throughput_start = timestamp; 26875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sprintf(str, "[%02u] throughput: %5u, ack_delay avg:%3u, min:%3u, max:%3u, ack_q_count avg:%3u, min:%3u, max:%3u", 26895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project index, p_ccb->fcrb.throughput[index], 26905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg[index], p_ccb->fcrb.ack_delay_min[index], p_ccb->fcrb.ack_delay_max[index], 26915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_avg[index], p_ccb->fcrb.ack_q_count_min[index], p_ccb->fcrb.ack_q_count_max[index] ); 26925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26930212487880be33e255d49f6e38dbb035d1f77750Sharvil Nanavati BT_TRACE(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI , TRACE_TYPE_GENERIC, "%s", str); 26945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project index = (index + 1) % L2CAP_ERTM_STATS_NUM_AVG; 26965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg_index = index; 26975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 26985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_max[index] = 0; 26995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_min[index] = 0xFFFFFFFF; 27005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_q_count_avg[index] = 0; 27015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 27025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 27035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_max[index] = 0; 27045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_min[index] = 0xFFFFFFFF; 27055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.ack_delay_avg[index] = 0; 27065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 27075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_ccb->fcrb.throughput[index] = 0; 27085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 27095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 27105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 27115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 27125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 27135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2714