/******************************************************************************* ** ** Function PORT_PortNegCnf ** ** Description This function is called from the RFCOMM layer to change ** state for the port. Propagate change to the user. ** *******************************************************************************/ void PORT_PortNegCnf (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars, UINT16 result) { tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); UNUSED(p_pars); RFCOMM_TRACE_EVENT ("PORT_PortNegCnf"); if (!p_port) { RFCOMM_TRACE_WARNING ("PORT_PortNegCnf no port"); return; } /* Port negotiation failed. Drop the connection */ if (result != RFCOMM_SUCCESS) { p_port->error = PORT_PORT_NEG_FAILED; RFCOMM_DlcReleaseReq (p_mcb, p_port->dlci); port_rfc_closed (p_port, PORT_PORT_NEG_FAILED); return; } if (!(p_port->port_ctrl & PORT_CTRL_REQ_SENT)) { RFCOMM_ControlReq (p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl); } else { RFCOMM_TRACE_WARNING ("PORT_PortNegCnf Control Already sent"); } }
/******************************************************************************* ** ** Function PORT_DlcReleaseInd ** ** Description This function is called from the RFCOMM layer when ** DLC connection is released. ** *******************************************************************************/ void PORT_DlcReleaseInd (tRFC_MCB *p_mcb, UINT8 dlci) { tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); RFCOMM_TRACE_EVENT ("PORT_DlcReleaseInd"); if (!p_port) return; port_rfc_closed (p_port, PORT_CLOSED); }
/******************************************************************************* ** ** Function Port_TimeOutCloseMux ** ** Description This function is called when RFCOMM timesout on a command ** as a result multiplexer connection is closed. ** *******************************************************************************/ void Port_TimeOutCloseMux (tRFC_MCB *p_mcb) { tPORT *p_port; int i; RFCOMM_TRACE_EVENT ("Port_TimeOutCloseMux"); p_port = &rfc_cb.port.port[0]; for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) { if (p_port->rfc.p_mcb == p_mcb) { port_rfc_closed (p_port, PORT_PEER_TIMEOUT); } } }
/******************************************************************************* ** ** Function PORT_CloseInd ** ** Description This function is called from the RFCOMM layer when ** multiplexer connection is released. ** *******************************************************************************/ void PORT_CloseInd (tRFC_MCB *p_mcb) { tPORT *p_port; int i; RFCOMM_TRACE_EVENT ("PORT_CloseInd"); p_port = &rfc_cb.port.port[0]; for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) { if (p_port->rfc.p_mcb == p_mcb) { port_rfc_closed (p_port, PORT_PEER_CONNECTION_FAILED); } } rfc_release_multiplexer_channel (p_mcb); }
/******************************************************************************* ** ** Function PORT_DlcEstablishCnf ** ** Description This function is called from the RFCOMM layer when peer ** acknowledges establish procedure (SABME/UA). Send reply ** to the user and set state to OPENED if result was ** successfull. ** *******************************************************************************/ void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result) { tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); RFCOMM_TRACE_EVENT ("PORT_DlcEstablishCnf dlci:%d mtu:%d result:%d", dlci, mtu, result); if (!p_port) { return; } if (result != RFCOMM_SUCCESS) { p_port->error = PORT_START_FAILED; port_rfc_closed (p_port, PORT_START_FAILED); return; } /* If L2CAP's mtu less then RFCOMM's take it */ if (mtu && (mtu < p_port->peer_mtu)) { p_port->peer_mtu = mtu; } /* If there was an inactivity timer running for MCB stop it */ rfc_timer_stop (p_mcb); if (p_port->p_callback && (p_port->ev_mask & PORT_EV_CONNECTED)) { (p_port->p_callback)(PORT_EV_CONNECTED, p_port->inx); } if (p_port->p_mgmt_callback) { p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx); } p_port->state = PORT_STATE_OPENED; /* RPN is required only if we want to tell DTE how the port should be opened */ if ((p_port->uuid == UUID_SERVCLASS_DIALUP_NETWORKING) || (p_port->uuid == UUID_SERVCLASS_FAX)) { RFCOMM_PortNegReq (p_port->rfc.p_mcb, p_port->dlci, NULL); } else { RFCOMM_ControlReq (p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl); } }
/******************************************************************************* ** ** Function rfc_port_closed ** ** Description The function is called when port is released based on the ** event received from the lower layer, typically L2CAP ** connection down, DISC, or DM frame. ** ** Returns void ** *******************************************************************************/ void rfc_port_closed (tPORT *p_port) { tRFC_MCB *p_mcb = p_port->rfc.p_mcb; RFCOMM_TRACE_DEBUG ("rfc_port_closed"); rfc_port_timer_stop (p_port); p_port->rfc.state = RFC_STATE_CLOSED; /* If multiplexer channel was up mark it as down */ if (p_mcb) { p_mcb->port_inx[p_port->dlci] = 0; /* If there are no more ports opened on this MCB release it */ rfc_check_mcb_active (p_mcb); } /* Notify port that RFC connection is gone */ port_rfc_closed (p_port, PORT_CLOSED); }
/******************************************************************************* ** ** Function rfc_port_sm_term_wait_sec_check ** ** Description This function handles events for the port in the ** WAIT_SEC_CHECK state. SABME has been received from the ** peer and Security Manager verifes BD_ADDR, before we can ** send ESTABLISH_IND to the Port entity ** ** Returns void ** *******************************************************************************/ void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data) { switch (event) { case RFC_EVENT_SEC_COMPLETE: if (*((UINT8 *)p_data) != BTM_SUCCESS) { /* Authentication/authorization failed. If link is still */ /* up send DM and check if we need to start inactive timer */ if (p_port->rfc.p_mcb) { rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE); p_port->rfc.p_mcb->is_disc_initiator = TRUE; port_rfc_closed (p_port, PORT_SEC_FAILED); } } else { PORT_DlcEstablishInd (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu); } return; case RFC_EVENT_OPEN: case RFC_EVENT_CLOSE: RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event); return; case RFC_EVENT_CLEAR: btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr); rfc_port_closed (p_port); return; case RFC_EVENT_DATA: RFCOMM_TRACE_ERROR ("Port error state Term Wait Sec event Data"); osi_free (p_data); return; case RFC_EVENT_SABME: /* Ignore SABME retransmission if client dares to do so */ return; case RFC_EVENT_DISC: btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr); p_port->rfc.state = RFC_STATE_CLOSED; rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci); PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci); return; case RFC_EVENT_UIH: osi_free (p_data); return; case RFC_EVENT_ESTABLISH_RSP: if (*((UINT8 *)p_data) != RFCOMM_SUCCESS) { if (p_port->rfc.p_mcb) { rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE); } } else { rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci); p_port->rfc.state = RFC_STATE_OPENED; } return; } RFCOMM_TRACE_WARNING ("Port state term_wait_sec_check Event ignored %d", event); }