/******************************************************************************
 *
 *  Copyright (C) 1999-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  this file contains the Serial Port API code
 *
 ******************************************************************************/

#include <string.h>
#include "bt_target.h"
#include "gki.h"
#include "rfcdefs.h"
#include "port_api.h"
#include "port_int.h"
#include "btm_int.h"
#include "btm_api.h"
#include "rfc_int.h"
#include "l2c_api.h"
#include "sdp_api.h"

/* duration of break in 200ms units */
#define PORT_BREAK_DURATION     1

#include <cutils/log.h>
#define info(fmt, ...)  ALOGI ("%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
#define debug(fmt, ...) ALOGD ("%s: " fmt,__FUNCTION__,  ## __VA_ARGS__)
#define error(fmt, ...) ALOGE ("## ERROR : %s: " fmt "##",__FUNCTION__,  ## __VA_ARGS__)
#define asrt(s) if(!(s)) ALOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)

/*******************************************************************************
**
** Function         RFCOMM_CreateConnection
**
** Description      RFCOMM_CreateConnection function is used from the application
**                  to establish serial port connection to the peer device,
**                  or allow RFCOMM to accept a connection from the peer
**                  application.
**
** Parameters:      scn          - Service Channel Number as registered with
**                                 the SDP (server) or obtained using SDP from
**                                 the peer device (client).
**                  is_server    - TRUE if requesting application is a server
**                  mtu          - Maximum frame size the application can accept
**                  bd_addr      - BD_ADDR of the peer (client)
**                  mask         - specifies events to be enabled.  A value
**                                 of zero disables all events.
**                  p_handle     - OUT pointer to the handle.
**                  p_mgmt_cb    - pointer to callback function to receive
**                                 connection up/down events.
** Notes:
**
** Server can call this function with the same scn parameter multiple times if
** it is ready to accept multiple simulteneous connections.
**
** DLCI for the connection is (scn * 2 + 1) if client originates connection on
** existing none initiator multiplexer channel.  Otherwise it is (scn * 2).
** For the server DLCI can be changed later if client will be calling it using
** (scn * 2 + 1) dlci.
**
*******************************************************************************/
int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
                             UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle,
                             tPORT_CALLBACK *p_mgmt_cb)
{
    tPORT      *p_port;
    int        i;
    UINT8      dlci;
    tRFC_MCB   *p_mcb = port_find_mcb (bd_addr);
    UINT16     rfcomm_mtu;

    RFCOMM_TRACE_API ("RFCOMM_CreateConnection()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
                       bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);

    *p_handle = 0;

    if (( scn == 0 )||(scn >= PORT_MAX_RFC_PORTS ))
    {
        /* Server Channel Number(SCN) should be in range 1...30 */
        RFCOMM_TRACE_ERROR ("RFCOMM_CreateConnection - invalid SCN");
        return (PORT_INVALID_SCN);
    }

    /* For client that originate connection on the existing none initiator */
    /* multiplexer channel DLCI should be odd */
    if (p_mcb && !p_mcb->is_initiator && !is_server)
        dlci = (scn << 1) + 1;
    else
        dlci = (scn << 1);
    RFCOMM_TRACE_API("RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, p_mcb:%p",
                       scn, dlci, is_server, mtu, p_mcb);

    /* For the server side always allocate a new port.  On the client side */
    /* do not allow the same (dlci, bd_addr) to be opened twice by application */
    if (!is_server && ((p_port = port_find_port (dlci, bd_addr)) != NULL))
    {
        /* if existing port is also a client port */
        if (p_port->is_server == FALSE)
        {
            RFCOMM_TRACE_ERROR ("RFCOMM_CreateConnection - already opened state:%d, RFC state:%d, MCB state:%d",
                p_port->state, p_port->rfc.state, p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0);
            return (PORT_ALREADY_OPENED);
        }
    }

    if ((p_port = port_allocate_port (dlci, bd_addr)) == NULL)
    {
        RFCOMM_TRACE_WARNING ("RFCOMM_CreateConnection - no resources");
        return (PORT_NO_RESOURCES);
    }
   RFCOMM_TRACE_API("RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, p_mcb:%p, p_port:%p",
                       scn, dlci, is_server, mtu, p_mcb, p_port);

    p_port->default_signal_state = (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);

    switch (uuid)
    {
    case UUID_PROTOCOL_OBEX:
        p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE;
        break;
    case UUID_SERVCLASS_SERIAL_PORT:
        p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE;
        break;
    case UUID_SERVCLASS_LAN_ACCESS_USING_PPP:
        p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE;
        break;
    case UUID_SERVCLASS_DIALUP_NETWORKING:
    case UUID_SERVCLASS_FAX:
        p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE;
        break;
    }

    RFCOMM_TRACE_EVENT ("RFCOMM_CreateConnection dlci:%d signal state:0x%x", dlci, p_port->default_signal_state);

    *p_handle = p_port->inx;

    p_port->state        = PORT_STATE_OPENING;
    p_port->uuid         = uuid;
    p_port->is_server    = is_server;
    p_port->scn          = scn;
    p_port->ev_mask      = 0;

    /* If the MTU is not specified (0), keep MTU decision until the
     * PN frame has to be send
     * at that time connection should be established and we
     * will know for sure our prefered MTU
     */

    rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;

    if (mtu)
        p_port->mtu      = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu;
    else
        p_port->mtu      = rfcomm_mtu;

    /* server doesn't need to release port when closing */
    if( is_server )
    {
        p_port->keep_port_handle = TRUE;

        /* keep mtu that user asked, p_port->mtu could be updated during param negotiation */
        p_port->keep_mtu         = p_port->mtu;
    }

    p_port->local_ctrl.modem_signal = p_port->default_signal_state;
    p_port->local_ctrl.fc           = FALSE;

    p_port->p_mgmt_callback = p_mgmt_cb;

    for (i = 0; i < BD_ADDR_LEN; i++)
        p_port->bd_addr[i] = bd_addr[i];

    /* If this is not initiator of the connection need to just wait */
    if (p_port->is_server)
    {
        return (PORT_SUCCESS);
    }

    /* Open will be continued after security checks are passed */
    return port_open_continue (p_port);
}


