15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 1999-2012 Broadcom Corporation 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Port Emulation entity utilities 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h> 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h" 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.h" 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "rfcdefs.h" 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "port_api.h" 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "port_int.h" 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "rfc_int.h" 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2cdefs.h" 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_int.h" 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btu.h" 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const tPORT_STATE default_port_pars = 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_BAUD_RATE_9600, 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_8_BITS, 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_ONESTOPBIT, 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_PARITY_NO, 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_ODD_PARITY, 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_FC_OFF, 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 0, /* No rx_char */ 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_XON_DC1, 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_XOFF_DC3, 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_allocate_port 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Look through the Port Control Blocks for a free one. Note 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** that one server can open several ports with the same SCN 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** if it can support simulteneous requests from different 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** clients. 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttPORT *port_allocate_port (UINT8 dlci, BD_ADDR bd_addr) 645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT *p_port = &rfc_cb.port.port[0]; 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 xx, yy; 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (xx = 0, yy = rfc_cb.rfc.last_port + 1; xx < MAX_RFC_PORTS; xx++, yy++) 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (yy >= MAX_RFC_PORTS) 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project yy = 0; 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port = &rfc_cb.port.port[yy]; 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_port->in_use) 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (p_port, 0, sizeof (tPORT)); 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->in_use = TRUE; 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->inx = yy + 1; 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->dlci = dlci; 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy (p_port->bd_addr, bd_addr, BD_ADDR_LEN); 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* During the open set default state for the port connection */ 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project port_set_defaults (p_port); 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rfc_cb.rfc.last_port = yy; 88689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project RFCOMM_TRACE_DEBUG2("rfc_cb.port.port[%d] allocated, last_port:%d", yy, rfc_cb.rfc.last_port); 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If here, no free PORT found */ 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_set_defaults 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Set defualt port parameters 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_set_defaults (tPORT *p_port) 1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->ev_mask = 0; 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->p_callback = NULL; 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->port_ctrl = 0; 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->error = 0; 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->line_status = 0; 1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx_flag_ev_pending = FALSE; 1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->peer_mtu = RFCOMM_DEFAULT_MTU; 1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->user_port_pars = default_port_pars; 1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->peer_port_pars = default_port_pars; 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_tx = 0; 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx = 0; 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* p_port->credit_rx_max = PORT_CREDIT_RX_MAX; Determined later */ 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* p_port->credit_rx_low = PORT_CREDIT_RX_LOW; Determined later */ 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->local_ctrl, 0, sizeof (p_port->local_ctrl)); 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->peer_ctrl, 0, sizeof (p_port->peer_ctrl)); 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->rx, 0, sizeof (p_port->rx)); 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->tx, 0, sizeof (p_port->tx)); 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** Function port_select_mtu 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Select MTU which will best serve connection from our 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** point of view. 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** If our device is 1.2 or lower we calculate how many DH5s 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** fit into 1 RFCOMM buffer. 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_select_mtu (tPORT *p_port) 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 packet_size; 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Will select MTU only if application did not setup something */ 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->mtu == 0) 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* find packet size which connection supports */ 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_size = btm_get_max_packet_size (p_port->bd_addr); 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (packet_size == 0) 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* something is very wrong */ 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_WARNING0 ("port_select_mtu bad packet size"); 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = RFCOMM_DEFAULT_MTU; 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We try to negotiate MTU that each packet can be split into whole 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project number of max packets. For example if link is 1.2 max packet size is 339 bytes. 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4 overhead. 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1695, that will be 5 Dh5 packets. Now maximum RFCOMM packet is 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691. Minus RFCOMM 6 bytes header overhead 1685 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1 3DH5 packet 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. Minus RFCOMM 6 bytes header overhead 1017 */ 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) >= packet_size) 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) / packet_size * packet_size) - RFCOMM_DATA_OVERHEAD - L2CAP_PKT_OVERHEAD; 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_select_mtu selected %d based on connection speed", p_port->mtu); 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD; 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_select_mtu selected %d based on l2cap PDU size", p_port->mtu); 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_select_mtu application selected %d", p_port->mtu); 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_max = (PORT_RX_HIGH_WM / p_port->mtu); 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->credit_rx_max > PORT_RX_BUF_HIGH_WM ) 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_max = PORT_RX_BUF_HIGH_WM; 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_low = (PORT_RX_LOW_WM / p_port->mtu); 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->credit_rx_low > PORT_RX_BUF_LOW_WM ) 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_low = PORT_RX_BUF_LOW_WM; 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx_buf_critical = (PORT_RX_CRITICAL_WM / p_port->mtu); 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->rx_buf_critical > PORT_RX_BUF_CRITICAL_WM ) 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx_buf_critical = PORT_RX_BUF_CRITICAL_WM; 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG3 ("port_select_mtu credit_rx_max %d, credit_rx_low %d, rx_buf_critical %d", 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_max, p_port->credit_rx_low, p_port->rx_buf_critical); 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_release_port 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Release port infor control block. 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_release_port (tPORT *p_port) 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf; 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 mask; 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT_CALLBACK *p_port_cb; 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT_STATE user_port_pars; 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_SCHEDULE_LOCK; 213689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project RFCOMM_TRACE_DEBUG1("port_release_port, p_port:%p", p_port); 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue)) != NULL) 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.queue_size = 0; 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->tx.queue)) != NULL) 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->tx.queue_size = 0; 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_SCHEDULE_UNLOCK; 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->state = PORT_STATE_CLOSED; 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rfc.state == RFC_STATE_CLOSED) 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG0 ("rfc_port_closed DONE"); 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rfc.p_mcb) 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rfc.p_mcb->port_inx[p_port->dlci] = 0; 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If there are no more ports opened on this MCB release it */ 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rfc_check_mcb_active (p_port->rfc.p_mcb); 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rfc_port_timer_stop (p_port); 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->keep_port_handle ) 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_release_port:Initialize handle:%d", p_port->inx); 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* save event mask and callback */ 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project mask = p_port->ev_mask; 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port_cb = p_port->p_callback; 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project user_port_pars = p_port->user_port_pars; 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project port_set_defaults(p_port); 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* restore */ 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->ev_mask = mask; 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->p_callback = p_port_cb; 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->user_port_pars = user_port_pars; 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = p_port->keep_mtu; 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->state = PORT_STATE_OPENING; 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rfc.p_mcb = NULL; 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(p_port->is_server) 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->dlci &= 0xfe; 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->local_ctrl.modem_signal = p_port->default_signal_state; 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy (p_port->bd_addr, BT_BD_ANY, BD_ADDR_LEN); 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_release_port:Clean-up handle:%d", p_port->inx); 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (p_port, 0, sizeof (tPORT)); 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_mcb 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function checks if connection exists to device with 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** the BD_ADDR. 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttRFC_MCB *port_find_mcb (BD_ADDR bd_addr) 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (i = 0; i < MAX_BD_CONNECTIONS; i++) 2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((rfc_cb.port.rfc_mcb[i].state != RFC_MX_STATE_IDLE) 2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !memcmp (rfc_cb.port.rfc_mcb[i].bd_addr, bd_addr, BD_ADDR_LEN)) 2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Multiplexer channel found do not change anything */ 2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (&rfc_cb.port.rfc_mcb[i]); 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_mcb_dlci_port 3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Find port on the multiplexer channel based on DLCI. If 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** this port with DLCI not found try to use even DLCI. This 3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** is for the case when client is establishing connection on 3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** none-initiator MCB. 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttPORT *port_find_mcb_dlci_port (tRFC_MCB *p_mcb, UINT8 dlci) 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 inx; 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_mcb) 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (dlci > RFCOMM_MAX_DLCI) 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project inx = p_mcb->port_inx[dlci]; 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (inx == 0) 3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (&rfc_cb.port.port[inx - 1]); 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** 3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_dlci_port 3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Find port with DLCI not assigned to multiplexer channel 3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttPORT *port_find_dlci_port (UINT8 dlci) 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 i; 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT *p_port; 3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (i = 0; i < MAX_RFC_PORTS; i++) 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port = &rfc_cb.port.port[i]; 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->in_use && (p_port->rfc.p_mcb == NULL)) 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->dlci == dlci) 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ((dlci & 0x01) && (p_port->dlci == (dlci - 1))) 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->dlci++; 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_port 3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Find port with DLCI, BD_ADDR 3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttPORT *port_find_port (UINT8 dlci, BD_ADDR bd_addr) 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 i; 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT *p_port; 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (i = 0; i < MAX_RFC_PORTS; i++) 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port = &rfc_cb.port.port[i]; 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->in_use 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->dlci == dlci) 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !memcmp (p_port->bd_addr, bd_addr, BD_ADDR_LEN)) 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_flow_control_user 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Check the current user flow control and if necessary return 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** events to be send to the user based on the user's specified 3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** flow control type. 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns event mask to be returned to the application 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT32 port_flow_control_user (tPORT *p_port) 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 event = 0; 4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Flow control to the user can be caused by flow controlling by the peer */ 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* (FlowInd, or flow control by the peer RFCOMM (Fcon) or internally if */ 4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* tx_queue is full */ 4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN fc = p_port->tx.peer_fc 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || !p_port->rfc.p_mcb 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || !p_port->rfc.p_mcb->peer_ready 4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_port->tx.queue_size > PORT_TX_HIGH_WM) 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM); 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->tx.user_fc == fc) 4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (0); 4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->tx.user_fc = fc; 4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (fc) 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project event = PORT_EV_FC; 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project event = PORT_EV_FC | PORT_EV_FCS; 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (event); 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_get_signal_changes 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Check modem signals that has been changed 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns event mask to be returned to the application 4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT32 port_get_signal_changes (tPORT *p_port, UINT8 old_signals, UINT8 signal) 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 changed_signals = (signal ^ old_signals); 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 events = 0; 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_DTRDSR_ON) 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_DSR; 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (signal & PORT_DTRDSR_ON) 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_DSRS; 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_CTSRTS_ON) 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_CTS; 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (signal & PORT_CTSRTS_ON) 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_CTSS; 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_RING_ON) 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_RING; 4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_DCD_ON) 4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_RLSD; 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (signal & PORT_DCD_ON) 4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_RLSDS; 4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port->ev_mask & events); 4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_flow_control_peer 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Send flow control messages to the peer for both enabling 4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** and disabling flow control, for both credit-based and 4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** TS 07.10 flow control mechanisms. 4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns nothing 4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_flow_control_peer(tPORT *p_port, BOOLEAN enable, UINT16 count) 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_port->rfc.p_mcb) 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If using credit based flow control */ 4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) 4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if want to enable flow from peer */ 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (enable) 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* update rx credits */ 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (count > p_port->credit_rx) 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx = 0; 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx -= count; 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If credit count is less than low credit watermark, and user */ 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* did not force flow control, send a credit update */ 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* There might be a special case when we just adjusted rx_max */ 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_port->credit_rx <= p_port->credit_rx_low) 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !p_port->rx.user_fc 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->credit_rx_max > p_port->credit_rx)) 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rfc_send_credit(p_port->rfc.p_mcb, p_port->dlci, 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (UINT8) (p_port->credit_rx_max - p_port->credit_rx)); 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx = p_port->credit_rx_max; 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = FALSE; 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* else want to disable flow from peer */ 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if client registered data callback, just do what they want */ 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->p_data_callback || p_port->p_data_co_callback) 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if queue count reached credit rx max, set peer fc */ 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_port->rx.queue.count >= p_port->credit_rx_max) 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* else using TS 07.10 flow control */ 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if want to enable flow from peer */ 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (enable) 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If rfcomm suspended traffic from the peer based on the rx_queue_size */ 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* check if it can be resumed now */ 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rx.peer_fc 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->rx.queue_size < PORT_RX_LOW_WM) 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->rx.queue.count < PORT_RX_BUF_LOW_WM)) 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = FALSE; 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If user did not force flow control allow traffic now */ 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_port->rx.user_fc) 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_FlowReq (p_port->rfc.p_mcb, p_port->dlci, TRUE); 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* else want to disable flow from peer */ 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if client registered data callback, just do what they want */ 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->p_data_callback || p_port->p_data_co_callback) 5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_FlowReq (p_port->rfc.p_mcb, p_port->dlci, FALSE); 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check the size of the rx queue. If it exceeds certain */ 5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* level and flow control has not been sent to the peer do it now */ 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ( ((p_port->rx.queue_size > PORT_RX_HIGH_WM) 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_port->rx.queue.count > PORT_RX_BUF_HIGH_WM)) 5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !p_port->rx.peer_fc) 5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_EVENT0 ("PORT_DataInd Data reached HW. Sending FC set."); 5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_FlowReq (p_port->rfc.p_mcb, p_port->dlci, FALSE); 5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 576