16ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/****************************************************************************** 26ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 36ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Copyright (C) 1999-2012 Broadcom Corporation 46ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 56ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Licensed under the Apache License, Version 2.0 (the "License"); 66ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * you may not use this file except in compliance with the License. 76ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * You may obtain a copy of the License at: 86ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 96ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * http://www.apache.org/licenses/LICENSE-2.0 106ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 116ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Unless required by applicable law or agreed to in writing, software 126ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * distributed under the License is distributed on an "AS IS" BASIS, 136ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 146ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * See the License for the specific language governing permissions and 156ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * limitations under the License. 166ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 176ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/ 186ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach 196ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/****************************************************************************** 206ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 216ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * this file contains the Serial Port API code 226ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * 236ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/ 24e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 25e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include <string.h> 26e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "bt_target.h" 27e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "gki.h" 28e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "rfcdefs.h" 29e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "port_api.h" 30e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "port_int.h" 31e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "btm_int.h" 32e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "btm_api.h" 33e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "rfc_int.h" 34e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "l2c_api.h" 35e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "sdp_api.h" 36e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 37e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/* duration of break in 200ms units */ 38e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#define PORT_BREAK_DURATION 1 39e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 4066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <cutils/log.h> 41595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define info(fmt, ...) ALOGI ("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) 42595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define debug(fmt, ...) ALOGD ("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) 43595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define error(fmt, ...) ALOGE ("## ERROR : %s: " fmt "##",__FUNCTION__, ## __VA_ARGS__) 44595bced8e7c280e37a75b9bf9c1f36263434041cMatthew Xie#define asrt(s) if(!(s)) ALOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__) 4566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 46e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 47e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 48e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function RFCOMM_CreateConnection 49e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 5066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description RFCOMM_CreateConnection function is used from the application 5166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** to establish serial port connection to the peer device, 5266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** or allow RFCOMM to accept a connection from the peer 5366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** application. 54e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 5566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: scn - Service Channel Number as registered with 5666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** the SDP (server) or obtained using SDP from 57e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** the peer device (client). 58e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** is_server - TRUE if requesting application is a server 59e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** mtu - Maximum frame size the application can accept 60e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** bd_addr - BD_ADDR of the peer (client) 6166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** mask - specifies events to be enabled. A value 62e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** of zero disables all events. 63e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_handle - OUT pointer to the handle. 64e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_mgmt_cb - pointer to callback function to receive 65e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** connection up/down events. 66e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Notes: 67e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 68e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Server can call this function with the same scn parameter multiple times if 69e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** it is ready to accept multiple simulteneous connections. 70e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 71e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** DLCI for the connection is (scn * 2 + 1) if client originates connection on 72e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** existing none initiator multiplexer channel. Otherwise it is (scn * 2). 73e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** For the server DLCI can be changed later if client will be calling it using 74e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** (scn * 2 + 1) dlci. 75e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 76e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 7766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryaniint RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server, 7866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle, 79e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT_CALLBACK *p_mgmt_cb) 80e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 81e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 82e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach int i; 83e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 dlci; 84e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tRFC_MCB *p_mcb = port_find_mcb (bd_addr); 85e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 rfcomm_mtu; 86e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 8766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_API3 ("RFCOMM_CreateConnection() called SCN: %d is_server:%d mtu:%d", 88e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach scn, is_server, mtu); 89e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API6 ("RFCOMM_CreateConnection() BDA: %02x-%02x-%02x-%02x-%02x-%02x", 90e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); 91e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 92e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_handle = 0; 93e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 94e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (( scn == 0 )||(scn >= PORT_MAX_RFC_PORTS )) 95e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 96e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Server Channel Number(SCN) should be in range 1...30 */ 97e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_ERROR0 ("RFCOMM_CreateConnection - invalid SCN"); 98e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_INVALID_SCN); 99e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 100e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 101e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* For client that originate connection on the existing none initiator */ 102e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* multiplexer channel DLCI should be odd */ 103e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_mcb && !p_mcb->is_initiator && !is_server) 104e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach dlci = (scn << 1) + 1; 105e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 106e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach dlci = (scn << 1); 107e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 108e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* For the server side always allocate a new port. On the client side */ 109e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* do not allow the same (dlci, bd_addr) to be opened twice by application */ 110e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!is_server && ((p_port = port_find_port (dlci, bd_addr)) != NULL)) 111e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 112e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* if existing port is also a client port */ 113e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->is_server == FALSE) 114e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 11566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_ERROR3 ("RFCOMM_CreateConnection - already opened state:%d, RFC state:%d, MCB state:%d", 116e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->state, p_port->rfc.state, p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0); 117e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_ALREADY_OPENED); 118e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 119e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 120e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 121e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_port = port_allocate_port (dlci, bd_addr)) == NULL) 122e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 123e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_WARNING0 ("RFCOMM_CreateConnection - no resources"); 124e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NO_RESOURCES); 125e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 126e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 127e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->default_signal_state = (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON); 128e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 129e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach switch (uuid) 130e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 131e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case UUID_PROTOCOL_OBEX: 132e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE; 133e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 134e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case UUID_SERVCLASS_SERIAL_PORT: 135e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE; 136e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 137e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case UUID_SERVCLASS_LAN_ACCESS_USING_PPP: 138e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE; 139e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 140e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case UUID_SERVCLASS_DIALUP_NETWORKING: 141e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case UUID_SERVCLASS_FAX: 142e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE; 143e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 144e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 145e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 146e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT2 ("RFCOMM_CreateConnection dlci:%d signal state:0x%x", dlci, p_port->default_signal_state); 147e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 148e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_handle = p_port->inx; 149e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 150e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->state = PORT_STATE_OPENING; 151e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->uuid = uuid; 152e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->is_server = is_server; 153e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->scn = scn; 154e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->ev_mask = 0; 155e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 156e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If the MTU is not specified (0), keep MTU decision until the 157e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach * PN frame has to be send 158e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach * at that time connection should be established and we 159e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach * will know for sure our prefered MTU 160e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach */ 161e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 162e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD; 163e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 164e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (mtu) 165e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->mtu = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu; 166e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 167e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->mtu = rfcomm_mtu; 168e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 169e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* server doesn't need to release port when closing */ 170e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if( is_server ) 171e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 172e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->keep_port_handle = TRUE; 173e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 174e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* keep mtu that user asked, p_port->mtu could be updated during param negotiation */ 17566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_port->keep_mtu = p_port->mtu; 176e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 177e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 178e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal = p_port->default_signal_state; 179e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.fc = FALSE; 180e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 181e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->p_mgmt_callback = p_mgmt_cb; 182e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 183e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (i = 0; i < BD_ADDR_LEN; i++) 184e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->bd_addr[i] = bd_addr[i]; 185e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 186e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If this is not initiator of the connection need to just wait */ 187e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->is_server) 188e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 189e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 190e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 191e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 192e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Open will be continued after security checks are passed */ 193e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return port_open_continue (p_port); 194e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 195e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 196e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 197e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 198e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 199e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function RFCOMM_RemoveConnection 200e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 201e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is called to close the specified connection. 202e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 20366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 204e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 205e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 206e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint RFCOMM_RemoveConnection (UINT16 handle) 207e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 208e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 209e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 210e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("RFCOMM_RemoveConnection() handle:%d", handle); 211e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 212e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 213e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 214e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 215e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_ERROR1 ("RFCOMM_RemoveConnection() BAD handle:%d", handle); 216e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 217e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 218e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 219e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 220e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 221e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 222e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT1 ("RFCOMM_RemoveConnection() Not opened:%d", handle); 223e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 224e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 225e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 226e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->state = PORT_STATE_CLOSING; 227e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 228e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_start_close (p_port); 229e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 230e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 231e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 232e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 233e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 234e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 235e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function RFCOMM_RemoveServer 236e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 237e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is called to close the server port. 238e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 23966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 240e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 241e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 242e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint RFCOMM_RemoveServer (UINT16 handle) 243e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 244e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 245e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 246e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("RFCOMM_RemoveServer() handle:%d", handle); 247e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 248e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 249e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 250e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 251e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_ERROR1 ("RFCOMM_RemoveServer() BAD handle:%d", handle); 252e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 253e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 254e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 255e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 256e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Do not report any events to the client any more. */ 257e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->p_mgmt_callback = NULL; 25866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 259e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 260e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 261e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT1 ("RFCOMM_RemoveServer() Not opened:%d", handle); 262e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 263e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 264e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 265e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* this port will be deallocated after closing */ 266e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->keep_port_handle = FALSE; 267e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->state = PORT_STATE_CLOSING; 268e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 269e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_start_close (p_port); 270e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 271e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 272e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 273e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 274e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 275e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 276e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_SetEventCallback 277e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 27866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function is called to provide an address of the 279e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** function which will be called when one of the events 280e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** specified in the mask occures. 281e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 28266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 28366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_callback - address of the callback function which should 28466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** be called from the RFCOMM when an event 285e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** specified in the mask occures. 286e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 287e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 288e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 289e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_SetEventCallback (UINT16 port_handle, tPORT_CALLBACK *p_port_cb) 290e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 291e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 292e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 293e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 294e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) 295e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 296e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 297e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 298e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 299e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[port_handle - 1]; 300e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 301e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 302e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 303e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 304e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 305e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 306e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_SetEventCallback() handle:%d", port_handle); 307e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 308e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->p_callback = p_port_cb; 309e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 310e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 311e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 312e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 313e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 314e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 315e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 316e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_SetDataCallback 317e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 318e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is when a data packet is received 319e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 32066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 32166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_callback - address of the callback function which should 32266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** be called from the RFCOMM when data packet 323e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** is received. 324e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 325e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 326e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 327e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_SetDataCallback (UINT16 port_handle, tPORT_DATA_CALLBACK *p_port_cb) 328e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 329e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 330e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 331e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle, p_port_cb); 332e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 333e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 334e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) 335e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 336e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 337e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 338e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 339e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[port_handle - 1]; 340e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 341e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 342e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 343e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 344e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 345e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 346e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->p_data_callback = p_port_cb; 347e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 348e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 349e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 35066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani/******************************************************************************* 35166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 35266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Function PORT_SetCODataCallback 35366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 35466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function is when a data packet is received 35566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 35666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 35766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_callback - address of the callback function which should 35866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** be called from the RFCOMM when data packet 35966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** is received. 36066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 36166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 36266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani*******************************************************************************/ 36366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryaniint PORT_SetDataCOCallback (UINT16 port_handle, tPORT_DATA_CO_CALLBACK *p_port_cb) 36466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 36566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani tPORT *p_port; 36666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 36766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_API2 ("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle, p_port_cb); 36866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 36966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* Check if handle is valid to avoid crashing */ 37066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) 37166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 37266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_BAD_HANDLE); 37366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 37466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 37566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_port = &rfc_cb.port.port[port_handle - 1]; 37666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 37766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 37866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 37966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_NOT_OPENED); 38066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 38166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 38266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_port->p_data_co_callback = p_port_cb; 38366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 38466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_SUCCESS); 38566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 38666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 387e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 388e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 389e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 390e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 391e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_SetEventMask 392e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 393e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is called to close the specified connection. 394e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 39566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 396e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** mask - Bitmask of the events the host is interested in 397e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 398e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 399e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_SetEventMask (UINT16 port_handle, UINT32 mask) 400e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 401e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 402e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 403e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_SetEventMask() handle:%d mask:0x%x", port_handle, mask); 404e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 405e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 406e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) 407e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 408e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 409e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 410e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 411e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[port_handle - 1]; 412e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 413e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 414e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 415e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 416e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 417e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 418e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->ev_mask = mask; 419e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 420e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 421e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 422e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 423e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 424e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 425e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 426e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_CheckConnection 427e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 428e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function returns PORT_SUCCESS if connection referenced 429e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** by handle is up and running 430e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 43166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 432e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** bd_addr - OUT bd_addr of the peer 433e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_lcid - OUT L2CAP's LCID 434e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 435e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 436e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid) 437e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 438e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 439e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 440e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_CheckConnection() handle:%d", handle); 441e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 442e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 443e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 444e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 445e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 446e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 447e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 448e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 449e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 450e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 451e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 452e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 453e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 454e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 45566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (!p_port->rfc.p_mcb 45666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani || !p_port->rfc.p_mcb->peer_ready 457e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach || (p_port->rfc.state != RFC_STATE_OPENED)) 458e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 459e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_LINE_ERR); 460e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 461e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 462e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy (bd_addr, p_port->rfc.p_mcb->bd_addr, BD_ADDR_LEN); 463e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_lcid) 464e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_lcid = p_port->rfc.p_mcb->lcid; 465e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 466e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 467e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 468e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 469e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 470e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 471e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_IsOpening 472e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 473e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function returns TRUE if there is any RFCOMM connection 474e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** opening in process. 475e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 476e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Parameters: TRUE if any connection opening is found 477e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** bd_addr - bd_addr of the peer 478e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 479e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 480e448862a47c08eb23185aaed574b39264f5005fcAndre EisenbachBOOLEAN PORT_IsOpening (BD_ADDR bd_addr) 481e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 482e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 xx, yy; 483e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tRFC_MCB *p_mcb = NULL; 484e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 485e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BOOLEAN found_port; 486e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 487e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check for any rfc_mcb which is in the middle of opening. */ 488e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (xx = 0; xx < MAX_BD_CONNECTIONS; xx++) 489e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 490e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((rfc_cb.port.rfc_mcb[xx].state > RFC_MX_STATE_IDLE) && 491e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (rfc_cb.port.rfc_mcb[xx].state < RFC_MX_STATE_CONNECTED)) 492e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 493e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN); 494e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return TRUE; 495e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 496e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 497e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (rfc_cb.port.rfc_mcb[xx].state == RFC_MX_STATE_CONNECTED) 498e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 499e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach found_port = FALSE; 500e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_mcb = &rfc_cb.port.rfc_mcb[xx]; 501e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[0]; 502e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 503e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach for (yy = 0; yy < MAX_RFC_PORTS; yy++, p_port++) 504e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 505e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->rfc.p_mcb == p_mcb) 506e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 507e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach found_port = TRUE; 508e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 509e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 510e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 511e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 51266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if ((!found_port) || 513e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) 514e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 515e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Port is not established yet. */ 516e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN); 517e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return TRUE; 518e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 519e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 520e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 521e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 522e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return FALSE; 523e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 524e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 525e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 526e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 527e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_SetState 528e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 52966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function configures connection according to the 530e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** specifications in the tPORT_STATE structure. 531e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 53266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 53366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_settings - Pointer to a tPORT_STATE structure containing 534e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** configuration information for the connection. 535e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 536e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 537e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 538e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_SetState (UINT16 handle, tPORT_STATE *p_settings) 539e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 540e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 541e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 baud_rate; 542e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 543e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_SetState() handle:%d", handle); 544e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 545e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 546e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 547e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 548e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 549e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 550e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 551e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 552e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 553e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 554e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 555e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 556e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 557e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 558e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->line_status) 559e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 560e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_LINE_ERR); 561e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 562e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 563e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_SetState() handle:%d FC_TYPE:0x%x", handle, 564e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_settings->fc_type); 565e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 566e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach baud_rate = p_port->user_port_pars.baud_rate; 567e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->user_port_pars = *p_settings; 568e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 569e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* for now we've been asked to pass only baud rate */ 570e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (baud_rate != p_settings->baud_rate) 571e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 572e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_start_par_neg (p_port); 573e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 574e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 575e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 576e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 577e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 578e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 579e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_GetRxQueueCnt 580e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 581e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function return number of buffers on the rx queue. 582e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 58366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 584e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_rx_queue_count - Pointer to return queue count in. 585e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 586e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 587e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_GetRxQueueCnt (UINT16 handle, UINT16 *p_rx_queue_count) 588e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 589e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 590e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 591e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_GetRxQueueCnt() handle:%d", handle); 592e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 593e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 594e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 595e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 596e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 597e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 598e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 599e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 600e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 601e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 602e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 603e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 604e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 605e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 606e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->line_status) 607e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 608e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_LINE_ERR); 609e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 610e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 611e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_rx_queue_count = p_port->rx.queue_size; 612e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 613e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_GetRxQueueCnt() p_rx_queue_count:%d, p_port->rx.queue.count = %d", 614e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_rx_queue_count, p_port->rx.queue_size); 615e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 616e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 617e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 618e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 619e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 620e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 621e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_GetState 622e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 623e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is called to fill tPORT_STATE structure 624e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** with the curremt control settings for the port 625e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 62666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 627e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_settings - Pointer to a tPORT_STATE structure in which 628e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** configuration information is returned. 629e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 630e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 631e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_GetState (UINT16 handle, tPORT_STATE *p_settings) 632e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 633e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 634e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 635e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_GetState() handle:%d", handle); 636e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 637e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 638e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 639e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 640e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 641e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 642e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 643e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 644e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 645e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 646e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 647e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 648e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 649e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 650e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->line_status) 651e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 652e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_LINE_ERR); 653e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 654e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 655e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_settings = p_port->user_port_pars; 656e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 657e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 658e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 659e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 660e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 661e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 662e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_Control 663e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 66466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function directs a specified connection to pass control 665e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** control information to the peer device. 666e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 66766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 668e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** signal = specify the function to be passed 669e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 670e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 671e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_Control (UINT16 handle, UINT8 signal) 672e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 673e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 674e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT8 old_modem_signal; 675e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 676e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_Control() handle:%d signal:0x%x", handle, signal); 677e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 678e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 679e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 680e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 681e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 682e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 683e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 684e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 685e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 686e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 687e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 688e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 689e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 690e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 691e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach old_modem_signal = p_port->local_ctrl.modem_signal; 692e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.break_signal = 0; 693e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 694e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach switch (signal) 695e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 696e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_SET_CTSRTS: 697e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal |= PORT_CTSRTS_ON; 698e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 699e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 700e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_CLR_CTSRTS: 701e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal &= ~PORT_CTSRTS_ON; 702e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 703e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 704e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_SET_DTRDSR: 705e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal |= PORT_DTRDSR_ON; 706e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 707e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 708e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_CLR_DTRDSR: 709e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal &= ~PORT_DTRDSR_ON; 710e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 711e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 712e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_SET_RI: 713e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal |= PORT_RING_ON; 714e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 715e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 716e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_CLR_RI: 717e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal &= ~PORT_RING_ON; 718e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 719e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 720e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_SET_DCD: 721e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal |= PORT_DCD_ON; 722e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 723e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 724e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_CLR_DCD: 725e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.modem_signal &= ~PORT_DCD_ON; 726e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 727e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 728e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 729e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (signal == PORT_BREAK) 730e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.break_signal = PORT_BREAK_DURATION; 731e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else if (p_port->local_ctrl.modem_signal == old_modem_signal) 732e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 733e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 734e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_start_control (p_port); 735e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 736e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT4 ("PORT_Control DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d", 737e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0), 738e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0), 739e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0), 740e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0)); 741e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 742e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 743e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 744e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 745e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 746e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 747e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 748e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_FlowControl 749e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 75066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function directs a specified connection to pass 75166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** flow control message to the peer device. Enable flag passed 752e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** shows if port can accept more data. 753e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 75466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 755e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** enable - enables data flow 756e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 757e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 758e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_FlowControl (UINT16 handle, BOOLEAN enable) 759e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 760e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 761e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BOOLEAN old_fc; 762e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 events; 763e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 764e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_FlowControl() handle:%d enable: %d", handle, enable); 765e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 766e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 767e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 768e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 769e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 770e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 771e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 772e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 773e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 774e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 775e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 776e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 777e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 778e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 779e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->rfc.p_mcb) 780e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 781e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 782e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 783e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 784e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->rx.user_fc = !enable; 785e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 786e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) 787e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 788e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->rx.user_fc) 789e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 790e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_flow_control_peer(p_port, TRUE, 0); 791e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 792e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 793e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 794e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 795e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach old_fc = p_port->local_ctrl.fc; 796e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 797e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* FC is set if user is set or peer is set */ 798e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc); 799e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 800e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->local_ctrl.fc != old_fc) 801e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_start_control (p_port); 802e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 803e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 804e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Need to take care of the case when we could not deliver events */ 805e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* to the application because we were flow controlled */ 806e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (enable && (p_port->rx.queue_size != 0)) 807e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 808e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach events = PORT_EV_RXCHAR; 809e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->rx_flag_ev_pending) 810e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 811e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->rx_flag_ev_pending = FALSE; 812e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach events |= PORT_EV_RXFLAG; 813e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 814e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 815e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach events &= p_port->ev_mask; 816e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->p_callback && events) 817e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 818e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->p_callback (events, p_port->inx); 819e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 820e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 821e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 822e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 823e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 824e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 825e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 826e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 827e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_GetModemStatus 828e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 82966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function retrieves modem control signals. Normally 83066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** application will call this function after a callback 83166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** function is called with notification that one of signals 832e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** has been changed. 833e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 83466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 835e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_signal - specify the pointer to control signals info 836e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 837e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 838e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_GetModemStatus (UINT16 handle, UINT8 *p_signal) 839e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 840e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 841e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 842e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 843e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 844e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 845e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 846e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 847e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 848e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 849e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 850e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 851e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 852e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 853e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 854e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_signal = p_port->peer_ctrl.modem_signal; 855e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 856e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_GetModemStatus() handle:%d signal:%x", handle, *p_signal); 85766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 858e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 859e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 860e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 861e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 862e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 863e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 864e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_ClearError 865e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 866e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function retreives information about a communications 86766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** error and reports current status of a connection. The 868e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** function should be called when an error occures to clear 869e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** the connection error flag and to enable additional read 870e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** and write operations. 871e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 87266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 873e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_errors - pointer of the variable to receive error codes 87466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_status - pointer to the tPORT_STATUS structur to receive 875e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** connection status 876e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 877e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 878e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_ClearError (UINT16 handle, UINT16 *p_errors, tPORT_STATUS *p_status) 879e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 880e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 881e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 882e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_ClearError() handle:%d", handle); 883e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 884e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 885e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 886e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 887e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 888e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 889e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 890e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 891e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 892e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 893e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 894e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 895e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 896e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_errors = p_port->line_status; 897e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 898e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* This is the only call to clear error status. We can not clear */ 899e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* connection failed status. To clean it port should be closed and reopened */ 900e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->line_status = (p_port->line_status & LINE_STATUS_FAILED); 901e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 902e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_GetQueueStatus (handle, p_status); 903e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 904e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 905e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 906e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 907e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 908e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 909e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_SendError 910e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 911e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function send a communications error to the peer device 912e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 91366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 914e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** errors - receive error codes 915e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 916e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 917e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_SendError (UINT16 handle, UINT8 errors) 918e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 919e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 920e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 921e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_SendError() handle:%d errors:0x%x", handle, errors); 922e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 923e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 924e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 925e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 926e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 927e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 928e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 929e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 930e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 931e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 932e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 933e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 934e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 935e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->rfc.p_mcb) 936e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 937e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 938e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 939e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 940e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_LineStatusReq (p_port->rfc.p_mcb, p_port->dlci, errors); 941e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 942e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 943e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 944e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 945e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 946e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 947e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_GetQueueStatus 948e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 94966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function reports current status of a connection. 950e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 95166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 95266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_status - pointer to the tPORT_STATUS structur to receive 953e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** connection status 954e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 955e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 956e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_GetQueueStatus (UINT16 handle, tPORT_STATUS *p_status) 957e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 958e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 959e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 960e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* RFCOMM_TRACE_API1 ("PORT_GetQueueStatus() handle:%d", handle); */ 961e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 962e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 963e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 964e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 965e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 966e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 967e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 968e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 969e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 970e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 971e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 972e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 973e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 974e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_status->in_queue_size = (UINT16) p_port->rx.queue_size; 975e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_status->out_queue_size = (UINT16) p_port->tx.queue_size; 976e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 977e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_status->mtu_size = (UINT16) p_port->peer_mtu; 978e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 979e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_status->flags = 0; 980e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 981e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!(p_port->peer_ctrl.modem_signal & PORT_CTSRTS_ON)) 982e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_status->flags |= PORT_FLAG_CTS_HOLD; 983e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 984e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!(p_port->peer_ctrl.modem_signal & PORT_DTRDSR_ON)) 985e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_status->flags |= PORT_FLAG_DSR_HOLD; 986e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 987e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!(p_port->peer_ctrl.modem_signal & PORT_DCD_ON)) 988e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_status->flags |= PORT_FLAG_RLSD_HOLD; 989e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 990e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 991e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 992e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 993e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 994e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 995e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 996e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_Purge 997e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 99866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function discards all the data from the output or 999e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** input queues of the specified connection. 1000e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 100166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 100266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** purge_flags - specify the action to take. 1003e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1004e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1005e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_Purge (UINT16 handle, UINT8 purge_flags) 1006e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1007e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 1008e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf; 1009e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 count; 101066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani UINT32 events; 1011e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1012e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_Purge() handle:%d flags:0x%x", handle, purge_flags); 1013e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1014e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 1015e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 1016e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1017e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 1018e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1019e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1020e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 1021e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1022e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 1023e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1024e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 1025e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1026e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1027e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (purge_flags & PORT_PURGE_RXCLEAR) 1028e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1029e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_LOCK; /* to prevent missing credit */ 1030e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1031e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach count = p_port->rx.queue.count; 1032e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1033e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue)) != NULL) 1034e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 1035e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1036e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->rx.queue_size = 0; 1037e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1038e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1039e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1040e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If we flowed controlled peer based on rx_queue size enable data again */ 1041e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (count) 1042e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_flow_control_peer (p_port, TRUE, count); 1043e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1044e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1045e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (purge_flags & PORT_PURGE_TXCLEAR) 1046e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1047e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_LOCK; /* to prevent tx.queue_size from being negative */ 1048e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1049e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->tx.queue)) != NULL) 1050e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 1051e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1052e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->tx.queue_size = 0; 105366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 1054e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1055e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1056e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach events = PORT_EV_TXEMPTY; 1057e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1058e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach events |= port_flow_control_user (p_port); 1059e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1060e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach events &= p_port->ev_mask; 1061e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1062e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_port->p_callback != NULL) && events) 1063e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (p_port->p_callback)(events, p_port->inx); 1064e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1065e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1066e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1067e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1068e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1069e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1070e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1071e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1072e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_ReadData 1073e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 107466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description Normally not GKI aware application will call this function 1075e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** after receiving PORT_EV_RXCHAR event. 1076e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 107766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 1078e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_data - Data area 1079e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** max_len - Byte count requested 1080e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_len - Byte count received 1081e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1082e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1083e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_ReadData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len) 1084e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1085e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 1086e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf; 1087e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 count; 1088e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1089e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API2 ("PORT_ReadData() handle:%d max_len:%d", handle, max_len); 1090e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1091e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Initialize this in case of an error */ 1092e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len = 0; 1093e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1094e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 1095e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 1096e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1097e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 1098e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1099e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1100e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 1101e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1102e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 1103e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1104e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 1105e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1106e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1107e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->line_status) 1108e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1109e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_LINE_ERR); 1110e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1111e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1112e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf = (BT_HDR *)GKI_getfirst (&p_port->rx.queue); 1113e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_buf) 1114e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1115e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1116e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach count = 0; 1117e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1118e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (max_len && p_buf) 1119e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1120e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_buf->len > max_len) 1121e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1122e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, max_len); 1123e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->offset += max_len; 1124e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->len -= max_len; 1125e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1126e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len += max_len; 1127e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1128e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_LOCK; 1129e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1130e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->rx.queue_size -= max_len; 1131e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1132e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1133e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1134e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1135e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1136e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1137e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1138e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len); 1139e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1140e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len += p_buf->len; 1141e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach max_len -= p_buf->len; 1142e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1143e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_LOCK; 1144e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1145e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->rx.queue_size -= p_buf->len; 1146e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1147e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (max_len) 1148e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1149e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_data += p_buf->len; 1150e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf = (BT_HDR *)GKI_getnext (p_buf); 1151e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1152e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1153e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (GKI_dequeue (&p_port->rx.queue)); 1154e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1155e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1156e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1157e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach count++; 1158e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1159e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1160e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1161e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (*p_len == 1) 1162e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1163e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT3 ("PORT_ReadData queue:%d returned:%d %x", p_port->rx.queue_size, *p_len, (p_data[0])); 1164e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1165e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1166e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1167e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT2 ("PORT_ReadData queue:%d returned:%d", p_port->rx.queue_size, *p_len); 1168e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1169e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1170e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If rfcomm suspended traffic from the peer based on the rx_queue_size */ 1171e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* check if it can be resumed now */ 1172e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_flow_control_peer (p_port, TRUE, count); 117366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 1174e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1175e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1176e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1177e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1178e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1179e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1180e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_Read 1181e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1182e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description Normally application will call this function after receiving 1183e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** PORT_EV_RXCHAR event. 1184e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 118566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 118666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** pp_buf - pointer to address of buffer with data, 1187e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1188e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1189e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_Read (UINT16 handle, BT_HDR **pp_buf) 1190e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1191e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 1192e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf; 1193e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1194e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_Read() handle:%d", handle); 1195e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1196e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 1197e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 1198e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1199e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 1200e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1201e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 1202e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1203e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 1204e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1205e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 1206e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1207e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1208e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->line_status) 1209e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1210e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_LINE_ERR); 1211e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1212e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1213e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_LOCK; 1214e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1215e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue); 1216e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_buf) 1217e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1218e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->rx.queue_size -= p_buf->len; 1219e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1220e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1221e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1222e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If rfcomm suspended traffic from the peer based on the rx_queue_size */ 1223e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* check if it can be resumed now */ 1224e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach port_flow_control_peer (p_port, TRUE, 1); 1225e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1226e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1227e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1228e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1229e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1230e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1231e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *pp_buf = p_buf; 1232e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1233e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1234e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1235e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1236e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1237e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1238e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function port_write 1239e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 124066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function when a data packet is received from the apper 124166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** layer task. 1242e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 124366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: p_port - pointer to address of port control block 124466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_buf - pointer to address of buffer with data, 1245e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1246e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1247e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachstatic int port_write (tPORT *p_port, BT_HDR *p_buf) 1248e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1249e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* We should not allow to write data in to server port when connection is not opened */ 125066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED)) 1251e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1252e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 1253e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_CLOSED); 1254e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1255e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1256e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Keep the data in pending queue if peer does not allow data, or */ 1257e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Peer is not ready or Port is not yet opened or initial port control */ 1258e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* command has not been sent */ 1259e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->tx.peer_fc 126066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani || !p_port->rfc.p_mcb 126166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani || !p_port->rfc.p_mcb->peer_ready 126266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani || (p_port->rfc.state != RFC_STATE_OPENED) 126366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani || ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) != 1264e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) 1265e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1266e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM) 1267e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach || (p_port->tx.queue.count > PORT_TX_BUF_CRITICAL_WM)) 1268e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 126966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_WARNING1 ("PORT_Write: Queue size: %d", 1270e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->tx.queue_size); 1271e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1272e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 1273e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1274e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR)) 1275e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->p_callback (PORT_EV_ERR, p_port->inx); 1276e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1277e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_TX_FULL); 1278e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1279e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 128066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_EVENT4 ("PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d ctrl_state %x", 128166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_port->tx.peer_fc, 1282e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready), 1283e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->rfc.state, 1284e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->port_ctrl); 1285e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1286e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_enqueue (&p_port->tx.queue, p_buf); 1287e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->tx.queue_size += p_buf->len; 1288e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1289e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_CMD_PENDING); 1290e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1291e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1292e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1293e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT0 ("PORT_Write : Data is being sent"); 1294e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1295e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_DataReq (p_port->rfc.p_mcb, p_port->dlci, p_buf); 1296e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1297e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1298e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1299e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1300e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1301e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1302e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_Write 1303e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 130466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description This function when a data packet is received from the apper 130566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** layer task. 1306e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 130766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 130866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** pp_buf - pointer to address of buffer with data, 1309e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1310e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1311e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_Write (UINT16 handle, BT_HDR *p_buf) 1312e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1313e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 1314e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 event = 0; 1315e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach int rc; 1316e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1317e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_Write() handle:%d", handle); 1318e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1319e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 1320e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 1321e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1322e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 1323e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 1324e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1325e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1326e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 1327e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1328e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 1329e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1330e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 1331e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 1332e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1333e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1334e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->line_status) 1335e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 133666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_WARNING1 ("PORT_Write: Data dropped line_status:0x%x", 1337e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->line_status); 1338e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach GKI_freebuf (p_buf); 1339e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_LINE_ERR); 1340e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1341e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1342e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rc = port_write (p_port, p_buf); 1343e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event |= port_flow_control_user (p_port); 134466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 1345e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach switch (rc) 1346e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1347e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_TX_FULL: 1348e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event |= PORT_EV_ERR; 1349e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1350e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1351e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach case PORT_SUCCESS: 1352e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event |= (PORT_EV_TXCHAR | PORT_EV_TXEMPTY); 1353e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1354e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1355e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Mask out all events that are not of interest to user */ 1356e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event &= p_port->ev_mask; 1357e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1358e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Send event to the application */ 1359e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->p_callback && event) 1360e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (p_port->p_callback)(event, p_port->inx); 1361e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1362e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1363e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 136466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani/******************************************************************************* 136566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 136666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Function PORT_WriteDataCO 136766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 136866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description Normally not GKI aware application will call this function 136966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** to send data to the port by callout functions 137066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 137166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 137266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** fd - socket fd 137366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** p_len - Byte count returned 137466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** 137566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani*******************************************************************************/ 137666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryaniint PORT_WriteDataCO (UINT16 handle, int* p_len) 137766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 137866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 137966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani tPORT *p_port; 138066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani BT_HDR *p_buf; 138166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani UINT32 event = 0; 138266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int rc = 0; 138366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani UINT16 length; 138466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 138566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_API1 ("PORT_WriteDataCO() handle:%d", handle); 138666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int written; 138766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *p_len = 0; 138866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 138966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* Check if handle is valid to avoid crashing */ 139066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if ((handle == 0) || (handle > MAX_RFC_PORTS)) 139166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 139266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_BAD_HANDLE); 139366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 139466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_port = &rfc_cb.port.port[handle - 1]; 139566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 139666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 139766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 139866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_WARNING1 ("PORT_WriteDataByFd() no port state:%d", p_port->state); 139966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_NOT_OPENED); 140066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 140166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 140266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (!p_port->peer_mtu) 140366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 140466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_ERROR1 ("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu); 140566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_UNKNOWN_ERROR); 140666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 140766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int available = 0; 140866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //if(ioctl(fd, FIONREAD, &available) < 0) 140966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(p_port->p_data_co_callback(handle, (UINT8*)&available, sizeof(available), 141066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE) == FALSE) 141166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 141266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_ERROR1("p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, available:%d", available); 141366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_UNKNOWN_ERROR); 141466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 141566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */ 141666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani length = RFCOMM_DATA_POOL_BUF_SIZE - 141766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD); 141866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 141966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* If there are buffers scheduled for transmission check if requested */ 142066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* data fits into the end of the queue */ 142166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani PORT_SCHEDULE_LOCK; 142266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 142366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (((p_buf = (BT_HDR *)p_port->tx.queue.p_last) != NULL) 142466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani && (((int)p_buf->len + available) <= (int)p_port->peer_mtu) 142566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani && (((int)p_buf->len + available) <= (int)length)) 142666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 142766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, available, 0) != available) 142866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, 142966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani available, DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE) 143066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 143166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 143266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, available:%d", available); 143366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_UNKNOWN_ERROR); 143466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 143566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len); 143666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_port->tx.queue_size += (UINT16)available; 143766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 143866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *p_len = available; 143966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_buf->len += (UINT16)available; 144066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 144166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani PORT_SCHEDULE_UNLOCK; 144266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 144366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_SUCCESS); 144466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 144566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 144666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani PORT_SCHEDULE_UNLOCK; 144766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 144866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu; 144966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 145066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //max_read = available < max_read ? available : max_read; 145166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 145266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani while (available) 145366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 145466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* if we're over buffer high water mark, we're done */ 145566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) 145666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM)) 145766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 145866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 145966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* continue with rfcomm data write */ 146066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_DATA_POOL_ID); 146166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (!p_buf) 146266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 146366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 146466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET; 146566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_buf->layer_specific = handle; 146666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 146766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (p_port->peer_mtu < length) 146866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani length = p_port->peer_mtu; 146966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (available < (int)length) 147066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani length = (UINT16)available; 147166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_buf->len = length; 147266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani p_buf->event = BT_EVT_TO_BTU_SP_DATA; 147366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 147466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length); 147566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset, (int)length, 0) != (int)length) 147666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset, length, 147766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE) 147866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 147966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d", length); 148066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_UNKNOWN_ERROR); 148166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 148266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 148366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 148466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani RFCOMM_TRACE_EVENT1 ("PORT_WriteData %d bytes", length); 148566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 148666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani rc = port_write (p_port, p_buf); 148766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 148866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* If queue went below the threashold need to send flow control */ 148966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani event |= port_flow_control_user (p_port); 149066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 149166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (rc == PORT_SUCCESS) 149266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani event |= PORT_EV_TXCHAR; 149366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 149466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) 149566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 149666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 149766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani *p_len += length; 149866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani available -= (int)length; 149966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 150066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED)) 150166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani event |= PORT_EV_TXEMPTY; 150266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 150366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* Mask out all events that are not of interest to user */ 150466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani event &= p_port->ev_mask; 150566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 150666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani /* Send event to the application */ 150766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if (p_port->p_callback && event) 150866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani (p_port->p_callback)(event, p_port->inx); 150966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 151066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return (PORT_SUCCESS); 151166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 151266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 1513e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1514e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1515e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1516e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1517e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_WriteData 1518e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 151966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Description Normally not GKI aware application will call this function 1520e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** to send data to the port. 1521e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 152266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 1523e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_data - Data area 1524e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** max_len - Byte count requested 1525e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_len - Byte count received 1526e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1527e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1528e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len) 1529e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1530e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 1531e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf; 1532e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT32 event = 0; 1533e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach int rc = 0; 1534e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach UINT16 length; 1535e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1536e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_WriteData() max_len:%d", max_len); 1537e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1538e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len = 0; 1539e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1540e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Check if handle is valid to avoid crashing */ 1541e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 1542e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1543e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 1544e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1545e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 1546e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1547e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 1548e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1549e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_WARNING1 ("PORT_WriteData() no port state:%d", p_port->state); 1550e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 1551e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1552e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1553e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!max_len || !p_port->peer_mtu) 1554e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1555e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_ERROR1 ("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu); 1556e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_UNKNOWN_ERROR); 1557e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1558e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1559e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */ 156066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani length = RFCOMM_DATA_POOL_BUF_SIZE - 1561e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD); 1562e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1563e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If there are buffers scheduled for transmission check if requested */ 1564e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* data fits into the end of the queue */ 1565e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_LOCK; 1566e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1567e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (((p_buf = (BT_HDR *)p_port->tx.queue.p_last) != NULL) 1568e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach && ((p_buf->len + max_len) <= p_port->peer_mtu) 1569e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach && ((p_buf->len + max_len) <= length)) 1570e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1571e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len); 1572e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port->tx.queue_size += max_len; 1573e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1574e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len = max_len; 1575e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->len += max_len; 1576e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1577e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1578e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1579e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1580e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1581e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1582e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach PORT_SCHEDULE_UNLOCK; 1583e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1584e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach while (max_len) 1585e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1586e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* if we're over buffer high water mark, we're done */ 1587e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) 1588e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM)) 1589e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1590e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1591e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* continue with rfcomm data write */ 1592e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_DATA_POOL_ID); 1593e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_buf) 1594e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1595e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1596e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET; 1597e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->layer_specific = handle; 1598e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1599e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->peer_mtu < length) 1600e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach length = p_port->peer_mtu; 1601e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (max_len < length) 1602e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach length = max_len; 1603e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->len = length; 1604e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->event = BT_EVT_TO_BTU_SP_DATA; 1605e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1606e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length); 1607e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1608e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_EVENT1 ("PORT_WriteData %d bytes", length); 1609e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1610e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rc = port_write (p_port, p_buf); 161166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 1612e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* If queue went below the threashold need to send flow control */ 1613e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event |= port_flow_control_user (p_port); 1614e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1615e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (rc == PORT_SUCCESS) 1616e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event |= PORT_EV_TXCHAR; 1617e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1618e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) 1619e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach break; 1620e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1621e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach *p_len += length; 1622e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach max_len -= length; 1623e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_data += length; 1624e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1625e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1626e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED)) 1627e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event |= PORT_EV_TXEMPTY; 1628e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1629e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Mask out all events that are not of interest to user */ 1630e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach event &= p_port->ev_mask; 1631e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1632e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach /* Send event to the application */ 1633e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (p_port->p_callback && event) 1634e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach (p_port->p_callback)(event, p_port->inx); 1635e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1636e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1637e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1638e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1639e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1640e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1641e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1642e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_Test 1643e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1644e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description Application can call this function to send RFCOMM Test frame 1645e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1646e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Parameters: handle - Handle returned in the RFCOMM_CreateConnection 1647e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** p_data - Data area 1648e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** max_len - Byte count requested 1649e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1650e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1651e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachint PORT_Test (UINT16 handle, UINT8 *p_data, UINT16 len) 1652e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1653e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach BT_HDR *p_buf; 1654e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach tPORT *p_port; 1655e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1656e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach RFCOMM_TRACE_API1 ("PORT_Test() len:%d", len); 1657e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1658e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((handle == 0) || (handle > MAX_RFC_PORTS)) 1659e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1660e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_BAD_HANDLE); 1661e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1662e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_port = &rfc_cb.port.port[handle - 1]; 1663e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1664e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) 1665e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1666e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NOT_OPENED); 1667e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1668e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1669e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (len > ((p_port->mtu == 0) ? RFCOMM_DEFAULT_MTU : p_port->mtu)) 1670e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1671e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_UNKNOWN_ERROR); 1672e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1673e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1674e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) != NULL) 1675e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 167666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 1677e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2; 1678e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach p_buf->len = len; 1679e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1680e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len); 1681e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1682e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rfc_send_test (p_port->rfc.p_mcb, TRUE, p_buf); 1683e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_SUCCESS); 1684e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1685e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach else 1686e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach { 1687e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (PORT_NO_MEM); 1688e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach } 1689e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1690e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1691e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1692e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1693e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function RFCOMM_Init 1694e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1695e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function is called to initialize RFCOMM layer 1696e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1697e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1698e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid RFCOMM_Init (void) 1699e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1700e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach memset (&rfc_cb, 0, sizeof (tRFC_CB)); /* Init RFCOMM control block */ 1701e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1702e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS; 1703e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1704e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#if defined(RFCOMM_INITIAL_TRACE_LEVEL) 1705e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rfc_cb.trace_level = RFCOMM_INITIAL_TRACE_LEVEL; 1706e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#else 1707e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rfc_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ 1708e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#endif 1709e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1710e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rfcomm_l2cap_if_init (); 1711e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1712e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1713e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************* 1714e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1715e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function PORT_SetTraceLevel 1716e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1717e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description This function sets the trace level for RFCOMM. If called with 1718e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** a value of 0xFF, it simply reads the current trace level. 1719e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1720e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns the new (current) trace level 1721e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** 1722e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*******************************************************************************/ 1723e448862a47c08eb23185aaed574b39264f5005fcAndre EisenbachUINT8 PORT_SetTraceLevel (UINT8 new_level) 1724e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{ 1725e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach if (new_level != 0xFF) 1726e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach rfc_cb.trace_level = new_level; 1727e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1728e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach return (rfc_cb.trace_level); 1729e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach} 1730e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach 1731