/*******************************************************************************
**
** Function         RFCOMM_RemoveConnection
**
** Description      This function is called to close the specified connection.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**
*******************************************************************************/
int RFCOMM_RemoveConnection (UINT16 handle)
{
    tPORT      *p_port;

    RFCOMM_TRACE_API ("RFCOMM_RemoveConnection() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        RFCOMM_TRACE_ERROR ("RFCOMM_RemoveConnection() BAD handle:%d", handle);
        return (PORT_BAD_HANDLE);
    }
    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        RFCOMM_TRACE_EVENT ("RFCOMM_RemoveConnection() Not opened:%d", handle);
        return (PORT_SUCCESS);
    }

    p_port->state = PORT_STATE_CLOSING;

    port_start_close (p_port);

    return (PORT_SUCCESS);
}

/*******************************************************************************
**
** Function         RFCOMM_RemoveServer
**
** Description      This function is called to close the server port.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**
*******************************************************************************/
int RFCOMM_RemoveServer (UINT16 handle)
{
    tPORT      *p_port;

    RFCOMM_TRACE_API ("RFCOMM_RemoveServer() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        RFCOMM_TRACE_ERROR ("RFCOMM_RemoveServer() BAD handle:%d", handle);
        return (PORT_BAD_HANDLE);
    }
    p_port = &rfc_cb.port.port[handle - 1];

    /* Do not report any events to the client any more. */
    p_port->p_mgmt_callback = NULL;

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        RFCOMM_TRACE_EVENT ("RFCOMM_RemoveServer() Not opened:%d", handle);
        return (PORT_SUCCESS);
    }

    /* this port will be deallocated after closing */
    p_port->keep_port_handle = FALSE;
    p_port->state = PORT_STATE_CLOSING;

    port_start_close (p_port);

    return (PORT_SUCCESS);
}

