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; 889ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie RFCOMM_TRACE_DEBUG3("rfc_cb.port.port[%d]:%p allocated, last_port:%d", yy, p_port, rfc_cb.rfc.last_port); 899ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie RFCOMM_TRACE_DEBUG6("port_allocate_port:bd_addr:%02x:%02x:%02x:%02x:%02x:%02x", 909ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If here, no free PORT found */ 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_set_defaults 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Set defualt port parameters 1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_set_defaults (tPORT *p_port) 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->ev_mask = 0; 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->p_callback = NULL; 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->port_ctrl = 0; 1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->error = 0; 1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->line_status = 0; 1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx_flag_ev_pending = FALSE; 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->peer_mtu = RFCOMM_DEFAULT_MTU; 1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->user_port_pars = default_port_pars; 1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->peer_port_pars = default_port_pars; 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_tx = 0; 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx = 0; 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* p_port->credit_rx_max = PORT_CREDIT_RX_MAX; Determined later */ 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* p_port->credit_rx_low = PORT_CREDIT_RX_LOW; Determined later */ 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->local_ctrl, 0, sizeof (p_port->local_ctrl)); 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->peer_ctrl, 0, sizeof (p_port->peer_ctrl)); 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->rx, 0, sizeof (p_port->rx)); 1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (&p_port->tx, 0, sizeof (p_port->tx)); 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_select_mtu 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Select MTU which will best serve connection from our 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** point of view. 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** If our device is 1.2 or lower we calculate how many DH5s 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** fit into 1 RFCOMM buffer. 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_select_mtu (tPORT *p_port) 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 packet_size; 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Will select MTU only if application did not setup something */ 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->mtu == 0) 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* find packet size which connection supports */ 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project packet_size = btm_get_max_packet_size (p_port->bd_addr); 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (packet_size == 0) 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* something is very wrong */ 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_WARNING0 ("port_select_mtu bad packet size"); 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = RFCOMM_DEFAULT_MTU; 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* We try to negotiate MTU that each packet can be split into whole 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project number of max packets. For example if link is 1.2 max packet size is 339 bytes. 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project At first calculate how many whole packets it is. MAX L2CAP is 1691 + 4 overhead. 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1695, that will be 5 Dh5 packets. Now maximum RFCOMM packet is 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5 * 339 = 1695. Minus 4 bytes L2CAP header 1691. Minus RFCOMM 6 bytes header overhead 1685 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project For EDR 2.0 packet size is 1027. So we better send RFCOMM packet as 1 3DH5 packet 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1 * 1027 = 1027. Minus 4 bytes L2CAP header 1023. Minus RFCOMM 6 bytes header overhead 1017 */ 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) >= packet_size) 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) / packet_size * packet_size) - RFCOMM_DATA_OVERHEAD - L2CAP_PKT_OVERHEAD; 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_select_mtu selected %d based on connection speed", p_port->mtu); 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD; 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_select_mtu selected %d based on l2cap PDU size", p_port->mtu); 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_select_mtu application selected %d", p_port->mtu); 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_max = (PORT_RX_HIGH_WM / p_port->mtu); 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->credit_rx_max > PORT_RX_BUF_HIGH_WM ) 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_max = PORT_RX_BUF_HIGH_WM; 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_low = (PORT_RX_LOW_WM / p_port->mtu); 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->credit_rx_low > PORT_RX_BUF_LOW_WM ) 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_low = PORT_RX_BUF_LOW_WM; 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx_buf_critical = (PORT_RX_CRITICAL_WM / p_port->mtu); 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->rx_buf_critical > PORT_RX_BUF_CRITICAL_WM ) 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx_buf_critical = PORT_RX_BUF_CRITICAL_WM; 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG3 ("port_select_mtu credit_rx_max %d, credit_rx_low %d, rx_buf_critical %d", 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx_max, p_port->credit_rx_low, p_port->rx_buf_critical); 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** 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_release_port 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Release port infor control block. 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_release_port (tPORT *p_port) 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HDR *p_buf; 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 mask; 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT_CALLBACK *p_port_cb; 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT_STATE user_port_pars; 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_SCHEDULE_LOCK; 215689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project RFCOMM_TRACE_DEBUG1("port_release_port, p_port:%p", p_port); 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue)) != NULL) 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.queue_size = 0; 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->tx.queue)) != NULL) 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project GKI_freebuf (p_buf); 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->tx.queue_size = 0; 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project PORT_SCHEDULE_UNLOCK; 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->state = PORT_STATE_CLOSED; 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rfc.state == RFC_STATE_CLOSED) 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG0 ("rfc_port_closed DONE"); 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rfc.p_mcb) 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rfc.p_mcb->port_inx[p_port->dlci] = 0; 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If there are no more ports opened on this MCB release it */ 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rfc_check_mcb_active (p_port->rfc.p_mcb); 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rfc_port_timer_stop (p_port); 2419ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie RFCOMM_TRACE_DEBUG1 ("port_release_port:p_port->keep_port_handle:%d", p_port->keep_port_handle); 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_port->keep_port_handle ) 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_release_port:Initialize handle:%d", p_port->inx); 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* save event mask and callback */ 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project mask = p_port->ev_mask; 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port_cb = p_port->p_callback; 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project user_port_pars = p_port->user_port_pars; 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project port_set_defaults(p_port); 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* restore */ 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->ev_mask = mask; 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->p_callback = p_port_cb; 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->user_port_pars = user_port_pars; 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->mtu = p_port->keep_mtu; 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->state = PORT_STATE_OPENING; 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rfc.p_mcb = NULL; 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(p_port->is_server) 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->dlci &= 0xfe; 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->local_ctrl.modem_signal = p_port->default_signal_state; 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy (p_port->bd_addr, BT_BD_ANY, BD_ADDR_LEN); 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_DEBUG1 ("port_release_port:Clean-up handle:%d", p_port->inx); 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset (p_port, 0, sizeof (tPORT)); 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/******************************************************************************* 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_mcb 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function checks if connection exists to device with 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** the BD_ADDR. 2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttRFC_MCB *port_find_mcb (BD_ADDR bd_addr) 2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (i = 0; i < MAX_BD_CONNECTIONS; i++) 2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((rfc_cb.port.rfc_mcb[i].state != RFC_MX_STATE_IDLE) 2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !memcmp (rfc_cb.port.rfc_mcb[i].bd_addr, bd_addr, BD_ADDR_LEN)) 2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Multiplexer channel found do not change anything */ 2929ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie RFCOMM_TRACE_DEBUG6("port_find_mcb: found bd_addr:%02x:%02x:%02x:%02x:%02x:%02x", 2939ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); 2949ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie RFCOMM_TRACE_DEBUG3("port_find_mcb: rfc_cb.port.rfc_mcb:index:%d, %p, lcid:%d", 2959ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie i, &rfc_cb.port.rfc_mcb[i], rfc_cb.port.rfc_mcb[i].lcid); 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (&rfc_cb.port.rfc_mcb[i]); 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2999ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie RFCOMM_TRACE_DEBUG6("port_find_mcb: not found, bd_addr:%02x:%02x:%02x:%02x:%02x:%02x", 3009ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); 3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_mcb_dlci_port 3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Find port on the multiplexer channel based on DLCI. If 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** this port with DLCI not found try to use even DLCI. This 3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** is for the case when client is establishing connection on 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** none-initiator MCB. 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttPORT *port_find_mcb_dlci_port (tRFC_MCB *p_mcb, UINT8 dlci) 3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 inx; 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_mcb) 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (dlci > RFCOMM_MAX_DLCI) 3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project inx = p_mcb->port_inx[dlci]; 3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (inx == 0) 3299ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie { 3309ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie RFCOMM_TRACE_DEBUG2("port_find_mcb_dlci_port: p_mcb:%p, port_inx[dlci:%d] is 0", p_mcb, dlci); 3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3329ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie } 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (&rfc_cb.port.port[inx - 1]); 3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_dlci_port 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Find port with DLCI not assigned to multiplexer channel 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttPORT *port_find_dlci_port (UINT8 dlci) 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 i; 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT *p_port; 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (i = 0; i < MAX_RFC_PORTS; i++) 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port = &rfc_cb.port.port[i]; 3559ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->in_use && (p_port->rfc.p_mcb == NULL)) 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->dlci == dlci) 3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ((dlci & 0x01) && (p_port->dlci == (dlci - 1))) 3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->dlci++; 3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_find_port 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Find port with DLCI, BD_ADDR 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Pointer to the PORT or NULL if not found 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttPORT *port_find_port (UINT8 dlci, BD_ADDR bd_addr) 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16 i; 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tPORT *p_port; 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for (i = 0; i < MAX_RFC_PORTS; i++) 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port = &rfc_cb.port.port[i]; 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->in_use 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->dlci == dlci) 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !memcmp (p_port->bd_addr, bd_addr, BD_ADDR_LEN)) 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port); 3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (NULL); 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_flow_control_user 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Check the current user flow control and if necessary return 4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** events to be send to the user based on the user's specified 4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** flow control type. 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns event mask to be returned to the application 4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT32 port_flow_control_user (tPORT *p_port) 4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 event = 0; 4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Flow control to the user can be caused by flow controlling by the peer */ 4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* (FlowInd, or flow control by the peer RFCOMM (Fcon) or internally if */ 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* tx_queue is full */ 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BOOLEAN fc = p_port->tx.peer_fc 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || !p_port->rfc.p_mcb 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || !p_port->rfc.p_mcb->peer_ready 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_port->tx.queue_size > PORT_TX_HIGH_WM) 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM); 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->tx.user_fc == fc) 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (0); 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->tx.user_fc = fc; 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (fc) 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project event = PORT_EV_FC; 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project event = PORT_EV_FC | PORT_EV_FCS; 4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (event); 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_get_signal_changes 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Check modem signals that has been changed 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns event mask to be returned to the application 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT32 port_get_signal_changes (tPORT *p_port, UINT8 old_signals, UINT8 signal) 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT8 changed_signals = (signal ^ old_signals); 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT32 events = 0; 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_DTRDSR_ON) 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_DSR; 4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (signal & PORT_DTRDSR_ON) 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_DSRS; 4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_CTSRTS_ON) 4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_CTS; 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (signal & PORT_CTSRTS_ON) 4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_CTSS; 4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_RING_ON) 4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_RING; 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (changed_signals & PORT_DCD_ON) 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_RLSD; 4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (signal & PORT_DCD_ON) 4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project events |= PORT_EV_RLSDS; 4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_port->ev_mask & events); 4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function port_flow_control_peer 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Send flow control messages to the peer for both enabling 4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** and disabling flow control, for both credit-based and 4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** TS 07.10 flow control mechanisms. 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns nothing 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid port_flow_control_peer(tPORT *p_port, BOOLEAN enable, UINT16 count) 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_port->rfc.p_mcb) 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If using credit based flow control */ 5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if want to enable flow from peer */ 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (enable) 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* update rx credits */ 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (count > p_port->credit_rx) 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx = 0; 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx -= count; 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If credit count is less than low credit watermark, and user */ 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* did not force flow control, send a credit update */ 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* There might be a special case when we just adjusted rx_max */ 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_port->credit_rx <= p_port->credit_rx_low) 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !p_port->rx.user_fc 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->credit_rx_max > p_port->credit_rx)) 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project rfc_send_credit(p_port->rfc.p_mcb, p_port->dlci, 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (UINT8) (p_port->credit_rx_max - p_port->credit_rx)); 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->credit_rx = p_port->credit_rx_max; 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = FALSE; 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* else want to disable flow from peer */ 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if client registered data callback, just do what they want */ 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->p_data_callback || p_port->p_data_co_callback) 5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if queue count reached credit rx max, set peer fc */ 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (p_port->rx.queue.count >= p_port->credit_rx_max) 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* else using TS 07.10 flow control */ 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if want to enable flow from peer */ 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (enable) 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If rfcomm suspended traffic from the peer based on the rx_queue_size */ 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* check if it can be resumed now */ 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->rx.peer_fc 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->rx.queue_size < PORT_RX_LOW_WM) 5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && (p_port->rx.queue.count < PORT_RX_BUF_LOW_WM)) 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = FALSE; 5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If user did not force flow control allow traffic now */ 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!p_port->rx.user_fc) 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_FlowReq (p_port->rfc.p_mcb, p_port->dlci, TRUE); 5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* else want to disable flow from peer */ 5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if client registered data callback, just do what they want */ 5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_port->p_data_callback || p_port->p_data_co_callback) 5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_FlowReq (p_port->rfc.p_mcb, p_port->dlci, FALSE); 5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check the size of the rx queue. If it exceeds certain */ 5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* level and flow control has not been sent to the peer do it now */ 5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if ( ((p_port->rx.queue_size > PORT_RX_HIGH_WM) 5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project || (p_port->rx.queue.count > PORT_RX_BUF_HIGH_WM)) 5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project && !p_port->rx.peer_fc) 5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_TRACE_EVENT0 ("PORT_DataInd Data reached HW. Sending FC set."); 5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_port->rx.peer_fc = TRUE; 5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project RFCOMM_FlowReq (p_port->rfc.p_mcb, p_port->dlci, FALSE); 5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 588