Home | History | Annotate | Download | only in rfcomm
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 1999-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This module contains functions for port emulation entity and RFCOMM
     22  *  communications
     23  *
     24  ******************************************************************************/
     25 #include <string.h>
     26 
     27 #include "osi/include/mutex.h"
     28 
     29 #include "bt_common.h"
     30 #include "bt_target.h"
     31 #include "bt_utils.h"
     32 #include "btm_api.h"
     33 #include "btm_int.h"
     34 #include "port_api.h"
     35 #include "port_int.h"
     36 #include "rfc_int.h"
     37 #include "rfcdefs.h"
     38 
     39 /*
     40 ** Local function definitions
     41 */
     42 UINT32 port_rfc_send_tx_data (tPORT *p_port);
     43 void   port_rfc_closed (tPORT *p_port, UINT8 res);
     44 void   port_get_credits (tPORT *p_port, UINT8 k);
     45 
     46 
     47 /*******************************************************************************
     48 **
     49 ** Function         port_open_continue
     50 **
     51 ** Description      This function is called after security manager completes
     52 **                  required security checks.
     53 **
     54 ** Returns          void
     55 **
     56 *******************************************************************************/
     57 int port_open_continue (tPORT *p_port)
     58 {
     59     tRFC_MCB *p_mcb;
     60 
     61     RFCOMM_TRACE_EVENT ("port_open_continue, p_port:%p", p_port);
     62 
     63     /* Check if multiplexer channel has already been established */
     64     if ((p_mcb = rfc_alloc_multiplexer_channel (p_port->bd_addr, TRUE)) == NULL)
     65     {
     66         RFCOMM_TRACE_WARNING ("port_open_continue no mx channel");
     67         port_release_port (p_port);
     68         return (PORT_NO_RESOURCES);
     69     }
     70 
     71     p_port->rfc.p_mcb = p_mcb;
     72 
     73     p_mcb->port_inx[p_port->dlci] = p_port->inx;
     74 
     75     /* Connection is up and we know local and remote features, select MTU */
     76     port_select_mtu (p_port);
     77 
     78     if (p_mcb->state == RFC_MX_STATE_CONNECTED)
     79     {
     80         RFCOMM_ParNegReq (p_mcb, p_port->dlci, p_port->mtu);
     81     }
     82     else if ((p_mcb->state == RFC_MX_STATE_IDLE)
     83            ||(p_mcb->state == RFC_MX_STATE_DISC_WAIT_UA))
     84     {
     85         /* In RFC_MX_STATE_IDLE state, MX state machine will create connection           */
     86         /* In RFC_MX_STATE_DISC_WAIT_UA state, MX state machine will recreate connection */
     87         /*    after disconnecting is completed                                           */
     88         RFCOMM_StartReq (p_mcb);
     89     }
     90     else
     91     {
     92         /* MX state machine ignores RFC_MX_EVENT_START_REQ in these states */
     93         /* When it enters RFC_MX_STATE_CONNECTED, it will check any openning ports */
     94         RFCOMM_TRACE_DEBUG ("port_open_continue: mx state(%d) mx channel is openning", p_mcb->state);
     95     }
     96     return (PORT_SUCCESS);
     97 }
     98 
     99 
    100 /*******************************************************************************
    101 **
    102 ** Function         port_start_control
    103 **
    104 ** Description      This function is called in the BTU_TASK context to
    105 **                  send control information
    106 **
    107 ** Returns          void
    108 **
    109 *******************************************************************************/
    110 void port_start_control (tPORT *p_port)
    111 {
    112     tRFC_MCB *p_mcb = p_port->rfc.p_mcb;
    113 
    114     if (p_mcb == NULL)
    115         return;
    116 
    117     RFCOMM_ControlReq (p_mcb, p_port->dlci, &p_port->local_ctrl);
    118 }
    119 
    120 
    121 /*******************************************************************************
    122 **
    123 ** Function         port_start_par_neg
    124 **
    125 ** Description      This function is called in the BTU_TASK context to
    126 **                  send configuration information
    127 **
    128 ** Returns          void
    129 **
    130 *******************************************************************************/
    131 void port_start_par_neg (tPORT *p_port)
    132 {
    133     tRFC_MCB *p_mcb = p_port->rfc.p_mcb;
    134 
    135     if (p_mcb == NULL)
    136         return;
    137 
    138     RFCOMM_PortNegReq (p_mcb, p_port->dlci, &p_port->user_port_pars);
    139 }
    140 
    141 
    142 /*******************************************************************************
    143 **
    144 ** Function         port_start_close
    145 **
    146 ** Description      This function is called in the BTU_TASK context to
    147 **                  release DLC
    148 **
    149 ** Returns          void
    150 **
    151 *******************************************************************************/
    152 void port_start_close (tPORT *p_port)
    153 {
    154     tRFC_MCB *p_mcb = p_port->rfc.p_mcb;
    155     UINT8  old_signals;
    156     UINT32 events = 0;
    157 
    158     /* At first indicate to the user that signals on the connection were dropped */
    159     p_port->line_status |= LINE_STATUS_FAILED;
    160     old_signals = p_port->peer_ctrl.modem_signal;
    161 
    162     p_port->peer_ctrl.modem_signal &= ~(PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
    163 
    164     events |= port_get_signal_changes (p_port, old_signals, p_port->peer_ctrl.modem_signal);
    165 
    166     if(p_port->ev_mask & PORT_EV_CONNECT_ERR)
    167         events |= PORT_EV_CONNECT_ERR;
    168 
    169     if(p_port->ev_mask & PORT_EV_ERR)
    170         events |= PORT_EV_ERR;
    171 
    172     if ((p_port->p_callback != NULL) && events)
    173         p_port->p_callback (events, p_port->inx);
    174 
    175 
    176     /* Check if RFCOMM side has been closed while the message was queued */
    177     if ((p_mcb == NULL) || (p_port->rfc.state == RFC_STATE_CLOSED))
    178     {
    179         /* Call management callback function before calling port_release_port() to clear tPort */
    180         if (p_port->p_mgmt_callback)
    181             p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx);
    182 
    183         port_release_port (p_port);
    184     }
    185     else
    186     {
    187         RFCOMM_DlcReleaseReq (p_mcb, p_port->dlci);
    188     }
    189 }
    190 
    191 
    192 /*******************************************************************************
    193 **
    194 ** Function         PORT_StartCnf
    195 **
    196 ** Description      This function is called from the RFCOMM layer when
    197 **                  establishing of the multiplexer channel is completed.
    198 **                  Continue establishing of the connection for all ports that
    199 **                  are in the OPENING state
    200 **
    201 *******************************************************************************/
    202 void PORT_StartCnf (tRFC_MCB *p_mcb, UINT16 result)
    203 {
    204     tPORT   *p_port;
    205     int     i;
    206     BOOLEAN no_ports_up = TRUE;
    207 
    208     RFCOMM_TRACE_EVENT ("PORT_StartCnf result:%d", result);
    209 
    210     p_port = &rfc_cb.port.port[0];
    211     for (i = 0; i < MAX_RFC_PORTS; i++, p_port++)
    212     {
    213         if (p_port->rfc.p_mcb == p_mcb)
    214         {
    215             no_ports_up = FALSE;
    216 
    217             if (result == RFCOMM_SUCCESS)
    218                 RFCOMM_ParNegReq (p_mcb, p_port->dlci, p_port->mtu);
    219             else
    220             {
    221                 RFCOMM_TRACE_WARNING ("PORT_StartCnf failed result:%d", result);
    222 
    223                 /* Warning: result is also set to 4 when l2cap connection
    224                    fails due to l2cap connect cnf (no_resources) */
    225                 if( result == HCI_ERR_PAGE_TIMEOUT )
    226                     p_port->error = PORT_PAGE_TIMEOUT;
    227                 else
    228                     p_port->error = PORT_START_FAILED;
    229 
    230                 rfc_release_multiplexer_channel (p_mcb);
    231 
    232                 /* Send event to the application */
    233                 if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECT_ERR))
    234                     (p_port->p_callback)(PORT_EV_CONNECT_ERR, p_port->inx);
    235 
    236                 if (p_port->p_mgmt_callback)
    237                     p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx);
    238 
    239                 port_release_port (p_port);
    240             }
    241         }
    242     }
    243 
    244     /* There can be a situation when after starting connection, user closes the */
    245     /* port, we can catch it here to close multiplexor channel */
    246     if (no_ports_up)
    247     {
    248         rfc_check_mcb_active (p_mcb);
    249     }
    250 }
    251 
    252 
    253 /*******************************************************************************
    254 **
    255 ** Function         PORT_StartInd
    256 **
    257 ** Description      This function is called from the RFCOMM layer when
    258 **                  some peer device wants to establish a multiplexer
    259 **                  connection.  Check if there are any ports open with this
    260 **                  or not assigned multiplexer.
    261 **
    262 *******************************************************************************/
    263 void PORT_StartInd (tRFC_MCB *p_mcb)
    264 {
    265     tPORT *p_port;
    266     int   i;
    267 
    268     RFCOMM_TRACE_EVENT ("PORT_StartInd");
    269 
    270     p_port = &rfc_cb.port.port[0];
    271     for (i = 0; i < MAX_RFC_PORTS; i++, p_port++)
    272     {
    273         if ((p_port->rfc.p_mcb == NULL)
    274          || (p_port->rfc.p_mcb == p_mcb))
    275         {
    276             RFCOMM_TRACE_DEBUG("PORT_StartInd, RFCOMM_StartRsp RFCOMM_SUCCESS: p_mcb:%p", p_mcb);
    277             RFCOMM_StartRsp (p_mcb, RFCOMM_SUCCESS);
    278             return;
    279         }
    280     }
    281     RFCOMM_StartRsp (p_mcb, RFCOMM_ERROR);
    282 }
    283 
    284 
    285 /*******************************************************************************
    286 **
    287 ** Function         PORT_ParNegInd
    288 **
    289 ** Description      This function is called from the RFCOMM layer to change
    290 **                  DLCI parameters (currently only MTU is negotiated).
    291 **                  If can not find the port do not accept the request.
    292 **                  Otherwise save the MTU size supported by the peer.
    293 **
    294 *******************************************************************************/
    295 void PORT_ParNegInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
    296 {
    297     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    298     UINT8 our_cl;
    299     UINT8 our_k;
    300 
    301     RFCOMM_TRACE_EVENT ("PORT_ParNegInd dlci:%d mtu:%d", dlci, mtu);
    302 
    303     if (!p_port)
    304     {
    305         /* This can be a first request for this port */
    306         p_port = port_find_dlci_port (dlci);
    307         if (!p_port)
    308         {
    309             /* If the port cannot be opened, send a DM.  Per Errata 1205 */
    310             rfc_send_dm(p_mcb, dlci, FALSE);
    311             /* check if this is the last port open, some headsets have
    312             problem, they don't disconnect if we send DM */
    313             rfc_check_mcb_active( p_mcb );
    314             RFCOMM_TRACE_EVENT( "PORT_ParNegInd: port not found" );
    315             return;
    316         }
    317         p_mcb->port_inx[dlci] = p_port->inx;
    318     }
    319 
    320     memcpy (p_port->bd_addr, p_mcb->bd_addr, BD_ADDR_LEN);
    321 
    322     /* Connection is up and we know local and remote features, select MTU */
    323     port_select_mtu (p_port);
    324 
    325     p_port->rfc.p_mcb   = p_mcb;
    326     p_port->mtu         = (p_port->mtu < mtu) ? p_port->mtu : mtu;
    327     p_port->peer_mtu    = p_port->mtu;
    328 
    329     /* Negotiate the flow control mechanism.  If flow control mechanism for */
    330     /* mux has not been set yet, set it now.  If either we or peer wants TS 07.10, */
    331     /* use that.  Otherwise both must want credit based, so use that. If flow is */
    332     /* already defined for this mux, we respond with that value. */
    333     if (p_mcb->flow == PORT_FC_UNDEFINED)
    334     {
    335         if ((PORT_FC_DEFAULT == PORT_FC_TS710) || (cl == RFCOMM_PN_CONV_LAYER_TYPE_1))
    336         {
    337             p_mcb->flow = PORT_FC_TS710;
    338         }
    339         else
    340         {
    341             p_mcb->flow = PORT_FC_CREDIT;
    342         }
    343     }
    344 
    345     /* Regardless of our flow control mechanism, if the PN cl is zero, we must */
    346     /* respond with zero.  "A responding implementation must set this field to 14 */
    347     /* if (and only if) the PN request was 15."  This could happen if a PN is sent */
    348     /* after the DLCI is already established-- the PN in that case must have cl = 0. */
    349     /* See RFCOMM spec 5.5.3 */
    350     if (cl == RFCOMM_PN_CONV_LAYER_TYPE_1)
    351     {
    352         our_cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
    353         our_k = 0;
    354     }
    355     else if (p_mcb->flow == PORT_FC_CREDIT)
    356     {
    357         /* get credits */
    358         port_get_credits (p_port, k);
    359 
    360         /* Set convergence layer and number of credits (k) */
    361         our_cl = RFCOMM_PN_CONV_LAYER_CBFC_R;
    362         our_k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max : RFCOMM_K_MAX;
    363         p_port->credit_rx = our_k;
    364     }
    365     else
    366     {
    367         /* must not be using credit based flow control; use TS 7.10 */
    368         our_cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
    369         our_k = 0;
    370     }
    371     RFCOMM_ParNegRsp (p_mcb, dlci, p_port->mtu, our_cl, our_k);
    372 }
    373 
    374 
    375 /*******************************************************************************
    376 **
    377 ** Function         PORT_ParNegCnf
    378 **
    379 ** Description      This function is called from the RFCOMM layer to change
    380 **                  DLCI parameters (currently only MTU is negotiated).
    381 **                  Save the MTU size supported by the peer.
    382 **                  If the confirmation is received during the port opening
    383 **                  procedure send EstablishRequest to continue.
    384 **
    385 *******************************************************************************/
    386 void PORT_ParNegCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
    387 {
    388     tPORT   *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    389 
    390     RFCOMM_TRACE_EVENT ("PORT_ParNegCnf dlci:%d mtu:%d cl: %d k: %d", dlci, mtu, cl, k);
    391 
    392     if (!p_port)
    393         return;
    394 
    395     /* Flow control mechanism not set yet.  Negotiate flow control mechanism. */
    396     if (p_mcb->flow == PORT_FC_UNDEFINED)
    397     {
    398         /* Our stack is configured for TS07.10 and they responded with credit-based. */
    399         /* This is illegal-- negotiation fails. */
    400         if ((PORT_FC_DEFAULT == PORT_FC_TS710) && (cl == RFCOMM_PN_CONV_LAYER_CBFC_R))
    401         {
    402             rfc_send_disc (p_mcb, p_port->dlci);
    403             rfc_port_closed (p_port);
    404             return;
    405         }
    406         /* Our stack is configured for credit-based and they responded with credit-based. */
    407         else if (cl == RFCOMM_PN_CONV_LAYER_CBFC_R)
    408         {
    409             p_mcb->flow = PORT_FC_CREDIT;
    410         }
    411         /* They responded with any other value.  Treat this as negotiation to TS07.10. */
    412         else
    413         {
    414             p_mcb->flow = PORT_FC_TS710;
    415         }
    416     }
    417     /* If mux flow control mechanism set, we honor that setting regardless of */
    418     /* the CL value in their response.  This allows us to gracefully accept any */
    419     /* illegal PN negotiation scenarios. */
    420 
    421     p_port->mtu         = (p_port->mtu < mtu) ? p_port->mtu : mtu;
    422     p_port->peer_mtu    = p_port->mtu;
    423 
    424     if (p_mcb->flow == PORT_FC_CREDIT)
    425     {
    426         port_get_credits (p_port, k);
    427     }
    428 
    429     if (p_port->state == PORT_STATE_OPENING)
    430         RFCOMM_DlcEstablishReq (p_mcb, p_port->dlci, p_port->mtu);
    431 }
    432 
    433 
    434 /*******************************************************************************
    435 **
    436 ** Function         PORT_DlcEstablishInd
    437 **
    438 ** Description      This function is called from the RFCOMM layer when peer
    439 **                  device wants to establish a new DLC.  If this is not the
    440 **                  first message in the establishment procedure port_handle
    441 **                  has a handle to the port control block otherwise the control
    442 **                  block should be found based on the muliplexer channel and
    443 **                  dlci.  The block should be allocated allocated before
    444 **                  meaning that application already made open.
    445 **
    446 *******************************************************************************/
    447 void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
    448 {
    449     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    450 
    451     RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci, mtu, p_port);
    452     RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb addr:%02x:%02x:%02x:%02x:%02x:%02x",
    453                          p_mcb->bd_addr[0], p_mcb->bd_addr[1], p_mcb->bd_addr[2],
    454                          p_mcb->bd_addr[3], p_mcb->bd_addr[4], p_mcb->bd_addr[5]);
    455 
    456     if (!p_port)
    457     {
    458         /* This can be a first request for this port */
    459         p_port = port_find_dlci_port (dlci);
    460         if (!p_port)
    461         {
    462             RFCOMM_DlcEstablishRsp (p_mcb, dlci, 0, RFCOMM_ERROR);
    463             return;
    464         }
    465         p_mcb->port_inx[dlci] = p_port->inx;
    466     }
    467 
    468     /* If L2CAP's mtu less then RFCOMM's take it */
    469     if (mtu && (mtu < p_port->peer_mtu))
    470         p_port->peer_mtu = mtu;
    471 
    472     /* If there was an inactivity timer running for MCB stop it */
    473     rfc_timer_stop (p_mcb);
    474 
    475     RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS);
    476 
    477     /* This is the server side.  If application wants to know when connection */
    478     /* is established, thats the place */
    479     if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECTED))
    480         (p_port->p_callback)(PORT_EV_CONNECTED, p_port->inx);
    481 
    482     if (p_port->p_mgmt_callback)
    483         p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx);
    484 
    485     p_port->state = PORT_STATE_OPENED;
    486 }
    487 
    488 
    489 /*******************************************************************************
    490 **
    491 ** Function         PORT_DlcEstablishCnf
    492 **
    493 ** Description      This function is called from the RFCOMM layer when peer
    494 **                  acknowledges establish procedure (SABME/UA).  Send reply
    495 **                  to the user and set state to OPENED if result was
    496 **                  successfull.
    497 **
    498 *******************************************************************************/
    499 void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
    500 {
    501     tPORT  *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    502 
    503     RFCOMM_TRACE_EVENT ("PORT_DlcEstablishCnf dlci:%d mtu:%d result:%d", dlci, mtu, result);
    504 
    505     if (!p_port)
    506         return;
    507 
    508     if (result != RFCOMM_SUCCESS)
    509     {
    510         p_port->error = PORT_START_FAILED;
    511         port_rfc_closed (p_port, PORT_START_FAILED);
    512         return;
    513     }
    514 
    515     /* If L2CAP's mtu less then RFCOMM's take it */
    516     if (mtu && (mtu < p_port->peer_mtu))
    517         p_port->peer_mtu = mtu;
    518 
    519     /* If there was an inactivity timer running for MCB stop it */
    520     rfc_timer_stop (p_mcb);
    521 
    522     if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECTED))
    523         (p_port->p_callback)(PORT_EV_CONNECTED, p_port->inx);
    524 
    525     if (p_port->p_mgmt_callback)
    526         p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx);
    527 
    528     p_port->state = PORT_STATE_OPENED;
    529 
    530     /* RPN is required only if we want to tell DTE how the port should be opened */
    531     if ((p_port->uuid == UUID_SERVCLASS_DIALUP_NETWORKING)
    532      || (p_port->uuid == UUID_SERVCLASS_FAX))
    533         RFCOMM_PortNegReq (p_port->rfc.p_mcb, p_port->dlci, NULL);
    534     else
    535         RFCOMM_ControlReq (p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl);
    536 }
    537 
    538 
    539 /*******************************************************************************
    540 **
    541 ** Function         PORT_PortNegInd
    542 **
    543 ** Description      This function is called from the RFCOMM layer when peer
    544 **                  device wants to set parameters of the port.  As per the spec
    545 **                  this message has to be sent before the first data packet
    546 **                  and can be sent before establish.  The block should be
    547 **                  allocated before meaning that application already made open.
    548 **
    549 *******************************************************************************/
    550 void PORT_PortNegInd (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars,
    551                       UINT16 param_mask)
    552 {
    553     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    554 
    555     RFCOMM_TRACE_EVENT ("PORT_PortNegInd");
    556 
    557     if (!p_port)
    558     {
    559         /* This can be a first request for this port */
    560         p_port = port_find_dlci_port (dlci);
    561         if (!p_port)
    562         {
    563             RFCOMM_PortNegRsp (p_mcb, dlci, p_pars, 0);
    564             return;
    565         }
    566         p_mcb->port_inx[dlci] = p_port->inx;
    567     }
    568 
    569     /* Check if the flow control is acceptable on local side */
    570     p_port->peer_port_pars = *p_pars;
    571     RFCOMM_PortNegRsp (p_mcb, dlci, p_pars, param_mask);
    572 }
    573 
    574 
    575 /*******************************************************************************
    576 **
    577 ** Function         PORT_PortNegCnf
    578 **
    579 ** Description      This function is called from the RFCOMM layer to change
    580 **                  state for the port.  Propagate change to the user.
    581 **
    582 *******************************************************************************/
    583 void PORT_PortNegCnf (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars, UINT16 result)
    584 {
    585     tPORT  *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    586     UNUSED(p_pars);
    587 
    588     RFCOMM_TRACE_EVENT ("PORT_PortNegCnf");
    589 
    590     if (!p_port)
    591     {
    592         RFCOMM_TRACE_WARNING ("PORT_PortNegCnf no port");
    593         return;
    594     }
    595     /* Port negotiation failed. Drop the connection */
    596     if (result != RFCOMM_SUCCESS)
    597     {
    598         p_port->error = PORT_PORT_NEG_FAILED;
    599 
    600         RFCOMM_DlcReleaseReq (p_mcb, p_port->dlci);
    601 
    602         port_rfc_closed (p_port, PORT_PORT_NEG_FAILED);
    603         return;
    604     }
    605 
    606     if (!(p_port->port_ctrl & PORT_CTRL_REQ_SENT))
    607     {
    608         RFCOMM_ControlReq (p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl);
    609     }
    610     else
    611     {
    612         RFCOMM_TRACE_WARNING ("PORT_PortNegCnf Control Already sent");
    613     }
    614 }
    615 
    616 
    617 /*******************************************************************************
    618 **
    619 ** Function         PORT_ControlInd
    620 **
    621 ** Description      This function is called from the RFCOMM layer on the modem
    622 **                  signal change.  Propagate change to the user.
    623 **
    624 *******************************************************************************/
    625 void PORT_ControlInd (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars)
    626 {
    627     tPORT  *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    628     UINT32 event;
    629     UINT8  old_signals;
    630 
    631     RFCOMM_TRACE_EVENT ("PORT_ControlInd");
    632 
    633     if (!p_port)
    634         return;
    635 
    636     old_signals = p_port->peer_ctrl.modem_signal;
    637 
    638     event = port_get_signal_changes (p_port, old_signals, p_pars->modem_signal);
    639 
    640     p_port->peer_ctrl = *p_pars;
    641 
    642     if (!(p_port->port_ctrl & PORT_CTRL_REQ_SENT))
    643         RFCOMM_ControlReq (p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl);
    644     else
    645     {
    646         /* If this is the first time we received control RFCOMM is connected */
    647         if (!(p_port->port_ctrl & PORT_CTRL_IND_RECEIVED))
    648         {
    649             event |= (PORT_EV_CONNECTED & p_port->ev_mask);
    650         }
    651 
    652         if (p_port->port_ctrl & PORT_CTRL_REQ_CONFIRMED)
    653         {
    654             event |= port_rfc_send_tx_data(p_port);
    655         }
    656     }
    657 
    658     p_port->port_ctrl |= (PORT_CTRL_IND_RECEIVED | PORT_CTRL_IND_RESPONDED);
    659 
    660     if (p_pars->break_signal)
    661         event |= (PORT_EV_BREAK & p_port->ev_mask);
    662 
    663     /* execute call back function only if the application is registered for events */
    664     if (event && p_port->p_callback)
    665         (p_port->p_callback)(event, p_port->inx);
    666 
    667     RFCOMM_TRACE_EVENT ("PORT_ControlInd DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d",
    668         ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0),
    669         ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0),
    670         ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0),
    671         ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0));
    672 
    673 }
    674 
    675 
    676 /*******************************************************************************
    677 **
    678 ** Function         PORT_ControlCnf
    679 **
    680 ** Description      This function is called from the RFCOMM layer when
    681 **                  peer acknowleges change of the modem signals.
    682 **
    683 *******************************************************************************/
    684 void PORT_ControlCnf (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars)
    685 {
    686     tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    687     UINT32 event = 0;
    688     UNUSED(p_pars);
    689 
    690     RFCOMM_TRACE_EVENT ("PORT_ControlCnf");
    691 
    692     if (!p_port)
    693         return;
    694 
    695     if (!(p_port->port_ctrl & PORT_CTRL_REQ_CONFIRMED))
    696     {
    697         p_port->port_ctrl |= PORT_CTRL_REQ_CONFIRMED;
    698 
    699         if (p_port->port_ctrl & PORT_CTRL_IND_RECEIVED)
    700             event = (p_port->ev_mask & PORT_EV_CONNECTED);
    701     }
    702 
    703     if (p_port->port_ctrl & PORT_CTRL_IND_RECEIVED)
    704     {
    705         event |= port_rfc_send_tx_data(p_port);
    706     }
    707 
    708     /* execute call back function only if the application is registered for events */
    709     if (event && p_port->p_callback)
    710         (p_port->p_callback)(event, p_port->inx);
    711 }
    712 
    713 
    714 /*******************************************************************************
    715 **
    716 ** Function         PORT_LineStatusInd
    717 **
    718 ** Description      This function is called from the RFCOMM layer when
    719 **                  peer indicates change in the line status
    720 **
    721 *******************************************************************************/
    722 void PORT_LineStatusInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 line_status)
    723 {
    724     tPORT  *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    725     UINT32 event = 0;
    726 
    727     RFCOMM_TRACE_EVENT ("PORT_LineStatusInd");
    728 
    729     if (!p_port)
    730         return;
    731 
    732     p_port->line_status |= line_status;
    733 
    734     if (line_status & PORT_ERR_OVERRUN)
    735         event |= PORT_EV_OVERRUN;
    736 
    737     if (line_status & PORT_ERR_BREAK)
    738         event |= PORT_EV_BREAK;
    739 
    740     if (line_status & ~(PORT_ERR_OVERRUN | PORT_ERR_BREAK))
    741         event |= PORT_EV_ERR;
    742 
    743     if ((p_port->p_callback != NULL) && (p_port->ev_mask & event))
    744           p_port->p_callback ((p_port->ev_mask & event), p_port->inx);
    745 }
    746 
    747 
    748 /*******************************************************************************
    749 **
    750 ** Function         PORT_DlcReleaseInd
    751 **
    752 ** Description      This function is called from the RFCOMM layer when
    753 **                  DLC connection is released.
    754 **
    755 *******************************************************************************/
    756 void PORT_DlcReleaseInd (tRFC_MCB *p_mcb, UINT8 dlci)
    757 {
    758     tPORT  *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    759 
    760     RFCOMM_TRACE_EVENT ("PORT_DlcReleaseInd");
    761 
    762     if (!p_port)
    763         return;
    764 
    765     port_rfc_closed (p_port, PORT_CLOSED);
    766 }
    767 
    768 
    769 /*******************************************************************************
    770 **
    771 ** Function         PORT_CloseInd
    772 **
    773 ** Description      This function is called from the RFCOMM layer when
    774 **                  multiplexer connection is released.
    775 **
    776 *******************************************************************************/
    777 void PORT_CloseInd (tRFC_MCB *p_mcb)
    778 {
    779     tPORT  *p_port;
    780     int    i;
    781 
    782     RFCOMM_TRACE_EVENT ("PORT_CloseInd");
    783 
    784     p_port = &rfc_cb.port.port[0];
    785     for (i = 0; i < MAX_RFC_PORTS; i++, p_port++)
    786     {
    787         if (p_port->rfc.p_mcb == p_mcb)
    788         {
    789             port_rfc_closed (p_port, PORT_PEER_CONNECTION_FAILED);
    790         }
    791     }
    792     rfc_release_multiplexer_channel (p_mcb);
    793 }
    794 
    795 /*******************************************************************************
    796 **
    797 ** Function         Port_TimeOutCloseMux
    798 **
    799 ** Description      This function is called when RFCOMM timesout on a command
    800 **                  as a result multiplexer connection is closed.
    801 **
    802 *******************************************************************************/
    803 void Port_TimeOutCloseMux (tRFC_MCB *p_mcb)
    804 {
    805     tPORT  *p_port;
    806     int    i;
    807 
    808     RFCOMM_TRACE_EVENT ("Port_TimeOutCloseMux");
    809 
    810     p_port = &rfc_cb.port.port[0];
    811     for (i = 0; i < MAX_RFC_PORTS; i++, p_port++)
    812     {
    813         if (p_port->rfc.p_mcb == p_mcb)
    814         {
    815             port_rfc_closed (p_port, PORT_PEER_TIMEOUT);
    816         }
    817     }
    818 }
    819 
    820 
    821 /*******************************************************************************
    822 **
    823 ** Function         PORT_DataInd
    824 **
    825 ** Description      This function is called from the RFCOMM layer when data
    826 **                  buffer is received from the peer.
    827 **
    828 *******************************************************************************/
    829 void PORT_DataInd (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
    830 {
    831     tPORT  *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
    832     UINT8  rx_char1;
    833     UINT32 events = 0;
    834     UINT8  *p;
    835     int    i;
    836 
    837     RFCOMM_TRACE_EVENT("PORT_DataInd with data length %d, p_mcb:%p,p_port:%p,dlci:%d",
    838                         p_buf->len, p_mcb, p_port, dlci);
    839     if (!p_port)
    840     {
    841         osi_free(p_buf);
    842         return;
    843     }
    844     /* If client registered callout callback with flow control we can just deliver receive data */
    845     if (p_port->p_data_co_callback)
    846     {
    847         /* Another packet is delivered to user.  Send credits to peer if required */
    848 
    849         if(p_port->p_data_co_callback(p_port->inx, (UINT8*)p_buf, -1, DATA_CO_CALLBACK_TYPE_INCOMING))
    850             port_flow_control_peer(p_port, TRUE, 1);
    851         else port_flow_control_peer(p_port, FALSE, 0);
    852         //osi_free(p_buf);
    853         return;
    854     }
    855     else RFCOMM_TRACE_ERROR("PORT_DataInd, p_port:%p, p_data_co_callback is null", p_port);
    856     /* If client registered callback we can just deliver receive data */
    857     if (p_port->p_data_callback)
    858     {
    859         /* Another packet is delivered to user.  Send credits to peer if required */
    860         port_flow_control_peer(p_port, TRUE, 1);
    861 
    862         p_port->p_data_callback (p_port->inx, (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
    863         osi_free(p_buf);
    864         return;
    865     }
    866 
    867     /* Check if rx queue exceeds the limit */
    868     if ((p_port->rx.queue_size + p_buf->len > PORT_RX_CRITICAL_WM)
    869      || (fixed_queue_length(p_port->rx.queue) + 1 > p_port->rx_buf_critical))
    870     {
    871         RFCOMM_TRACE_EVENT ("PORT_DataInd. Buffer over run. Dropping the buffer");
    872         osi_free(p_buf);
    873 
    874         RFCOMM_LineStatusReq (p_mcb, dlci, LINE_STATUS_OVERRUN);
    875         return;
    876     }
    877 
    878     /* If user registered to receive notification when a particular byte is */
    879     /* received we mast check all received bytes */
    880     if (((rx_char1 = p_port->user_port_pars.rx_char1) != 0)
    881      && (p_port->ev_mask & PORT_EV_RXFLAG))
    882     {
    883         for (i = 0, p = (UINT8 *)(p_buf + 1) + p_buf->offset; i < p_buf->len; i++)
    884         {
    885             if (*p++ == rx_char1)
    886             {
    887                 events |= PORT_EV_RXFLAG;
    888                 break;
    889             }
    890         }
    891     }
    892 
    893     mutex_global_lock();
    894 
    895     fixed_queue_enqueue(p_port->rx.queue, p_buf);
    896     p_port->rx.queue_size += p_buf->len;
    897 
    898     mutex_global_unlock();
    899 
    900     /* perform flow control procedures if necessary */
    901     port_flow_control_peer(p_port, FALSE, 0);
    902 
    903     /* If user indicated flow control can not deliver any notifications to him */
    904     if (p_port->rx.user_fc)
    905     {
    906         if (events & PORT_EV_RXFLAG)
    907             p_port->rx_flag_ev_pending = TRUE;
    908 
    909         return;
    910     }
    911 
    912     events |= PORT_EV_RXCHAR;
    913 
    914     /* Mask out all events that are not of interest to user */
    915     events &= p_port->ev_mask;
    916 
    917     if (p_port->p_callback && events)
    918         p_port->p_callback (events, p_port->inx);
    919 }
    920 
    921 
    922 /*******************************************************************************
    923 **
    924 ** Function         PORT_FlowInd
    925 **
    926 ** Description      This function is called from the RFCOMM layer on the flow
    927 **                  control signal change.  Propagate change to the user.
    928 **
    929 *******************************************************************************/
    930 void PORT_FlowInd (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN enable_data)
    931 {
    932     tPORT  *p_port = (tPORT *)NULL;
    933     UINT32 events = 0;
    934     int    i;
    935 
    936     RFCOMM_TRACE_EVENT ("PORT_FlowInd fc:%d", enable_data);
    937 
    938     if (dlci == 0)
    939     {
    940         p_mcb->peer_ready = enable_data;
    941     }
    942     else
    943     {
    944         if ((p_port = port_find_mcb_dlci_port (p_mcb, dlci)) == NULL)
    945             return;
    946 
    947         p_port->tx.peer_fc = !enable_data;
    948     }
    949 
    950     for (i = 0; i < MAX_RFC_PORTS; i++)
    951     {
    952         /* If DLCI is 0 event applies to all ports */
    953         if (dlci == 0)
    954         {
    955             p_port = &rfc_cb.port.port[i];
    956             if (!p_port->in_use
    957              || (p_port->rfc.p_mcb != p_mcb)
    958              || (p_port->rfc.state != RFC_STATE_OPENED))
    959                 continue;
    960         }
    961         events = 0;
    962 
    963         /* Check if flow of data is still enabled */
    964         events |= port_flow_control_user (p_port);
    965 
    966         /* Check if data can be sent and send it */
    967         events |= port_rfc_send_tx_data (p_port);
    968 
    969         /* Mask out all events that are not of interest to user */
    970         events &= p_port->ev_mask;
    971 
    972         /* Send event to the application */
    973         if (p_port->p_callback && events)
    974             (p_port->p_callback)(events, p_port->inx);
    975 
    976         /* If DLCI is not 0 event applies to one port only */
    977         if (dlci != 0)
    978             break;
    979     }
    980 }
    981 
    982 
    983 /*******************************************************************************
    984 **
    985 ** Function         port_rfc_send_tx_data
    986 **
    987 ** Description      This function is when forward data can be sent to the peer
    988 **
    989 *******************************************************************************/
    990 UINT32 port_rfc_send_tx_data (tPORT *p_port)
    991 {
    992     UINT32 events = 0;
    993     BT_HDR *p_buf;
    994 
    995     /* if there is data to be sent */
    996     if (p_port->tx.queue_size > 0)
    997     {
    998         /* while the rfcomm peer is not flow controlling us, and peer is ready */
    999         while (!p_port->tx.peer_fc && p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready)
   1000         {
   1001             /* get data from tx queue and send it */
   1002             mutex_global_lock();
   1003 
   1004             if ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_port->tx.queue)) != NULL)
   1005             {
   1006                 p_port->tx.queue_size -= p_buf->len;
   1007 
   1008                 mutex_global_unlock();
   1009 
   1010                 RFCOMM_TRACE_DEBUG ("Sending RFCOMM_DataReq tx.queue_size=%d", p_port->tx.queue_size);
   1011 
   1012                 RFCOMM_DataReq (p_port->rfc.p_mcb, p_port->dlci, p_buf);
   1013 
   1014                 events |= PORT_EV_TXCHAR;
   1015 
   1016                 if (p_port->tx.queue_size == 0)
   1017                 {
   1018                     events |= PORT_EV_TXEMPTY;
   1019                     break;
   1020                 }
   1021             }
   1022             /* queue is empty-- all data sent */
   1023             else
   1024             {
   1025                 mutex_global_unlock();
   1026 
   1027                 events |= PORT_EV_TXEMPTY;
   1028                 break;
   1029             }
   1030         }
   1031         /* If we flow controlled user based on the queue size enable data again */
   1032         events |= port_flow_control_user (p_port);
   1033     }
   1034     return (events & p_port->ev_mask);
   1035 }
   1036 
   1037 
   1038 /*******************************************************************************
   1039 **
   1040 ** Function         port_rfc_closed
   1041 **
   1042 ** Description      This function when RFCOMM side of port is closed
   1043 **
   1044 *******************************************************************************/
   1045 void port_rfc_closed (tPORT *p_port, UINT8 res)
   1046 {
   1047     UINT8     old_signals;
   1048     UINT32    events = 0;
   1049     tRFC_MCB *p_mcb = p_port->rfc.p_mcb;
   1050 
   1051     if ((p_port->state == PORT_STATE_OPENING) && (p_port->is_server))
   1052     {
   1053         /* The servr side has not been informed that connection is up, ignore */
   1054         RFCOMM_TRACE_EVENT ("port_rfc_closed in OPENING state ignored");
   1055 
   1056         rfc_port_timer_stop (p_port);
   1057         p_port->rfc.state = RFC_STATE_CLOSED;
   1058 
   1059         if (p_mcb)
   1060         {
   1061             p_mcb->port_inx[p_port->dlci] = 0;
   1062 
   1063             /* If there are no more ports opened on this MCB release it */
   1064             rfc_check_mcb_active (p_mcb);
   1065             p_port->rfc.p_mcb = NULL;
   1066         }
   1067 
   1068         /* Need to restore DLCI to listening state
   1069          * if the server was on the initiating RFC
   1070          */
   1071         p_port->dlci &= 0xfe;
   1072 
   1073         return;
   1074     }
   1075 
   1076     if ((p_port->state != PORT_STATE_CLOSING) && (p_port->state != PORT_STATE_CLOSED))
   1077     {
   1078         p_port->line_status |= LINE_STATUS_FAILED;
   1079 
   1080         old_signals = p_port->peer_ctrl.modem_signal;
   1081 
   1082         p_port->peer_ctrl.modem_signal &= ~(PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
   1083 
   1084         events |= port_get_signal_changes (p_port, old_signals, p_port->peer_ctrl.modem_signal);
   1085 
   1086         if(p_port->ev_mask & PORT_EV_CONNECT_ERR)
   1087             events |= PORT_EV_CONNECT_ERR;
   1088     }
   1089     RFCOMM_TRACE_EVENT ("port_rfc_closed state:%d sending events:%x", p_port->state, events);
   1090 
   1091     if ((p_port->p_callback != NULL) && events)
   1092         p_port->p_callback (events, p_port->inx);
   1093 
   1094     if (p_port->p_mgmt_callback)
   1095         p_port->p_mgmt_callback (res, p_port->inx);
   1096 
   1097     p_port->rfc.state = RFC_STATE_CLOSED;
   1098 
   1099     RFCOMM_TRACE_WARNING ("%s RFCOMM connection in state %d closed: %s (res: %d)",
   1100                           __func__, p_port->state, PORT_GetResultString(res), res);
   1101 
   1102     port_release_port (p_port);
   1103 }
   1104 
   1105 
   1106 /*******************************************************************************
   1107 **
   1108 ** Function         port_get_credits
   1109 **
   1110 ** Description      Set initial values for credits.
   1111 **                  Adjust max number of rx credits based on negotiated MTU.
   1112 **                  Check max allowed num of bytes, max allowed num buffers,
   1113 **                  should be less then 255
   1114 **
   1115 *******************************************************************************/
   1116 void port_get_credits (tPORT *p_port, UINT8 k)
   1117 {
   1118     p_port->credit_tx = k;
   1119     if (p_port->credit_tx == 0)
   1120         p_port->tx.peer_fc = TRUE;
   1121 }
   1122