/*******************************************************************************
**
** Function         PORT_SetEventCallback
**
** Description      This function is called to provide an address of the
**                  function which will be called when one of the events
**                  specified in the mask occures.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_callback - address of the callback function which should
**                               be called from the RFCOMM when an event
**                               specified in the mask occures.
**
**
*******************************************************************************/
int PORT_SetEventCallback (UINT16 port_handle, tPORT_CALLBACK *p_port_cb)
{
    tPORT  *p_port;

    /* Check if handle is valid to avoid crashing */
    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[port_handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    RFCOMM_TRACE_API ("PORT_SetEventCallback() handle:%d", port_handle);

    p_port->p_callback = p_port_cb;

    return (PORT_SUCCESS);
}
/*******************************************************************************
**
** Function         PORT_ClearKeepHandleFlag
**
** Description      This function is called to clear the keep handle flag
**                  which will cause not to keep the port handle open when closed
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**
*******************************************************************************/

int PORT_ClearKeepHandleFlag (UINT16 port_handle)
{
    tPORT  *p_port;

    /* Check if handle is valid to avoid crashing */
    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[port_handle - 1];
    p_port->keep_port_handle = 0;
    return (PORT_SUCCESS);
}

/*******************************************************************************
**
** Function         PORT_SetDataCallback
**
** Description      This function is when a data packet is received
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_callback - address of the callback function which should
**                               be called from the RFCOMM when data packet
**                               is received.
**
**
*******************************************************************************/
int PORT_SetDataCallback (UINT16 port_handle, tPORT_DATA_CALLBACK *p_port_cb)
{
    tPORT  *p_port;

    RFCOMM_TRACE_API ("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle, p_port_cb);

    /* Check if handle is valid to avoid crashing */
    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[port_handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    p_port->p_data_callback = p_port_cb;

    return (PORT_SUCCESS);
}
/*******************************************************************************
**
** Function         PORT_SetCODataCallback
**
** Description      This function is when a data packet is received
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_callback - address of the callback function which should
**                               be called from the RFCOMM when data packet
**                               is received.
**
**
*******************************************************************************/
int PORT_SetDataCOCallback (UINT16 port_handle, tPORT_DATA_CO_CALLBACK *p_port_cb)
{
    tPORT  *p_port;

    RFCOMM_TRACE_API ("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle, p_port_cb);

    /* Check if handle is valid to avoid crashing */
    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[port_handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    p_port->p_data_co_callback = p_port_cb;

    return (PORT_SUCCESS);
}



/*******************************************************************************
**
** Function         PORT_SetEventMask
**
** Description      This function is called to close the specified connection.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  mask   - Bitmask of the events the host is interested in
**
*******************************************************************************/
int PORT_SetEventMask (UINT16 port_handle, UINT32 mask)
{
    tPORT  *p_port;

    RFCOMM_TRACE_API ("PORT_SetEventMask() handle:%d mask:0x%x", port_handle, mask);

    /* Check if handle is valid to avoid crashing */
    if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[port_handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    p_port->ev_mask = mask;

    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_CheckConnection
**
** Description      This function returns PORT_SUCCESS if connection referenced
**                  by handle is up and running
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  bd_addr    - OUT bd_addr of the peer
**                  p_lcid     - OUT L2CAP's LCID
**
*******************************************************************************/
int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid)
{
    tPORT      *p_port;

    RFCOMM_TRACE_API ("PORT_CheckConnection() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (!p_port->rfc.p_mcb
     || !p_port->rfc.p_mcb->peer_ready
     || (p_port->rfc.state != RFC_STATE_OPENED))
    {
        return (PORT_LINE_ERR);
    }

    memcpy (bd_addr, p_port->rfc.p_mcb->bd_addr, BD_ADDR_LEN);
    if (p_lcid)
        *p_lcid = p_port->rfc.p_mcb->lcid;

    return (PORT_SUCCESS);
}

/*******************************************************************************
**
** Function         PORT_IsOpening
**
** Description      This function returns TRUE if there is any RFCOMM connection
**                  opening in process.
**
** Parameters:      TRUE if any connection opening is found
**                  bd_addr    - bd_addr of the peer
**
*******************************************************************************/
BOOLEAN PORT_IsOpening (BD_ADDR bd_addr)
{
    UINT8   xx, yy;
    tRFC_MCB *p_mcb = NULL;
    tPORT  *p_port;
    BOOLEAN found_port;

    /* Check for any rfc_mcb which is in the middle of opening. */
    for (xx = 0; xx < MAX_BD_CONNECTIONS; xx++)
    {
        if ((rfc_cb.port.rfc_mcb[xx].state > RFC_MX_STATE_IDLE) &&
            (rfc_cb.port.rfc_mcb[xx].state < RFC_MX_STATE_CONNECTED))
        {
            memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
            return TRUE;
        }

        if (rfc_cb.port.rfc_mcb[xx].state == RFC_MX_STATE_CONNECTED)
        {
            found_port = FALSE;
            p_mcb = &rfc_cb.port.rfc_mcb[xx];
            p_port = &rfc_cb.port.port[0];

            for (yy = 0; yy < MAX_RFC_PORTS; yy++, p_port++)
            {
                if (p_port->rfc.p_mcb == p_mcb)
                {
                    found_port = TRUE;
                    break;
                }
            }

            if ((!found_port) ||
                (found_port && (p_port->rfc.state < RFC_STATE_OPENED)))
            {
                /* Port is not established yet. */
                memcpy (bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
                return TRUE;
            }
        }
    }

    return FALSE;
}

/*******************************************************************************
**
** Function         PORT_SetState
**
** Description      This function configures connection according to the
**                  specifications in the tPORT_STATE structure.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_settings - Pointer to a tPORT_STATE structure containing
**                               configuration information for the connection.
**
**
*******************************************************************************/
int PORT_SetState (UINT16 handle, tPORT_STATE *p_settings)
{
    tPORT      *p_port;
    UINT8       baud_rate;

    RFCOMM_TRACE_API ("PORT_SetState() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (p_port->line_status)
    {
        return (PORT_LINE_ERR);
    }

    RFCOMM_TRACE_API ("PORT_SetState() handle:%d FC_TYPE:0x%x", handle,
                       p_settings->fc_type);

    baud_rate = p_port->user_port_pars.baud_rate;
    p_port->user_port_pars = *p_settings;

    /* for now we've been asked to pass only baud rate */
    if (baud_rate != p_settings->baud_rate)
    {
        port_start_par_neg (p_port);
    }
    return (PORT_SUCCESS);
}

/*******************************************************************************
**
** Function         PORT_GetRxQueueCnt
**
** Description      This function return number of buffers on the rx queue.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_rx_queue_count - Pointer to return queue count in.
**
*******************************************************************************/
int PORT_GetRxQueueCnt (UINT16 handle, UINT16 *p_rx_queue_count)
{
    tPORT      *p_port;

    RFCOMM_TRACE_API ("PORT_GetRxQueueCnt() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (p_port->line_status)
    {
        return (PORT_LINE_ERR);
    }

    *p_rx_queue_count = p_port->rx.queue_size;

	RFCOMM_TRACE_API ("PORT_GetRxQueueCnt() p_rx_queue_count:%d, p_port->rx.queue.count = %d",
		                                     *p_rx_queue_count, p_port->rx.queue_size);

    return (PORT_SUCCESS);
}

/*******************************************************************************
**
** Function         PORT_GetState
**
** Description      This function is called to fill tPORT_STATE structure
**                  with the curremt control settings for the port
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_settings - Pointer to a tPORT_STATE structure in which
**                               configuration information is returned.
**
*******************************************************************************/
int PORT_GetState (UINT16 handle, tPORT_STATE *p_settings)
{
    tPORT      *p_port;

    RFCOMM_TRACE_API ("PORT_GetState() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (p_port->line_status)
    {
        return (PORT_LINE_ERR);
    }

    *p_settings = p_port->user_port_pars;
    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_Control
**
** Description      This function directs a specified connection to pass control
**                  control information to the peer device.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  signal     = specify the function to be passed
**
*******************************************************************************/
int PORT_Control (UINT16 handle, UINT8 signal)
{
    tPORT      *p_port;
    UINT8      old_modem_signal;

    RFCOMM_TRACE_API ("PORT_Control() handle:%d signal:0x%x", handle, signal);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    old_modem_signal = p_port->local_ctrl.modem_signal;
    p_port->local_ctrl.break_signal = 0;

    switch (signal)
    {
    case PORT_SET_CTSRTS:
        p_port->local_ctrl.modem_signal |= PORT_CTSRTS_ON;
        break;

    case PORT_CLR_CTSRTS:
        p_port->local_ctrl.modem_signal &= ~PORT_CTSRTS_ON;
        break;

    case PORT_SET_DTRDSR:
        p_port->local_ctrl.modem_signal |= PORT_DTRDSR_ON;
        break;

    case PORT_CLR_DTRDSR:
        p_port->local_ctrl.modem_signal &= ~PORT_DTRDSR_ON;
        break;

    case PORT_SET_RI:
        p_port->local_ctrl.modem_signal |= PORT_RING_ON;
        break;

    case PORT_CLR_RI:
        p_port->local_ctrl.modem_signal &= ~PORT_RING_ON;
        break;

    case PORT_SET_DCD:
        p_port->local_ctrl.modem_signal |= PORT_DCD_ON;
        break;

    case PORT_CLR_DCD:
        p_port->local_ctrl.modem_signal &= ~PORT_DCD_ON;
        break;
    }

    if (signal == PORT_BREAK)
        p_port->local_ctrl.break_signal = PORT_BREAK_DURATION;
    else if (p_port->local_ctrl.modem_signal == old_modem_signal)
        return (PORT_SUCCESS);

    port_start_control (p_port);

    RFCOMM_TRACE_EVENT ("PORT_Control DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d",
        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0),
        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0),
        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0),
        ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0));

    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_FlowControl
**
** Description      This function directs a specified connection to pass
**                  flow control message to the peer device.  Enable flag passed
**                  shows if port can accept more data.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  enable     - enables data flow
**
*******************************************************************************/
int PORT_FlowControl (UINT16 handle, BOOLEAN enable)
{
    tPORT      *p_port;
    BOOLEAN    old_fc;
    UINT32     events;

    RFCOMM_TRACE_API ("PORT_FlowControl() handle:%d enable: %d", handle, enable);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (!p_port->rfc.p_mcb)
    {
        return (PORT_NOT_OPENED);
    }

    p_port->rx.user_fc = !enable;

    if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT)
    {
        if (!p_port->rx.user_fc)
        {
            port_flow_control_peer(p_port, TRUE, 0);
        }
    }
    else
    {
        old_fc = p_port->local_ctrl.fc;

        /* FC is set if user is set or peer is set */
        p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);

        if (p_port->local_ctrl.fc != old_fc)
            port_start_control (p_port);
    }

    /* Need to take care of the case when we could not deliver events */
    /* to the application because we were flow controlled */
    if (enable && (p_port->rx.queue_size != 0))
    {
        events = PORT_EV_RXCHAR;
        if (p_port->rx_flag_ev_pending)
        {
            p_port->rx_flag_ev_pending = FALSE;
            events |= PORT_EV_RXFLAG;
        }

        events &= p_port->ev_mask;
        if (p_port->p_callback && events)
        {
            p_port->p_callback (events, p_port->inx);
        }
    }
    return (PORT_SUCCESS);
}
/*******************************************************************************
**
** Function         PORT_FlowControl_MaxCredit
**
** Description      This function directs a specified connection to pass
**                  flow control message to the peer device.  Enable flag passed
**                  shows if port can accept more data. It also sends max credit
**                  when data flow enabled
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  enable     - enables data flow
**
*******************************************************************************/

int PORT_FlowControl_MaxCredit (UINT16 handle, BOOLEAN enable)
{
    tPORT      *p_port;
    BOOLEAN    old_fc;
    UINT32     events;

    RFCOMM_TRACE_API ("PORT_FlowControl() handle:%d enable: %d", handle, enable);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (!p_port->rfc.p_mcb)
    {
        return (PORT_NOT_OPENED);
    }

    p_port->rx.user_fc = !enable;

    if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT)
    {
        if (!p_port->rx.user_fc)
        {
            port_flow_control_peer(p_port, TRUE, p_port->credit_rx);
        }
    }
    else
    {
        old_fc = p_port->local_ctrl.fc;

        /* FC is set if user is set or peer is set */
        p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);

        if (p_port->local_ctrl.fc != old_fc)
            port_start_control (p_port);
    }

    /* Need to take care of the case when we could not deliver events */
    /* to the application because we were flow controlled */
    if (enable && (p_port->rx.queue_size != 0))
    {
        events = PORT_EV_RXCHAR;
        if (p_port->rx_flag_ev_pending)
        {
            p_port->rx_flag_ev_pending = FALSE;
            events |= PORT_EV_RXFLAG;
        }

        events &= p_port->ev_mask;
        if (p_port->p_callback && events)
        {
            p_port->p_callback (events, p_port->inx);
        }
    }
    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_GetModemStatus
**
** Description      This function retrieves modem control signals.  Normally
**                  application will call this function after a callback
**                  function is called with notification that one of signals
**                  has been changed.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_signal   - specify the pointer to control signals info
**
*******************************************************************************/
int PORT_GetModemStatus (UINT16 handle, UINT8 *p_signal)
{
    tPORT      *p_port;

    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    *p_signal = p_port->peer_ctrl.modem_signal;

    RFCOMM_TRACE_API ("PORT_GetModemStatus() handle:%d signal:%x", handle, *p_signal);

    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_ClearError
**
** Description      This function retreives information about a communications
**                  error and reports current status of a connection.  The
**                  function should be called when an error occures to clear
**                  the connection error flag and to enable additional read
**                  and write operations.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_errors   - pointer of the variable to receive error codes
**                  p_status   - pointer to the tPORT_STATUS structur to receive
**                               connection status
**
*******************************************************************************/
int PORT_ClearError (UINT16 handle, UINT16 *p_errors, tPORT_STATUS *p_status)
{
    tPORT  *p_port;

    RFCOMM_TRACE_API ("PORT_ClearError() handle:%d", handle);

    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    *p_errors = p_port->line_status;

    /* This is the only call to clear error status.  We can not clear */
    /* connection failed status.  To clean it port should be closed and reopened */
    p_port->line_status = (p_port->line_status & LINE_STATUS_FAILED);

    PORT_GetQueueStatus (handle, p_status);
    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_SendError
**
** Description      This function send a communications error to the peer device
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  errors     - receive error codes
**
*******************************************************************************/
int PORT_SendError (UINT16 handle, UINT8 errors)
{
    tPORT      *p_port;

    RFCOMM_TRACE_API ("PORT_SendError() handle:%d errors:0x%x", handle, errors);

    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (!p_port->rfc.p_mcb)
    {
        return (PORT_NOT_OPENED);
    }

    RFCOMM_LineStatusReq (p_port->rfc.p_mcb, p_port->dlci, errors);
    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_GetQueueStatus
**
** Description      This function reports current status of a connection.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_status   - pointer to the tPORT_STATUS structur to receive
**                               connection status
**
*******************************************************************************/
int PORT_GetQueueStatus (UINT16 handle, tPORT_STATUS *p_status)
{
    tPORT      *p_port;

    /* RFCOMM_TRACE_API ("PORT_GetQueueStatus() handle:%d", handle); */

    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    p_status->in_queue_size  = (UINT16) p_port->rx.queue_size;
    p_status->out_queue_size = (UINT16) p_port->tx.queue_size;

    p_status->mtu_size = (UINT16) p_port->peer_mtu;

    p_status->flags = 0;

    if (!(p_port->peer_ctrl.modem_signal & PORT_CTSRTS_ON))
        p_status->flags |= PORT_FLAG_CTS_HOLD;

    if (!(p_port->peer_ctrl.modem_signal & PORT_DTRDSR_ON))
        p_status->flags |= PORT_FLAG_DSR_HOLD;

    if (!(p_port->peer_ctrl.modem_signal & PORT_DCD_ON))
        p_status->flags |= PORT_FLAG_RLSD_HOLD;

    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_Purge
**
** Description      This function discards all the data from the output or
**                  input queues of the specified connection.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  purge_flags - specify the action to take.
**
*******************************************************************************/
int PORT_Purge (UINT16 handle, UINT8 purge_flags)
{
    tPORT      *p_port;
    BT_HDR     *p_buf;
    UINT16      count;
    UINT32     events;

    RFCOMM_TRACE_API ("PORT_Purge() handle:%d flags:0x%x", handle, purge_flags);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (purge_flags & PORT_PURGE_RXCLEAR)
    {
        PORT_SCHEDULE_LOCK;  /* to prevent missing credit */

        count = p_port->rx.queue.count;

        while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue)) != NULL)
            GKI_freebuf (p_buf);

        p_port->rx.queue_size = 0;

        PORT_SCHEDULE_UNLOCK;

        /* If we flowed controlled peer based on rx_queue size enable data again */
        if (count)
            port_flow_control_peer (p_port, TRUE, count);
    }

    if (purge_flags & PORT_PURGE_TXCLEAR)
    {
        PORT_SCHEDULE_LOCK;  /* to prevent tx.queue_size from being negative */

        while ((p_buf = (BT_HDR *)GKI_dequeue (&p_port->tx.queue)) != NULL)
            GKI_freebuf (p_buf);

        p_port->tx.queue_size = 0;

        PORT_SCHEDULE_UNLOCK;

        events = PORT_EV_TXEMPTY;

        events |= port_flow_control_user (p_port);

        events &= p_port->ev_mask;

        if ((p_port->p_callback != NULL) && events)
            (p_port->p_callback)(events, p_port->inx);
    }

    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_ReadData
**
** Description      Normally not GKI aware application will call this function
**                  after receiving PORT_EV_RXCHAR event.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_data      - Data area
**                  max_len     - Byte count requested
**                  p_len       - Byte count received
**
*******************************************************************************/
int PORT_ReadData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
{
    tPORT      *p_port;
    BT_HDR     *p_buf;
    UINT16      count;

    RFCOMM_TRACE_API ("PORT_ReadData() handle:%d max_len:%d", handle, max_len);

    /* Initialize this in case of an error */
    *p_len = 0;

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (p_port->line_status)
    {
        return (PORT_LINE_ERR);
    }

    p_buf = (BT_HDR *)GKI_getfirst (&p_port->rx.queue);
    if (!p_buf)
        return (PORT_SUCCESS);

    count = 0;

    while (max_len && p_buf)
    {
        if (p_buf->len > max_len)
        {
            memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, max_len);
            p_buf->offset += max_len;
            p_buf->len    -= max_len;

            *p_len += max_len;

            PORT_SCHEDULE_LOCK;

            p_port->rx.queue_size -= max_len;

            PORT_SCHEDULE_UNLOCK;

            break;
        }
        else
        {
            memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);

            *p_len  += p_buf->len;
            max_len -= p_buf->len;

            PORT_SCHEDULE_LOCK;

            p_port->rx.queue_size -= p_buf->len;

            if (max_len)
            {
                p_data  += p_buf->len;
                p_buf = (BT_HDR *)GKI_getnext (p_buf);
            }

            GKI_freebuf (GKI_dequeue (&p_port->rx.queue));

            PORT_SCHEDULE_UNLOCK;

            count++;
        }
    }

    if (*p_len == 1)
    {
        RFCOMM_TRACE_EVENT ("PORT_ReadData queue:%d returned:%d %x", p_port->rx.queue_size, *p_len, (p_data[0]));
    }
    else
    {
        RFCOMM_TRACE_EVENT ("PORT_ReadData queue:%d returned:%d", p_port->rx.queue_size, *p_len);
    }

    /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
    /* check if it can be resumed now */
    port_flow_control_peer (p_port, TRUE, count);

    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_Read
**
** Description      Normally application will call this function after receiving
**                  PORT_EV_RXCHAR event.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  pp_buf      - pointer to address of buffer with data,
**
*******************************************************************************/
int PORT_Read (UINT16 handle, BT_HDR **pp_buf)
{
    tPORT      *p_port;
    BT_HDR     *p_buf;

    RFCOMM_TRACE_API ("PORT_Read() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }
    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (p_port->line_status)
    {
        return (PORT_LINE_ERR);
    }

    PORT_SCHEDULE_LOCK;

    p_buf = (BT_HDR *)GKI_dequeue (&p_port->rx.queue);
    if (p_buf)
    {
        p_port->rx.queue_size -= p_buf->len;

        PORT_SCHEDULE_UNLOCK;

        /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
        /* check if it can be resumed now */
        port_flow_control_peer (p_port, TRUE, 1);
    }
    else
    {
        PORT_SCHEDULE_UNLOCK;
    }

    *pp_buf = p_buf;
    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         port_write
**
** Description      This function when a data packet is received from the apper
**                  layer task.
**
** Parameters:      p_port     - pointer to address of port control block
**                  p_buf      - pointer to address of buffer with data,
**
*******************************************************************************/
static int port_write (tPORT *p_port, BT_HDR *p_buf)
{
    /* We should not allow to write data in to server port when connection is not opened */
    if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED))
    {
        GKI_freebuf (p_buf);
        return (PORT_CLOSED);
    }

    /* Keep the data in pending queue if peer does not allow data, or */
    /* Peer is not ready or Port is not yet opened or initial port control */
    /* command has not been sent */
    if (p_port->tx.peer_fc
     || !p_port->rfc.p_mcb
     || !p_port->rfc.p_mcb->peer_ready
     || (p_port->rfc.state != RFC_STATE_OPENED)
     || ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
                              (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)))
    {
        if ((p_port->tx.queue_size  > PORT_TX_CRITICAL_WM)
         || (p_port->tx.queue.count > PORT_TX_BUF_CRITICAL_WM))
        {
            RFCOMM_TRACE_WARNING ("PORT_Write: Queue size: %d",
                                   p_port->tx.queue_size);

            GKI_freebuf (p_buf);

            if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR))
                  p_port->p_callback (PORT_EV_ERR, p_port->inx);

            return (PORT_TX_FULL);
        }

        RFCOMM_TRACE_EVENT ("PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d ctrl_state %x",
                             p_port->tx.peer_fc,
                             (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready),
                             p_port->rfc.state,
                             p_port->port_ctrl);

        GKI_enqueue (&p_port->tx.queue, p_buf);
        p_port->tx.queue_size += p_buf->len;

        return (PORT_CMD_PENDING);
    }
    else
    {
        RFCOMM_TRACE_EVENT ("PORT_Write : Data is being sent");

        RFCOMM_DataReq (p_port->rfc.p_mcb, p_port->dlci, p_buf);
        return (PORT_SUCCESS);
    }
}

/*******************************************************************************
**
** Function         PORT_Write
**
** Description      This function when a data packet is received from the apper
**                  layer task.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  pp_buf      - pointer to address of buffer with data,
**
*******************************************************************************/
int PORT_Write (UINT16 handle, BT_HDR *p_buf)
{
    tPORT  *p_port;
    UINT32 event = 0;
    int    rc;

    RFCOMM_TRACE_API ("PORT_Write() handle:%d", handle);

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        GKI_freebuf (p_buf);
        return (PORT_BAD_HANDLE);
    }

    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        GKI_freebuf (p_buf);
        return (PORT_NOT_OPENED);
    }

    if (p_port->line_status)
    {
        RFCOMM_TRACE_WARNING ("PORT_Write: Data dropped line_status:0x%x",
                               p_port->line_status);
        GKI_freebuf (p_buf);
        return (PORT_LINE_ERR);
    }

    rc = port_write (p_port, p_buf);
    event |= port_flow_control_user (p_port);

    switch (rc)
    {
    case PORT_TX_FULL:
        event |= PORT_EV_ERR;
        break;

    case PORT_SUCCESS:
        event |= (PORT_EV_TXCHAR | PORT_EV_TXEMPTY);
        break;
    }
    /* Mask out all events that are not of interest to user */
    event &= p_port->ev_mask;

    /* Send event to the application */
    if (p_port->p_callback && event)
        (p_port->p_callback)(event, p_port->inx);

    return (PORT_SUCCESS);
}
/*******************************************************************************
**
** Function         PORT_WriteDataCO
**
** Description      Normally not GKI aware application will call this function
**                  to send data to the port by callout functions
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  fd         - socket fd
**                  p_len      - Byte count returned
**
*******************************************************************************/
int PORT_WriteDataCO (UINT16 handle, int* p_len)
{

    tPORT      *p_port;
    BT_HDR     *p_buf;
    UINT32     event = 0;
    int        rc = 0;
    UINT16     length;

    RFCOMM_TRACE_API ("PORT_WriteDataCO() handle:%d", handle);
    *p_len = 0;

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }
    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        RFCOMM_TRACE_WARNING ("PORT_WriteDataByFd() no port state:%d", p_port->state);
        return (PORT_NOT_OPENED);
    }

    if (!p_port->peer_mtu)
    {
        RFCOMM_TRACE_ERROR ("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu);
        return (PORT_UNKNOWN_ERROR);
    }
    int available = 0;
    //if(ioctl(fd, FIONREAD, &available) < 0)
    if(p_port->p_data_co_callback(handle, (UINT8*)&available, sizeof(available),
                                DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE) == FALSE)
    {
        RFCOMM_TRACE_ERROR("p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, available:%d", available);
        return (PORT_UNKNOWN_ERROR);
    }
    if(available == 0)
        return PORT_SUCCESS;
    /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */
    length = RFCOMM_DATA_POOL_BUF_SIZE -
            (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);

    /* If there are buffers scheduled for transmission check if requested */
    /* data fits into the end of the queue */
    PORT_SCHEDULE_LOCK;

    if (((p_buf = (BT_HDR *)p_port->tx.queue.p_last) != NULL)
     && (((int)p_buf->len + available) <= (int)p_port->peer_mtu)
     && (((int)p_buf->len + available) <= (int)length))
    {
        //if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, available, 0) != available)
        if(p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len,
                                    available, DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE)

        {
            error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, available:%d", available);
            PORT_SCHEDULE_UNLOCK;
            return (PORT_UNKNOWN_ERROR);
        }
        //memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
        p_port->tx.queue_size += (UINT16)available;

        *p_len = available;
        p_buf->len += (UINT16)available;

        PORT_SCHEDULE_UNLOCK;

        return (PORT_SUCCESS);
    }

    PORT_SCHEDULE_UNLOCK;

    //int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu;

    //max_read = available < max_read ? available : max_read;

    while (available)
    {
        /* if we're over buffer high water mark, we're done */
        if ((p_port->tx.queue_size  > PORT_TX_HIGH_WM)
         || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM))
        {
            port_flow_control_user(p_port);
            event |= PORT_EV_FC;
            debug("tx queue is full,tx.queue_size:%d,tx.queue.count:%d,available:%d",
                    p_port->tx.queue_size, p_port->tx.queue.count, available);
            break;
         }

        /* continue with rfcomm data write */
        p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_DATA_POOL_ID);
        if (!p_buf)
            break;

        p_buf->offset         = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
        p_buf->layer_specific = handle;

        if (p_port->peer_mtu < length)
            length = p_port->peer_mtu;
        if (available < (int)length)
            length = (UINT16)available;
        p_buf->len = length;
        p_buf->event          = BT_EVT_TO_BTU_SP_DATA;

        //memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);
        //if(recv(fd, (UINT8 *)(p_buf + 1) + p_buf->offset, (int)length, 0) != (int)length)
        if(p_port->p_data_co_callback(handle, (UINT8 *)(p_buf + 1) + p_buf->offset, length,
                                      DATA_CO_CALLBACK_TYPE_OUTGOING) == FALSE)
        {
            error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d", length);
            return (PORT_UNKNOWN_ERROR);
        }


        RFCOMM_TRACE_EVENT ("PORT_WriteData %d bytes", length);

        rc = port_write (p_port, p_buf);

        /* If queue went below the threashold need to send flow control */
        event |= port_flow_control_user (p_port);

        if (rc == PORT_SUCCESS)
            event |= PORT_EV_TXCHAR;

        if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING))
            break;

        *p_len  += length;
        available -= (int)length;
    }
    if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
        event |= PORT_EV_TXEMPTY;

    /* Mask out all events that are not of interest to user */
    event &= p_port->ev_mask;

    /* Send event to the application */
    if (p_port->p_callback && event)
        (p_port->p_callback)(event, p_port->inx);

    return (PORT_SUCCESS);
}



