/******************************************************************************* ** ** Function port_open_continue ** ** Description This function is called after security manager completes ** required security checks. ** ** Returns void ** *******************************************************************************/ int port_open_continue (tPORT *p_port) { tRFC_MCB *p_mcb; RFCOMM_TRACE_EVENT ("port_open_continue, p_port:%p", p_port); /* Check if multiplexer channel has already been established */ if ((p_mcb = rfc_alloc_multiplexer_channel (p_port->bd_addr, TRUE)) == NULL) { RFCOMM_TRACE_WARNING ("port_open_continue no mx channel"); port_release_port (p_port); return (PORT_NO_RESOURCES); } p_port->rfc.p_mcb = p_mcb; p_mcb->port_inx[p_port->dlci] = p_port->inx; /* Connection is up and we know local and remote features, select MTU */ port_select_mtu (p_port); if (p_mcb->state == RFC_MX_STATE_CONNECTED) { RFCOMM_ParNegReq (p_mcb, p_port->dlci, p_port->mtu); } else if ((p_mcb->state == RFC_MX_STATE_IDLE) || (p_mcb->state == RFC_MX_STATE_DISC_WAIT_UA)) { /* In RFC_MX_STATE_IDLE state, MX state machine will create connection */ /* In RFC_MX_STATE_DISC_WAIT_UA state, MX state machine will recreate connection */ /* after disconnecting is completed */ RFCOMM_StartReq (p_mcb); } else { /* MX state machine ignores RFC_MX_EVENT_START_REQ in these states */ /* When it enters RFC_MX_STATE_CONNECTED, it will check any openning ports */ RFCOMM_TRACE_DEBUG ("port_open_continue: mx state(%d) mx channel is openning", p_mcb->state); } return (PORT_SUCCESS); }
/******************************************************************************* ** ** Function RFCOMM_ConnectInd ** ** Description This is a callback function called by L2CAP when ** L2CA_ConnectInd received. Allocate multiplexer control block ** and dispatch the event to it. ** *******************************************************************************/ void RFCOMM_ConnectInd (BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UINT8 id) { tRFC_MCB *p_mcb = rfc_alloc_multiplexer_channel(bd_addr, FALSE); UNUSED(psm); if ((p_mcb)&&(p_mcb->state != RFC_MX_STATE_IDLE)) { /* if this is collision case */ if ((p_mcb->is_initiator)&&(p_mcb->state == RFC_MX_STATE_WAIT_CONN_CNF)) { p_mcb->pending_lcid = lcid; p_mcb->pending_id = id; /* wait random timeout (2 - 12) to resolve collision */ /* if peer gives up then local device rejects incoming connection and continues as initiator */ /* if timeout, local device disconnects outgoing connection and continues as acceptor */ RFCOMM_TRACE_DEBUG ("RFCOMM_ConnectInd start timer for collision, initiator's LCID(0x%x), acceptor's LCID(0x%x)", p_mcb->lcid, p_mcb->pending_lcid); rfc_timer_start(p_mcb, (UINT16)(GKI_get_tick_count()%10 + 2)); return; } else { /* we cannot accept connection request from peer at this state */ /* don't update lcid */ p_mcb = NULL; } } else { /* store mcb even if null */ rfc_save_lcid_mcb (p_mcb, lcid); } if (p_mcb == NULL) { L2CA_ConnectRsp (bd_addr, id, lcid, L2CAP_CONN_NO_RESOURCES, 0); return; } p_mcb->lcid = lcid; rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_CONN_IND, &id); }