15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 1999-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  this file contains the Serial Port API code
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gki.h"
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "rfcdefs.h"
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "port_api.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "port_int.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_int.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_api.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "rfc_int.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "l2c_api.h"
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "sdp_api.h"
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* duration of break in 200ms units */
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define PORT_BREAK_DURATION     1
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <cutils/log.h>
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define info(fmt, ...)  ALOGI ("%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define debug(fmt, ...) ALOGD ("%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define error(fmt, ...) ALOGE ("## ERROR : %s: " fmt "##",__FUNCTION__,  ## __VA_ARGS__)
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define asrt(s) if(!(s)) ALOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         RFCOMM_CreateConnection
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      RFCOMM_CreateConnection function is used from the application
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to establish serial port connection to the peer device,
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  or allow RFCOMM to accept a connection from the peer
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  application.
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      scn          - Service Channel Number as registered with
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                                 the SDP (server) or obtained using SDP from
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                                 the peer device (client).
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  is_server    - TRUE if requesting application is a server
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mtu          - Maximum frame size the application can accept
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  bd_addr      - BD_ADDR of the peer (client)
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mask         - specifies events to be enabled.  A value
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                                 of zero disables all events.
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_handle     - OUT pointer to the handle.
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_mgmt_cb    - pointer to callback function to receive
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                                 connection up/down events.
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Notes:
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Server can call this function with the same scn parameter multiple times if
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** it is ready to accept multiple simulteneous connections.
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** DLCI for the connection is (scn * 2 + 1) if client originates connection on
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** existing none initiator multiplexer channel.  Otherwise it is (scn * 2).
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** For the server DLCI can be changed later if client will be calling it using
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** (scn * 2 + 1) dlci.
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle,
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             tPORT_CALLBACK *p_mgmt_cb)
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int        i;
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8      dlci;
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tRFC_MCB   *p_mcb = port_find_mcb (bd_addr);
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16     rfcomm_mtu;
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API6 ("RFCOMM_CreateConnection()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_handle = 0;
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (( scn == 0 )||(scn >= PORT_MAX_RFC_PORTS ))
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Server Channel Number(SCN) should be in range 1...30 */
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_ERROR0 ("RFCOMM_CreateConnection - invalid SCN");
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_INVALID_SCN);
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* For client that originate connection on the existing none initiator */
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* multiplexer channel DLCI should be odd */
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_mcb && !p_mcb->is_initiator && !is_server)
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        dlci = (scn << 1) + 1;
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        dlci = (scn << 1);
1059ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    RFCOMM_TRACE_API5("RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, p_mcb:%p",
1069ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                       scn, dlci, is_server, mtu, p_mcb);
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* For the server side always allocate a new port.  On the client side */
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* do not allow the same (dlci, bd_addr) to be opened twice by application */
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!is_server && ((p_port = port_find_port (dlci, bd_addr)) != NULL))
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if existing port is also a client port */
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_port->is_server == FALSE)
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            RFCOMM_TRACE_ERROR3 ("RFCOMM_CreateConnection - already opened state:%d, RFC state:%d, MCB state:%d",
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_port->state, p_port->rfc.state, p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0);
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (PORT_ALREADY_OPENED);
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_port = port_allocate_port (dlci, bd_addr)) == NULL)
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_WARNING0 ("RFCOMM_CreateConnection - no resources");
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NO_RESOURCES);
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1269ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie   RFCOMM_TRACE_API6("RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, p_mcb:%p, p_port:%p",
1279ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie                       scn, dlci, is_server, mtu, p_mcb, p_port);
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->default_signal_state = (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (uuid)
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case UUID_PROTOCOL_OBEX:
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE;
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case UUID_SERVCLASS_SERIAL_PORT:
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE;
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case UUID_SERVCLASS_LAN_ACCESS_USING_PPP:
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE;
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case UUID_SERVCLASS_DIALUP_NETWORKING:
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case UUID_SERVCLASS_FAX:
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE;
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_EVENT2 ("RFCOMM_CreateConnection dlci:%d signal state:0x%x", dlci, p_port->default_signal_state);
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_handle = p_port->inx;
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->state        = PORT_STATE_OPENING;
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->uuid         = uuid;
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->is_server    = is_server;
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->scn          = scn;
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->ev_mask      = 0;
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If the MTU is not specified (0), keep MTU decision until the
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * PN frame has to be send
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * at that time connection should be established and we
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     * will know for sure our prefered MTU
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     */
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (mtu)
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->mtu      = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu;
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->mtu      = rfcomm_mtu;
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* server doesn't need to release port when closing */
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( is_server )
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->keep_port_handle = TRUE;
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* keep mtu that user asked, p_port->mtu could be updated during param negotiation */
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->keep_mtu         = p_port->mtu;
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->local_ctrl.modem_signal = p_port->default_signal_state;
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->local_ctrl.fc           = FALSE;
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->p_mgmt_callback = p_mgmt_cb;
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i = 0; i < BD_ADDR_LEN; i++)
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->bd_addr[i] = bd_addr[i];
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If this is not initiator of the connection need to just wait */
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->is_server)
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Open will be continued after security checks are passed */
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return port_open_continue (p_port);
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         RFCOMM_RemoveConnection
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to close the specified connection.
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint RFCOMM_RemoveConnection (UINT16 handle)
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("RFCOMM_RemoveConnection() handle:%d", handle);
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_ERROR1 ("RFCOMM_RemoveConnection() BAD handle:%d", handle);
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT1 ("RFCOMM_RemoveConnection() Not opened:%d", handle);
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->state = PORT_STATE_CLOSING;
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    port_start_close (p_port);
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         RFCOMM_RemoveServer
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to close the server port.
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint RFCOMM_RemoveServer (UINT16 handle)
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("RFCOMM_RemoveServer() handle:%d", handle);
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_ERROR1 ("RFCOMM_RemoveServer() BAD handle:%d", handle);
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Do not report any events to the client any more. */
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->p_mgmt_callback = NULL;
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT1 ("RFCOMM_RemoveServer() Not opened:%d", handle);
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* this port will be deallocated after closing */
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->keep_port_handle = FALSE;
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->state = PORT_STATE_CLOSING;
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    port_start_close (p_port);
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_SetEventCallback
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to provide an address of the
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function which will be called when one of the events
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  specified in the mask occures.
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_callback - address of the callback function which should
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               be called from the RFCOMM when an event
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               specified in the mask occures.
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_SetEventCallback (UINT16 port_handle, tPORT_CALLBACK *p_port_cb)
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT  *p_port;
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[port_handle - 1];
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_SetEventCallback() handle:%d", port_handle);
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->p_callback = p_port_cb;
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3149ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie/*******************************************************************************
3159ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie**
3169ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie** Function         PORT_ClearKeepHandleFlag
3179ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie**
3189ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie** Description      This function is called to clear the keep handle flag
3199ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie**                  which will cause not to keep the port handle open when closed
3209ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
3219ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie**
3229ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie*******************************************************************************/
3239ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie
3249ac641d0a674333af57b85b367e64cf94dfae291Matthew Xieint PORT_ClearKeepHandleFlag (UINT16 port_handle)
3259ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie{
3269ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    tPORT  *p_port;
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3289ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    /* Check if handle is valid to avoid crashing */
3299ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
3309ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    {
3319ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie        return (PORT_BAD_HANDLE);
3329ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    }
3339ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie
3349ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    p_port = &rfc_cb.port.port[port_handle - 1];
3359ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    p_port->keep_port_handle = 0;
3369ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie    return (PORT_SUCCESS);
3379ac641d0a674333af57b85b367e64cf94dfae291Matthew Xie}
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_SetDataCallback
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is when a data packet is received
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_callback - address of the callback function which should
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               be called from the RFCOMM when data packet
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               is received.
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_SetDataCallback (UINT16 port_handle, tPORT_DATA_CALLBACK *p_port_cb)
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT  *p_port;
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[port_handle - 1];
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->p_data_callback = p_port_cb;
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_SetCODataCallback
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is when a data packet is received
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_callback - address of the callback function which should
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               be called from the RFCOMM when data packet
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               is received.
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_SetDataCOCallback (UINT16 port_handle, tPORT_DATA_CO_CALLBACK *p_port_cb)
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT  *p_port;
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle, p_port_cb);
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[port_handle - 1];
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->p_data_co_callback = p_port_cb;
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_SetEventMask
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to close the specified connection.
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  mask   - Bitmask of the events the host is interested in
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_SetEventMask (UINT16 port_handle, UINT32 mask)
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT  *p_port;
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_SetEventMask() handle:%d mask:0x%x", port_handle, mask);
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[port_handle - 1];
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->ev_mask = mask;
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_CheckConnection
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function returns PORT_SUCCESS if connection referenced
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  by handle is up and running
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  bd_addr    - OUT bd_addr of the peer
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_lcid     - OUT L2CAP's LCID
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid)
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_CheckConnection() handle:%d", handle);
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->rfc.p_mcb
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || !p_port->rfc.p_mcb->peer_ready
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || (p_port->rfc.state != RFC_STATE_OPENED))
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_LINE_ERR);
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memcpy (bd_addr, p_port->rfc.p_mcb->bd_addr, BD_ADDR_LEN);
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_lcid)
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_lcid = p_port->rfc.p_mcb->lcid;
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_IsOpening
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function returns TRUE if there is any RFCOMM connection
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  opening in process.
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      TRUE if any connection opening is found
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  bd_addr    - bd_addr of the peer
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN PORT_IsOpening (BD_ADDR bd_addr)
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   xx, yy;
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tRFC_MCB *p_mcb = NULL;
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT  *p_port;
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN found_port;
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check for any rfc_mcb which is in the middle of opening. */
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (xx = 0; xx < MAX_BD_CONNECTIONS; xx++)
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((rfc_cb.port.rfc_mcb[xx].state > RFC_MX_STATE_IDLE) &&
5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (rfc_cb.port.rfc_mcb[xx].state < RFC_MX_STATE_CONNECTED))
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return TRUE;
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (rfc_cb.port.rfc_mcb[xx].state == RFC_MX_STATE_CONNECTED)
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            found_port = FALSE;
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_mcb = &rfc_cb.port.rfc_mcb[xx];
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_port = &rfc_cb.port.port[0];
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            for (yy = 0; yy < MAX_RFC_PORTS; yy++, p_port++)
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if (p_port->rfc.p_mcb == p_mcb)
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    found_port = TRUE;
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    break;
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((!found_port) ||
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                (found_port && (p_port->rfc.state < RFC_STATE_OPENED)))
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                /* Port is not established yet. */
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return TRUE;
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return FALSE;
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_SetState
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function configures connection according to the
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  specifications in the tPORT_STATE structure.
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_settings - Pointer to a tPORT_STATE structure containing
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               configuration information for the connection.
5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_SetState (UINT16 handle, tPORT_STATE *p_settings)
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       baud_rate;
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_SetState() handle:%d", handle);
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->line_status)
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_LINE_ERR);
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_SetState() handle:%d FC_TYPE:0x%x", handle,
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       p_settings->fc_type);
5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    baud_rate = p_port->user_port_pars.baud_rate;
5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->user_port_pars = *p_settings;
5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* for now we've been asked to pass only baud rate */
5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (baud_rate != p_settings->baud_rate)
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        port_start_par_neg (p_port);
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_GetRxQueueCnt
6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function return number of buffers on the rx queue.
6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_rx_queue_count - Pointer to return queue count in.
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_GetRxQueueCnt (UINT16 handle, UINT16 *p_rx_queue_count)
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_GetRxQueueCnt() handle:%d", handle);
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->line_status)
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_LINE_ERR);
6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_rx_queue_count = p_port->rx.queue_size;
6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project	RFCOMM_TRACE_API2 ("PORT_GetRxQueueCnt() p_rx_queue_count:%d, p_port->rx.queue.count = %d",
6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project		                                     *p_rx_queue_count, p_port->rx.queue_size);
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_GetState
6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to fill tPORT_STATE structure
6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  with the curremt control settings for the port
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_settings - Pointer to a tPORT_STATE structure in which
6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               configuration information is returned.
6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_GetState (UINT16 handle, tPORT_STATE *p_settings)
6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_GetState() handle:%d", handle);
6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->line_status)
6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_LINE_ERR);
6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_settings = p_port->user_port_pars;
6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_Control
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function directs a specified connection to pass control
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  control information to the peer device.
6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  signal     = specify the function to be passed
6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_Control (UINT16 handle, UINT8 signal)
6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8      old_modem_signal;
7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_Control() handle:%d signal:0x%x", handle, signal);
7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    old_modem_signal = p_port->local_ctrl.modem_signal;
7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->local_ctrl.break_signal = 0;
7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (signal)
7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_SET_CTSRTS:
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal |= PORT_CTSRTS_ON;
7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_CLR_CTSRTS:
7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal &= ~PORT_CTSRTS_ON;
7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_SET_DTRDSR:
7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal |= PORT_DTRDSR_ON;
7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_CLR_DTRDSR:
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal &= ~PORT_DTRDSR_ON;
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_SET_RI:
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal |= PORT_RING_ON;
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_CLR_RI:
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal &= ~PORT_RING_ON;
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_SET_DCD:
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal |= PORT_DCD_ON;
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_CLR_DCD:
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.modem_signal &= ~PORT_DCD_ON;
7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (signal == PORT_BREAK)
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.break_signal = PORT_BREAK_DURATION;
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_port->local_ctrl.modem_signal == old_modem_signal)
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    port_start_control (p_port);
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_EVENT4 ("PORT_Control DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d",
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0),
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0),
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0),
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0));
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_FlowControl
7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function directs a specified connection to pass
7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  flow control message to the peer device.  Enable flag passed
7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  shows if port can accept more data.
7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  enable     - enables data flow
7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_FlowControl (UINT16 handle, BOOLEAN enable)
7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN    old_fc;
7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32     events;
7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_FlowControl() handle:%d enable: %d", handle, enable);
7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->rfc.p_mcb)
8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->rx.user_fc = !enable;
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT)
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_port->rx.user_fc)
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            port_flow_control_peer(p_port, TRUE, 0);
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        old_fc = p_port->local_ctrl.fc;
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* FC is set if user is set or peer is set */
8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_port->local_ctrl.fc != old_fc)
8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            port_start_control (p_port);
8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Need to take care of the case when we could not deliver events */
8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* to the application because we were flow controlled */
8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (enable && (p_port->rx.queue_size != 0))
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        events = PORT_EV_RXCHAR;
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_port->rx_flag_ev_pending)
8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_port->rx_flag_ev_pending = FALSE;
8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            events |= PORT_EV_RXFLAG;
8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        events &= p_port->ev_mask;
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_port->p_callback && events)
842181adbef76c194e257639daecb486bfc9a0ad037zzy        {
843181adbef76c194e257639daecb486bfc9a0ad037zzy            p_port->p_callback (events, p_port->inx);
844181adbef76c194e257639daecb486bfc9a0ad037zzy        }
845181adbef76c194e257639daecb486bfc9a0ad037zzy    }
846181adbef76c194e257639daecb486bfc9a0ad037zzy    return (PORT_SUCCESS);
847181adbef76c194e257639daecb486bfc9a0ad037zzy}
848181adbef76c194e257639daecb486bfc9a0ad037zzy/*******************************************************************************
849181adbef76c194e257639daecb486bfc9a0ad037zzy**
850181adbef76c194e257639daecb486bfc9a0ad037zzy** Function         PORT_FlowControl_MaxCredit
851181adbef76c194e257639daecb486bfc9a0ad037zzy**
852181adbef76c194e257639daecb486bfc9a0ad037zzy** Description      This function directs a specified connection to pass
853181adbef76c194e257639daecb486bfc9a0ad037zzy**                  flow control message to the peer device.  Enable flag passed
854181adbef76c194e257639daecb486bfc9a0ad037zzy**                  shows if port can accept more data. It also sends max credit
855181adbef76c194e257639daecb486bfc9a0ad037zzy**                  when data flow enabled
856181adbef76c194e257639daecb486bfc9a0ad037zzy**
857181adbef76c194e257639daecb486bfc9a0ad037zzy** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
858181adbef76c194e257639daecb486bfc9a0ad037zzy**                  enable     - enables data flow
859181adbef76c194e257639daecb486bfc9a0ad037zzy**
860181adbef76c194e257639daecb486bfc9a0ad037zzy*******************************************************************************/
861181adbef76c194e257639daecb486bfc9a0ad037zzy
862181adbef76c194e257639daecb486bfc9a0ad037zzyint PORT_FlowControl_MaxCredit (UINT16 handle, BOOLEAN enable)
863181adbef76c194e257639daecb486bfc9a0ad037zzy{
864181adbef76c194e257639daecb486bfc9a0ad037zzy    tPORT      *p_port;
865181adbef76c194e257639daecb486bfc9a0ad037zzy    BOOLEAN    old_fc;
866181adbef76c194e257639daecb486bfc9a0ad037zzy    UINT32     events;
867181adbef76c194e257639daecb486bfc9a0ad037zzy
868181adbef76c194e257639daecb486bfc9a0ad037zzy    RFCOMM_TRACE_API2 ("PORT_FlowControl() handle:%d enable: %d", handle, enable);
869181adbef76c194e257639daecb486bfc9a0ad037zzy
870181adbef76c194e257639daecb486bfc9a0ad037zzy    /* Check if handle is valid to avoid crashing */
871181adbef76c194e257639daecb486bfc9a0ad037zzy    if ((handle == 0) || (handle > MAX_RFC_PORTS))
872181adbef76c194e257639daecb486bfc9a0ad037zzy    {
873181adbef76c194e257639daecb486bfc9a0ad037zzy        return (PORT_BAD_HANDLE);
874181adbef76c194e257639daecb486bfc9a0ad037zzy    }
875181adbef76c194e257639daecb486bfc9a0ad037zzy
876181adbef76c194e257639daecb486bfc9a0ad037zzy    p_port = &rfc_cb.port.port[handle - 1];
877181adbef76c194e257639daecb486bfc9a0ad037zzy
878181adbef76c194e257639daecb486bfc9a0ad037zzy    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
879181adbef76c194e257639daecb486bfc9a0ad037zzy    {
880181adbef76c194e257639daecb486bfc9a0ad037zzy        return (PORT_NOT_OPENED);
881181adbef76c194e257639daecb486bfc9a0ad037zzy    }
882181adbef76c194e257639daecb486bfc9a0ad037zzy
883181adbef76c194e257639daecb486bfc9a0ad037zzy    if (!p_port->rfc.p_mcb)
884181adbef76c194e257639daecb486bfc9a0ad037zzy    {
885181adbef76c194e257639daecb486bfc9a0ad037zzy        return (PORT_NOT_OPENED);
886181adbef76c194e257639daecb486bfc9a0ad037zzy    }
887181adbef76c194e257639daecb486bfc9a0ad037zzy
888181adbef76c194e257639daecb486bfc9a0ad037zzy    p_port->rx.user_fc = !enable;
889181adbef76c194e257639daecb486bfc9a0ad037zzy
890181adbef76c194e257639daecb486bfc9a0ad037zzy    if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT)
891181adbef76c194e257639daecb486bfc9a0ad037zzy    {
892181adbef76c194e257639daecb486bfc9a0ad037zzy        if (!p_port->rx.user_fc)
893181adbef76c194e257639daecb486bfc9a0ad037zzy        {
894181adbef76c194e257639daecb486bfc9a0ad037zzy            port_flow_control_peer(p_port, TRUE, p_port->credit_rx);
895181adbef76c194e257639daecb486bfc9a0ad037zzy        }
896181adbef76c194e257639daecb486bfc9a0ad037zzy    }
897181adbef76c194e257639daecb486bfc9a0ad037zzy    else
898181adbef76c194e257639daecb486bfc9a0ad037zzy    {
899181adbef76c194e257639daecb486bfc9a0ad037zzy        old_fc = p_port->local_ctrl.fc;
900181adbef76c194e257639daecb486bfc9a0ad037zzy
901181adbef76c194e257639daecb486bfc9a0ad037zzy        /* FC is set if user is set or peer is set */
902181adbef76c194e257639daecb486bfc9a0ad037zzy        p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
903181adbef76c194e257639daecb486bfc9a0ad037zzy
904181adbef76c194e257639daecb486bfc9a0ad037zzy        if (p_port->local_ctrl.fc != old_fc)
905181adbef76c194e257639daecb486bfc9a0ad037zzy            port_start_control (p_port);
906181adbef76c194e257639daecb486bfc9a0ad037zzy    }
907181adbef76c194e257639daecb486bfc9a0ad037zzy
908181adbef76c194e257639daecb486bfc9a0ad037zzy    /* Need to take care of the case when we could not deliver events */
909181adbef76c194e257639daecb486bfc9a0ad037zzy    /* to the application because we were flow controlled */
910181adbef76c194e257639daecb486bfc9a0ad037zzy    if (enable && (p_port->rx.queue_size != 0))
911181adbef76c194e257639daecb486bfc9a0ad037zzy    {
912181adbef76c194e257639daecb486bfc9a0ad037zzy        events = PORT_EV_RXCHAR;
913181adbef76c194e257639daecb486bfc9a0ad037zzy        if (p_port->rx_flag_ev_pending)
914181adbef76c194e257639daecb486bfc9a0ad037zzy        {
915181adbef76c194e257639daecb486bfc9a0ad037zzy            p_port->rx_flag_ev_pending = FALSE;
916181adbef76c194e257639daecb486bfc9a0ad037zzy            events |= PORT_EV_RXFLAG;
917181adbef76c194e257639daecb486bfc9a0ad037zzy        }
918181adbef76c194e257639daecb486bfc9a0ad037zzy
919181adbef76c194e257639daecb486bfc9a0ad037zzy        events &= p_port->ev_mask;
920181adbef76c194e257639daecb486bfc9a0ad037zzy        if (p_port->p_callback && events)
9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_port->p_callback (events, p_port->inx);
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_GetModemStatus
9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function retrieves modem control signals.  Normally
9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  application will call this function after a callback
9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function is called with notification that one of signals
9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  has been changed.
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_signal   - specify the pointer to control signals info
9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_GetModemStatus (UINT16 handle, UINT8 *p_signal)
9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_signal = p_port->peer_ctrl.modem_signal;
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_GetModemStatus() handle:%d signal:%x", handle, *p_signal);
9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_ClearError
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function retreives information about a communications
9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  error and reports current status of a connection.  The
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  function should be called when an error occures to clear
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the connection error flag and to enable additional read
9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  and write operations.
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_errors   - pointer of the variable to receive error codes
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_status   - pointer to the tPORT_STATUS structur to receive
9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               connection status
9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_ClearError (UINT16 handle, UINT16 *p_errors, tPORT_STATUS *p_status)
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT  *p_port;
9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_ClearError() handle:%d", handle);
9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_errors = p_port->line_status;
10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* This is the only call to clear error status.  We can not clear */
10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* connection failed status.  To clean it port should be closed and reopened */
10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port->line_status = (p_port->line_status & LINE_STATUS_FAILED);
10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    PORT_GetQueueStatus (handle, p_status);
10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_SendError
10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function send a communications error to the peer device
10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  errors     - receive error codes
10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_SendError (UINT16 handle, UINT8 errors)
10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_SendError() handle:%d errors:0x%x", handle, errors);
10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->rfc.p_mcb)
10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_LineStatusReq (p_port->rfc.p_mcb, p_port->dlci, errors);
10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_GetQueueStatus
10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function reports current status of a connection.
10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_status   - pointer to the tPORT_STATUS structur to receive
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                               connection status
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_GetQueueStatus (UINT16 handle, tPORT_STATUS *p_status)
10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* RFCOMM_TRACE_API1 ("PORT_GetQueueStatus() handle:%d", handle); */
10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_status->in_queue_size  = (UINT16) p_port->rx.queue_size;
10795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_status->out_queue_size = (UINT16) p_port->tx.queue_size;
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_status->mtu_size = (UINT16) p_port->peer_mtu;
10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_status->flags = 0;
10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!(p_port->peer_ctrl.modem_signal & PORT_CTSRTS_ON))
10865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_status->flags |= PORT_FLAG_CTS_HOLD;
10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!(p_port->peer_ctrl.modem_signal & PORT_DTRDSR_ON))
10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_status->flags |= PORT_FLAG_DSR_HOLD;
10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!(p_port->peer_ctrl.modem_signal & PORT_DCD_ON))
10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_status->flags |= PORT_FLAG_RLSD_HOLD;
10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
10995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_Purge
11015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function discards all the data from the output or
11035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  input queues of the specified connection.
11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
11065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  purge_flags - specify the action to take.
11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_Purge (UINT16 handle, UINT8 purge_flags)
11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR     *p_buf;
11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      count;
11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32     events;
11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_Purge() handle:%d flags:0x%x", handle, purge_flags);
11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
11195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
11205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (purge_flags & PORT_PURGE_RXCLEAR)
11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_LOCK;  /* to prevent missing credit */
11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        count = p_port->rx.queue.count;
11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue)) != NULL)
11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GKI_freebuf (p_buf);
11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->rx.queue_size = 0;
11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_UNLOCK;
11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If we flowed controlled peer based on rx_queue size enable data again */
11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (count)
11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            port_flow_control_peer (p_port, TRUE, count);
11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (purge_flags & PORT_PURGE_TXCLEAR)
11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_LOCK;  /* to prevent tx.queue_size from being negative */
11525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->tx.queue)) != NULL)
11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GKI_freebuf (p_buf);
11555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->tx.queue_size = 0;
11575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_UNLOCK;
11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        events = PORT_EV_TXEMPTY;
11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        events |= port_flow_control_user (p_port);
11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        events &= p_port->ev_mask;
11655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_port->p_callback != NULL) && events)
11675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (p_port->p_callback)(events, p_port->inx);
11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
11715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
11755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_ReadData
11775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Normally not GKI aware application will call this function
11795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  after receiving PORT_EV_RXCHAR event.
11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_data      - Data area
11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  max_len     - Byte count requested
11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len       - Byte count received
11855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
11865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
11875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_ReadData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
11885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
11895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
11905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR     *p_buf;
11915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16      count;
11925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API2 ("PORT_ReadData() handle:%d max_len:%d", handle, max_len);
11945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Initialize this in case of an error */
11965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_len = 0;
11975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
11985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
11995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
12025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
12055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
12075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
12095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->line_status)
12125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_LINE_ERR);
12145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf = (BT_HDR *)GKI_getfirst (&p_port->rx.queue);
12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_buf)
12185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
12195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    count = 0;
12215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (max_len && p_buf)
12235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_buf->len > max_len)
12255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, max_len);
12275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->offset += max_len;
12285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_buf->len    -= max_len;
12295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_len += max_len;
12315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            PORT_SCHEDULE_LOCK;
12335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_port->rx.queue_size -= max_len;
12355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            PORT_SCHEDULE_UNLOCK;
12375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
12395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
12415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
12425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
12435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_len  += p_buf->len;
12455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            max_len -= p_buf->len;
12465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            PORT_SCHEDULE_LOCK;
12485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_port->rx.queue_size -= p_buf->len;
12505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (max_len)
12525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
12535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_data  += p_buf->len;
12545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                p_buf = (BT_HDR *)GKI_getnext (p_buf);
12555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
12565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GKI_freebuf (GKI_dequeue (&p_port->rx.queue));
12585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            PORT_SCHEDULE_UNLOCK;
12605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            count++;
12625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
12635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (*p_len == 1)
12665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT3 ("PORT_ReadData queue:%d returned:%d %x", p_port->rx.queue_size, *p_len, (p_data[0]));
12685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
12705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
12715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT2 ("PORT_ReadData queue:%d returned:%d", p_port->rx.queue_size, *p_len);
12725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
12735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
12755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* check if it can be resumed now */
12765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    port_flow_control_peer (p_port, TRUE, count);
12775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
12795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
12805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
12835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_Read
12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Normally application will call this function after receiving
12875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  PORT_EV_RXCHAR event.
12885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
12905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  pp_buf      - pointer to address of buffer with data,
12915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
12925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
12935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_Read (UINT16 handle, BT_HDR **pp_buf)
12945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
12955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
12965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR     *p_buf;
12975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
12985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_Read() handle:%d", handle);
12995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
13015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
13025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
13045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
13065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
13085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
13105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->line_status)
13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_LINE_ERR);
13155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    PORT_SCHEDULE_LOCK;
13185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue);
13205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_buf)
13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->rx.queue_size -= p_buf->len;
13235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_UNLOCK;
13255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
13275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* check if it can be resumed now */
13285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        port_flow_control_peer (p_port, TRUE, 1);
13295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
13315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_UNLOCK;
13335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *pp_buf = p_buf;
13365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
13375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
13385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
13415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         port_write
13435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function when a data packet is received from the apper
13455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  layer task.
13465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      p_port     - pointer to address of port control block
13485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_buf      - pointer to address of buffer with data,
13495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
13505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
13515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int port_write (tPORT *p_port, BT_HDR *p_buf)
13525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
13535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* We should not allow to write data in to server port when connection is not opened */
13545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED))
13555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
13575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_CLOSED);
13585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Keep the data in pending queue if peer does not allow data, or */
13615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Peer is not ready or Port is not yet opened or initial port control */
13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* command has not been sent */
13635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->tx.peer_fc
13645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || !p_port->rfc.p_mcb
13655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || !p_port->rfc.p_mcb->peer_ready
13665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || (p_port->rfc.state != RFC_STATE_OPENED)
13675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     || ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
13685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                              (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)))
13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_port->tx.queue_size  > PORT_TX_CRITICAL_WM)
13715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || (p_port->tx.queue.count > PORT_TX_BUF_CRITICAL_WM))
13725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
13735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            RFCOMM_TRACE_WARNING1 ("PORT_Write: Queue size: %d",
13745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                   p_port->tx.queue_size);
13755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            GKI_freebuf (p_buf);
13775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR))
13795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                  p_port->p_callback (PORT_EV_ERR, p_port->inx);
13805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (PORT_TX_FULL);
13825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT4 ("PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d ctrl_state %x",
13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             p_port->tx.peer_fc,
13865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready),
13875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             p_port->rfc.state,
13885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                             p_port->port_ctrl);
13895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_enqueue (&p_port->tx.queue, p_buf);
13915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->tx.queue_size += p_buf->len;
13925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_CMD_PENDING);
13945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
13955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
13965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
13975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT0 ("PORT_Write : Data is being sent");
13985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
13995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_DataReq (p_port->rfc.p_mcb, p_port->dlci, p_buf);
14005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
14015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
14035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
14055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_Write
14075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function when a data packet is received from the apper
14095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  layer task.
14105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
14125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  pp_buf      - pointer to address of buffer with data,
14135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
14155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_Write (UINT16 handle, BT_HDR *p_buf)
14165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
14175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT  *p_port;
14185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32 event = 0;
14195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int    rc;
14205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_Write() handle:%d", handle);
14225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
14245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
14255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
14275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
14285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
14315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
14335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
14355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
14365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->line_status)
14395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_WARNING1 ("PORT_Write: Data dropped line_status:0x%x",
14415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                               p_port->line_status);
14425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GKI_freebuf (p_buf);
14435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_LINE_ERR);
14445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rc = port_write (p_port, p_buf);
14475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    event |= port_flow_control_user (p_port);
14485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (rc)
14505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_TX_FULL:
14525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        event |= PORT_EV_ERR;
14535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
14545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    case PORT_SUCCESS:
14565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        event |= (PORT_EV_TXCHAR | PORT_EV_TXEMPTY);
14575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        break;
14585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Mask out all events that are not of interest to user */
14605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    event &= p_port->ev_mask;
14615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send event to the application */
14635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->p_callback && event)
14645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_port->p_callback)(event, p_port->inx);
14655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
14675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
14685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
14695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_WriteDataCO
14715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Normally not GKI aware application will call this function
14735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to send data to the port by callout functions
14745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
14765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  fd         - socket fd
14775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len      - Byte count returned
14785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
14795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
14805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_WriteDataCO (UINT16 handle, int* p_len)
14815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
14825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
14845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR     *p_buf;
14855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32     event = 0;
14865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int        rc = 0;
14875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16     length;
14885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_WriteDataCO() handle:%d", handle);
14905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int written;
14915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_len = 0;
14925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
14945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
14955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
14965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
14975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
14985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
14995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
15015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_WARNING1 ("PORT_WriteDataByFd() no port state:%d", p_port->state);
15035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
15045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->peer_mtu)
15075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_ERROR1 ("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu);
15095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_UNKNOWN_ERROR);
15105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int available = 0;
15125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    //if(ioctl(fd, FIONREAD, &available) < 0)
15135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(p_port->p_data_co_callback(handle, (UINT8*)&available, sizeof(available),
15145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE) == FALSE)
15155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_ERROR1("p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, available:%d", available);
15175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_UNKNOWN_ERROR);
15185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1519ebef4763b36b05370d13dfd27c4fcaa9095dbeffzzy    if(available == 0)
1520ebef4763b36b05370d13dfd27c4fcaa9095dbeffzzy        return PORT_SUCCESS;
15215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */
15225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    length = RFCOMM_DATA_POOL_BUF_SIZE -
15235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
15245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If there are buffers scheduled for transmission check if requested */
15265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* data fits into the end of the queue */
15275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    PORT_SCHEDULE_LOCK;
15285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (((p_buf = (BT_HDR *)p_port->tx.queue.p_last) != NULL)
15305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     && (((int)p_buf->len + available) <= (int)p_port->peer_mtu)
15315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     && (((int)p_buf->len + available) <= (int)length))
15325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, available, 0) != available)
15345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len,
15355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                    available, DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE)
15365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
15385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, available:%d", available);
1539ebef4763b36b05370d13dfd27c4fcaa9095dbeffzzy            PORT_SCHEDULE_UNLOCK;
15405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (PORT_UNKNOWN_ERROR);
15415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
15425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
15435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->tx.queue_size += (UINT16)available;
15445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_len = available;
15465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len += (UINT16)available;
15475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_UNLOCK;
15495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
15515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
15525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    PORT_SCHEDULE_UNLOCK;
15545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    //int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu;
15565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    //max_read = available < max_read ? available : max_read;
15585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (available)
15605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
15615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if we're over buffer high water mark, we're done */
15625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_port->tx.queue_size  > PORT_TX_HIGH_WM)
15635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM))
15645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
15655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* continue with rfcomm data write */
15675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_DATA_POOL_ID);
15685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_buf)
15695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
15705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset         = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
15725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->layer_specific = handle;
15735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_port->peer_mtu < length)
15755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            length = p_port->peer_mtu;
15765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (available < (int)length)
15775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            length = (UINT16)available;
15785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len = length;
15795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->event          = BT_EVT_TO_BTU_SP_DATA;
15805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);
15825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        //if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset, (int)length, 0) != (int)length)
15835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset, length,
15845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                      DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE)
15855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
15865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d", length);
15875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return (PORT_UNKNOWN_ERROR);
15885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
15895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT1 ("PORT_WriteData %d bytes", length);
15925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rc = port_write (p_port, p_buf);
15945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If queue went below the threashold need to send flow control */
15965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        event |= port_flow_control_user (p_port);
15975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
15985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (rc == PORT_SUCCESS)
15995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            event |= PORT_EV_TXCHAR;
16005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING))
16025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
16035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_len  += length;
16055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        available -= (int)length;
16065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
16085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        event |= PORT_EV_TXEMPTY;
16095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Mask out all events that are not of interest to user */
16115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    event &= p_port->ev_mask;
16125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send event to the application */
16145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->p_callback && event)
16155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_port->p_callback)(event, p_port->inx);
16165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
16185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
16235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_WriteData
16255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Normally not GKI aware application will call this function
16275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  to send data to the port.
16285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
16305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_data      - Data area
16315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  max_len     - Byte count requested
16325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_len       - Byte count received
16335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
16345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
16355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
16365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
16375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT      *p_port;
16385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR     *p_buf;
16395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32     event = 0;
16405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int        rc = 0;
16415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16     length;
16425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_WriteData() max_len:%d", max_len);
16445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    *p_len = 0;
16465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Check if handle is valid to avoid crashing */
16485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
16495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
16515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
16535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
16555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_WARNING1 ("PORT_WriteData() no port state:%d", p_port->state);
16575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
16585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!max_len || !p_port->peer_mtu)
16615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_ERROR1 ("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu);
16635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_UNKNOWN_ERROR);
16645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */
16675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    length = RFCOMM_DATA_POOL_BUF_SIZE -
16685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
16695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* If there are buffers scheduled for transmission check if requested */
16715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* data fits into the end of the queue */
16725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    PORT_SCHEDULE_LOCK;
16735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (((p_buf = (BT_HDR *)p_port->tx.queue.p_last) != NULL)
16755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     && ((p_buf->len + max_len) <= p_port->peer_mtu)
16765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project     && ((p_buf->len + max_len) <= length))
16775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
16795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_port->tx.queue_size += max_len;
16805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_len = max_len;
16825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len += max_len;
16835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        PORT_SCHEDULE_UNLOCK;
16855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
16875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
16885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    PORT_SCHEDULE_UNLOCK;
16905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    while (max_len)
16925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
16935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if we're over buffer high water mark, we're done */
16945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((p_port->tx.queue_size  > PORT_TX_HIGH_WM)
16955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM))
16965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
16975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* continue with rfcomm data write */
16995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_DATA_POOL_ID);
17005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_buf)
17015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
17025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset         = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
17045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->layer_specific = handle;
17055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (p_port->peer_mtu < length)
17075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            length = p_port->peer_mtu;
17085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (max_len < length)
17095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            length = max_len;
17105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len = length;
17115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->event          = BT_EVT_TO_BTU_SP_DATA;
17125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);
17145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        RFCOMM_TRACE_EVENT1 ("PORT_WriteData %d bytes", length);
17165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rc = port_write (p_port, p_buf);
17185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* If queue went below the threashold need to send flow control */
17205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        event |= port_flow_control_user (p_port);
17215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (rc == PORT_SUCCESS)
17235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            event |= PORT_EV_TXCHAR;
17245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING))
17265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
17275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_len  += length;
17295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        max_len -= length;
17305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_data  += length;
17315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
17345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        event |= PORT_EV_TXEMPTY;
17355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Mask out all events that are not of interest to user */
17375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    event &= p_port->ev_mask;
17385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Send event to the application */
17405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_port->p_callback && event)
17415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_port->p_callback)(event, p_port->inx);
17425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (PORT_SUCCESS);
17445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_Test
17505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Application can call this function to send RFCOMM Test frame
17525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Parameters:      handle      - Handle returned in the RFCOMM_CreateConnection
17545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  p_data      - Data area
17555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  max_len     - Byte count requested
17565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
17575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
17585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint PORT_Test (UINT16 handle, UINT8 *p_data, UINT16 len)
17595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
17605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BT_HDR   *p_buf;
17615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tPORT    *p_port;
17625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    RFCOMM_TRACE_API1 ("PORT_Test() len:%d", len);
17645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((handle == 0) || (handle > MAX_RFC_PORTS))
17665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_BAD_HANDLE);
17685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p_port = &rfc_cb.port.port[handle - 1];
17705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
17725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NOT_OPENED);
17745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (len > ((p_port->mtu == 0) ? RFCOMM_DEFAULT_MTU : p_port->mtu))
17775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_UNKNOWN_ERROR);
17795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) != NULL)
17825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->offset  = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
17855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_buf->len = len;
17865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
17885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_send_test (p_port->rfc.p_mcb, TRUE, p_buf);
17905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_SUCCESS);
17915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
17935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
17945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return (PORT_NO_MEM);
17955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
17965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
17975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
17985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
17995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         RFCOMM_Init
18015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called to initialize RFCOMM layer
18035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid RFCOMM_Init (void)
18065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
18075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&rfc_cb, 0, sizeof (tRFC_CB));  /* Init RFCOMM control block */
18085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS;
18105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if defined(RFCOMM_INITIAL_TRACE_LEVEL)
18125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_cb.trace_level = RFCOMM_INITIAL_TRACE_LEVEL;
18135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else
18145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfc_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
18155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
18165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rfcomm_l2cap_if_init ();
18185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
18215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         PORT_SetTraceLevel
18235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sets the trace level for RFCOMM. If called with
18255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  a value of 0xFF, it simply reads the current trace level.
18265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          the new (current) trace level
18285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
18295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
18305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectUINT8 PORT_SetTraceLevel (UINT8 new_level)
18315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
18325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (new_level != 0xFF)
18335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rfc_cb.trace_level = new_level;
18345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
18355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return (rfc_cb.trace_level);
18365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1838