/*******************************************************************************
**
** Function         PORT_WriteData
**
** Description      Normally not GKI aware application will call this function
**                  to send data to the port.
**
** Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
**                  p_data      - Data area
**                  max_len     - Byte count requested
**                  p_len       - Byte count received
**
*******************************************************************************/
int PORT_WriteData (UINT16 handle, char *p_data, UINT16 max_len, UINT16 *p_len)
{
    tPORT      *p_port;
    BT_HDR     *p_buf;
    UINT32     event = 0;
    int        rc = 0;
    UINT16     length;

    RFCOMM_TRACE_API ("PORT_WriteData() max_len:%d", max_len);

    *p_len = 0;

    /* Check if handle is valid to avoid crashing */
    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }
    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        RFCOMM_TRACE_WARNING ("PORT_WriteData() no port state:%d", p_port->state);
        return (PORT_NOT_OPENED);
    }

    if (!max_len || !p_port->peer_mtu)
    {
        RFCOMM_TRACE_ERROR ("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu);
        return (PORT_UNKNOWN_ERROR);
    }

    /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len */
    length = RFCOMM_DATA_POOL_BUF_SIZE -
            (UINT16)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);

    /* If there are buffers scheduled for transmission check if requested */
    /* data fits into the end of the queue */
    PORT_SCHEDULE_LOCK;

    if (((p_buf = (BT_HDR *)p_port->tx.queue.p_last) != NULL)
     && ((p_buf->len + max_len) <= p_port->peer_mtu)
     && ((p_buf->len + max_len) <= length))
    {
        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
        p_port->tx.queue_size += max_len;

        *p_len = max_len;
        p_buf->len += max_len;

        PORT_SCHEDULE_UNLOCK;

        return (PORT_SUCCESS);
    }

    PORT_SCHEDULE_UNLOCK;

    while (max_len)
    {
        /* if we're over buffer high water mark, we're done */
        if ((p_port->tx.queue_size  > PORT_TX_HIGH_WM)
         || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM))
            break;

        /* continue with rfcomm data write */
        p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_DATA_POOL_ID);
        if (!p_buf)
            break;

        p_buf->offset         = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
        p_buf->layer_specific = handle;

        if (p_port->peer_mtu < length)
            length = p_port->peer_mtu;
        if (max_len < length)
            length = max_len;
        p_buf->len = length;
        p_buf->event          = BT_EVT_TO_BTU_SP_DATA;

        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, length);

        RFCOMM_TRACE_EVENT ("PORT_WriteData %d bytes", length);

        rc = port_write (p_port, p_buf);

        /* If queue went below the threashold need to send flow control */
        event |= port_flow_control_user (p_port);

        if (rc == PORT_SUCCESS)
            event |= PORT_EV_TXCHAR;

        if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING))
            break;

        *p_len  += length;
        max_len -= length;
        p_data  += length;

    }
    if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
        event |= PORT_EV_TXEMPTY;

    /* Mask out all events that are not of interest to user */
    event &= p_port->ev_mask;

    /* Send event to the application */
    if (p_port->p_callback && event)
        (p_port->p_callback)(event, p_port->inx);

    return (PORT_SUCCESS);
}


/*******************************************************************************
**
** Function         PORT_Test
**
** Description      Application can call this function to send RFCOMM Test frame
**
** Parameters:      handle      - Handle returned in the RFCOMM_CreateConnection
**                  p_data      - Data area
**                  max_len     - Byte count requested
**
*******************************************************************************/
int PORT_Test (UINT16 handle, UINT8 *p_data, UINT16 len)
{
    BT_HDR   *p_buf;
    tPORT    *p_port;

    RFCOMM_TRACE_API ("PORT_Test() len:%d", len);

    if ((handle == 0) || (handle > MAX_RFC_PORTS))
    {
        return (PORT_BAD_HANDLE);
    }
    p_port = &rfc_cb.port.port[handle - 1];

    if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED))
    {
        return (PORT_NOT_OPENED);
    }

    if (len > ((p_port->mtu == 0) ? RFCOMM_DEFAULT_MTU : p_port->mtu))
    {
        return (PORT_UNKNOWN_ERROR);
    }

    if ((p_buf = (BT_HDR *)GKI_getpoolbuf (RFCOMM_CMD_POOL_ID)) != NULL)
    {

        p_buf->offset  = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
        p_buf->len = len;

        memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);

        rfc_send_test (p_port->rfc.p_mcb, TRUE, p_buf);
        return (PORT_SUCCESS);
    }
    else
    {
        return (PORT_NO_MEM);
    }
}

/*******************************************************************************
**
** Function         RFCOMM_Init
**
** Description      This function is called to initialize RFCOMM layer
**
*******************************************************************************/
void RFCOMM_Init (void)
{
    memset (&rfc_cb, 0, sizeof (tRFC_CB));  /* Init RFCOMM control block */

    rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS;

#if defined(RFCOMM_INITIAL_TRACE_LEVEL)
    rfc_cb.trace_level = RFCOMM_INITIAL_TRACE_LEVEL;
#else
    rfc_cb.trace_level = BT_TRACE_LEVEL_NONE;    /* No traces */
#endif

    rfcomm_l2cap_if_init ();
}

/*******************************************************************************
**
** Function         PORT_SetTraceLevel
**
** Description      This function sets the trace level for RFCOMM. If called with
**                  a value of 0xFF, it simply reads the current trace level.
**
** Returns          the new (current) trace level
**
*******************************************************************************/
UINT8 PORT_SetTraceLevel (UINT8 new_level)
{
    if (new_level != 0xFF)
        rfc_cb.trace_level = new_level;

    return (rfc_cb.trace_level);
}

