/******************************************************************************* ** ** Function NFA_P2pGetLinkInfo ** ** Description This function is called to get local/remote link MIU and ** Well-Known Service list encoded as a 16-bit field of connected LLCP. ** NFA_P2P_LINK_INFO_EVT will be returned. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if server or client is not registered ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pGetLinkInfo (tNFA_HANDLE handle) { tNFA_P2P_API_GET_LINK_INFO *p_msg; tNFA_HANDLE xx; P2P_TRACE_API1 ("NFA_P2pGetLinkInfo (): handle:0x%x", handle); if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) { P2P_TRACE_ERROR0 ("NFA_P2pGetLinkInfo (): LLCP link is not activated"); return (NFA_STATUS_FAILED); } xx = handle & NFA_HANDLE_MASK; if ( (xx >= NFA_P2P_NUM_SAP) ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) ) { P2P_TRACE_ERROR0 ("NFA_P2pGetLinkInfo (): Handle is invalid or not registered"); return (NFA_STATUS_BAD_HANDLE); } if ((p_msg = (tNFA_P2P_API_GET_LINK_INFO *) GKI_getbuf (sizeof (tNFA_P2P_API_GET_LINK_INFO))) != NULL) { p_msg->hdr.event = NFA_P2P_API_GET_LINK_INFO_EVT; p_msg->handle = handle; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_P2pAcceptConn ** ** Description This function is called to accept a request of data link ** connection to a listening SAP on LLCP after receiving ** NFA_P2P_CONN_REQ_EVT. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if handle is not valid ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pAcceptConn (tNFA_HANDLE handle, UINT16 miu, UINT8 rw) { tNFA_P2P_API_ACCEPT_CONN *p_msg; tNFA_HANDLE xx; P2P_TRACE_API3 ("NFA_P2pAcceptConn (): handle:0x%02X, MIU:%d, RW:%d", handle, miu, rw); xx = handle & NFA_HANDLE_MASK; if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) { P2P_TRACE_ERROR0 ("NFA_P2pAcceptConn (): Connection Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } else { xx &= ~NFA_P2P_HANDLE_FLAG_CONN; } if ( (xx >= LLCP_MAX_DATA_LINK) ||(nfa_p2p_cb.conn_cb[xx].flags == 0) ) { P2P_TRACE_ERROR0 ("NFA_P2pAcceptConn (): Connection Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } if ((miu < LLCP_DEFAULT_MIU) || (nfa_p2p_cb.local_link_miu < miu)) { P2P_TRACE_ERROR3 ("NFA_P2pAcceptConn (): MIU(%d) must be between %d and %d", miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu); } else if ((p_msg = (tNFA_P2P_API_ACCEPT_CONN *) GKI_getbuf (sizeof (tNFA_P2P_API_ACCEPT_CONN))) != NULL) { p_msg->hdr.event = NFA_P2P_API_ACCEPT_CONN_EVT; p_msg->conn_handle = handle; p_msg->miu = miu; p_msg->rw = rw; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function nfa_p2p_evt_hdlr ** ** Description Processing event for NFA P2P ** ** ** Returns TRUE if p_msg needs to be deallocated ** *******************************************************************************/ static BOOLEAN nfa_p2p_evt_hdlr (BT_HDR *p_hdr) { BOOLEAN delete_msg = TRUE; UINT16 event; tNFA_P2P_MSG *p_msg = (tNFA_P2P_MSG *)p_hdr; #if (BT_TRACE_VERBOSE == TRUE) P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]", nfa_p2p_llcp_state_code (nfa_p2p_cb.llcp_state), nfa_p2p_evt_code (p_msg->hdr.event)); #else P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x", nfa_p2p_cb.llcp_state, p_msg->hdr.event); #endif event = p_msg->hdr.event & 0x00ff; /* execute action functions */ if (event < NFA_P2P_NUM_ACTIONS) { delete_msg = (*nfa_p2p_action[event]) (p_msg); } else { P2P_TRACE_ERROR0 ("Unhandled event"); } return delete_msg; }
/******************************************************************************* ** ** Function NFA_P2pDeregister ** ** Description This function is called to stop listening to a SAP as server ** or stop client service on LLCP. ** ** Note: If this function is called to de-register a server and RF discovery ** is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if handle is not valid ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pDeregister (tNFA_HANDLE handle) { tNFA_P2P_API_DEREG *p_msg; tNFA_HANDLE xx; P2P_TRACE_API1 ("NFA_P2pDeregister (): handle:0x%02X", handle); xx = handle & NFA_HANDLE_MASK; if ( (xx >= NFA_P2P_NUM_SAP) ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) ) { P2P_TRACE_ERROR0 ("NFA_P2pDeregister (): Handle is invalid or not registered"); return (NFA_STATUS_BAD_HANDLE); } if ((p_msg = (tNFA_P2P_API_DEREG *) GKI_getbuf (sizeof (tNFA_P2P_API_DEREG))) != NULL) { p_msg->hdr.event = NFA_P2P_API_DEREG_EVT; p_msg->handle = handle; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_P2pSetLocalBusy ** ** Description This function is called to stop or resume incoming data on ** connection-oriented transport. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if handle is not valid ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pSetLocalBusy (tNFA_HANDLE conn_handle, BOOLEAN is_busy) { tNFA_P2P_API_SET_LOCAL_BUSY *p_msg; tNFA_HANDLE xx; P2P_TRACE_API2 ("NFA_P2pSetLocalBusy (): conn_handle:0x%02X, is_busy:%d", conn_handle, is_busy); xx = conn_handle & NFA_HANDLE_MASK; if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) { P2P_TRACE_ERROR0 ("NFA_P2pSetLocalBusy (): Connection Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } else { xx &= ~NFA_P2P_HANDLE_FLAG_CONN; } if ( (xx >= LLCP_MAX_DATA_LINK) ||(nfa_p2p_cb.conn_cb[xx].flags == 0) ) { P2P_TRACE_ERROR0 ("NFA_P2pSetLocalBusy (): Connection Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } if ((p_msg = (tNFA_P2P_API_SET_LOCAL_BUSY *) GKI_getbuf (sizeof (tNFA_P2P_API_SET_LOCAL_BUSY))) != NULL) { p_msg->hdr.event = NFA_P2P_API_SET_LOCAL_BUSY_EVT; p_msg->conn_handle = conn_handle; p_msg->is_busy = is_busy; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_P2pDisconnect ** ** Description This function is called to disconnect an existing or ** connecting data link connection. ** ** discard any pending data on data link connection if flush is set to TRUE ** ** NFA_P2P_DISC_EVT will be returned after data link connection is disconnected ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if handle is not valid ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pDisconnect (tNFA_HANDLE handle, BOOLEAN flush) { tNFA_P2P_API_DISCONNECT *p_msg; tNFA_HANDLE xx; P2P_TRACE_API2 ("NFA_P2pDisconnect (): handle:0x%02X, flush=%d", handle, flush); xx = handle & NFA_HANDLE_MASK; if (xx & NFA_P2P_HANDLE_FLAG_CONN) { xx &= ~NFA_P2P_HANDLE_FLAG_CONN; if ( (xx >= LLCP_MAX_DATA_LINK) ||(nfa_p2p_cb.conn_cb[xx].flags == 0) ) { P2P_TRACE_ERROR0 ("NFA_P2pDisconnect (): Connection Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } } else { P2P_TRACE_ERROR0 ("NFA_P2pDisconnect (): Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } if ((p_msg = (tNFA_P2P_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_DISCONNECT))) != NULL) { p_msg->hdr.event = NFA_P2P_API_DISCONNECT_EVT; p_msg->conn_handle = handle; p_msg->flush = flush; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_P2pGetRemoteSap ** ** Description This function is called to get SAP associated by service name ** on connected remote LLCP. ** NFA_P2P_SDP_EVT will be returned. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if server or client is not registered ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pGetRemoteSap (tNFA_HANDLE handle, char *p_service_name) { tNFA_P2P_API_GET_REMOTE_SAP *p_msg; tNFA_HANDLE xx; P2P_TRACE_API2 ("NFA_P2pGetRemoteSap(): handle:0x%x, SN:<%s>", handle, p_service_name); if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) { P2P_TRACE_ERROR0 ("NFA_P2pGetRemoteSap(): LLCP link is not activated"); return (NFA_STATUS_FAILED); } xx = handle & NFA_HANDLE_MASK; if ( (xx >= NFA_P2P_NUM_SAP) ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) ) { P2P_TRACE_ERROR0 ("NFA_P2pGetRemoteSap (): Handle is invalid or not registered"); return (NFA_STATUS_BAD_HANDLE); } if ((p_msg = (tNFA_P2P_API_GET_REMOTE_SAP *) GKI_getbuf (sizeof (tNFA_P2P_API_GET_REMOTE_SAP))) != NULL) { p_msg->hdr.event = NFA_P2P_API_GET_REMOTE_SAP_EVT; p_msg->handle = handle; BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN); p_msg->service_name[LLCP_MAX_SN_LEN] = 0; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_P2pRejectConn ** ** Description This function is called to reject a request of data link ** connection to a listening SAP on LLCP after receiving ** NFA_P2P_CONN_REQ_EVT. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if handle is not valid ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pRejectConn (tNFA_HANDLE handle) { tNFA_P2P_API_REJECT_CONN *p_msg; tNFA_HANDLE xx; P2P_TRACE_API1 ("NFA_P2pRejectConn (): handle:0x%02X", handle); xx = handle & NFA_HANDLE_MASK; if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) { P2P_TRACE_ERROR0 ("NFA_P2pRejectConn (): Connection Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } else { xx &= ~NFA_P2P_HANDLE_FLAG_CONN; } if ( (xx >= LLCP_MAX_DATA_LINK) ||(nfa_p2p_cb.conn_cb[xx].flags == 0) ) { P2P_TRACE_ERROR0 ("NFA_P2pRejectConn (): Connection Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } if ((p_msg = (tNFA_P2P_API_REJECT_CONN *) GKI_getbuf (sizeof (tNFA_P2P_API_REJECT_CONN))) != NULL) { p_msg->hdr.event = NFA_P2P_API_REJECT_CONN_EVT; p_msg->conn_handle = handle; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_P2pConnectByName ** ** Description This function is called to create a connection-oriented transport ** by a service name. ** NFA_P2P_CONNECTED_EVT if success ** NFA_P2P_DISC_EVT if failed ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_BAD_HANDLE if client is not registered ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pConnectByName (tNFA_HANDLE client_handle, char *p_service_name, UINT16 miu, UINT8 rw) { tNFA_P2P_API_CONNECT *p_msg; tNFA_HANDLE xx; P2P_TRACE_API4 ("NFA_P2pConnectByName (): client_handle:0x%x, SN:<%s>, MIU:%d, RW:%d", client_handle, p_service_name, miu, rw); xx = client_handle & NFA_HANDLE_MASK; if ( (xx >= NFA_P2P_NUM_SAP) ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) ) { P2P_TRACE_ERROR0 ("NFA_P2pConnectByName (): Client Handle is not valid"); return (NFA_STATUS_BAD_HANDLE); } if ( (miu < LLCP_DEFAULT_MIU) ||(nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) ||(nfa_p2p_cb.local_link_miu < miu) ) { P2P_TRACE_ERROR3 ("NFA_P2pConnectByName (): MIU(%d) must be between %d and %d or LLCP link is not activated", miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu); } else if ((p_msg = (tNFA_P2P_API_CONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_CONNECT))) != NULL) { p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT; BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN); p_msg->service_name[LLCP_MAX_SN_LEN] = 0; p_msg->dsap = LLCP_INVALID_SAP; p_msg->miu = miu; p_msg->rw = rw; p_msg->client_handle = client_handle; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function NFA_P2pSetLLCPConfig ** ** Description This function is called to change LLCP config parameters. ** Application must call while LLCP is not activated. ** ** Parameters descriptions (default value) ** - Local Link MIU (LLCP_MIU) ** - Option parameter (LLCP_OPT_VALUE) ** - Response Waiting Time Index (LLCP_WAITING_TIME) ** - Local Link Timeout (LLCP_LTO_VALUE) ** - Inactivity Timeout as initiator role (LLCP_INIT_INACTIVITY_TIMEOUT) ** - Inactivity Timeout as target role (LLCP_TARGET_INACTIVITY_TIMEOUT) ** - Delay SYMM response (LLCP_DELAY_RESP_TIME) ** - Data link connection timeout (LLCP_DATA_LINK_CONNECTION_TOUT) ** - Delay timeout to send first PDU as initiator (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU) ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** *******************************************************************************/ tNFA_STATUS NFA_P2pSetLLCPConfig (UINT16 link_miu, UINT8 opt, UINT8 wt, UINT16 link_timeout, UINT16 inact_timeout_init, UINT16 inact_timeout_target, UINT16 symm_delay, UINT16 data_link_timeout, UINT16 delay_first_pdu_timeout) { tNFA_P2P_API_SET_LLCP_CFG *p_msg; P2P_TRACE_API4 ("NFA_P2pSetLLCPConfig ():link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d", link_miu, opt, wt, link_timeout); P2P_TRACE_API4 (" inact_timeout(init:%d, target:%d), symm_delay:%d, data_link_timeout:%d", inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout); P2P_TRACE_API1 (" delay_first_pdu_timeout:%d", delay_first_pdu_timeout); if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) { P2P_TRACE_ERROR0 ("NFA_P2pSetLLCPConfig (): LLCP link is activated"); return (NFA_STATUS_FAILED); } if ((p_msg = (tNFA_P2P_API_SET_LLCP_CFG *) GKI_getbuf (sizeof (tNFA_P2P_API_SET_LLCP_CFG))) != NULL) { p_msg->hdr.event = NFA_P2P_API_SET_LLCP_CFG_EVT; p_msg->link_miu = link_miu; p_msg->opt = opt; p_msg->wt = wt; p_msg->link_timeout = link_timeout; p_msg->inact_timeout_init = inact_timeout_init; p_msg->inact_timeout_target = inact_timeout_target; p_msg->symm_delay = symm_delay; p_msg->data_link_timeout = data_link_timeout; p_msg->delay_first_pdu_timeout = delay_first_pdu_timeout; nfa_sys_sendmsg (p_msg); return (NFA_STATUS_OK); } return (NFA_STATUS_FAILED); }
/******************************************************************************* ** ** Function nfa_p2p_discovery_cback ** ** Description Processing event from discovery callback for listening ** ** ** Returns None ** *******************************************************************************/ void nfa_p2p_discovery_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data) { tNFA_CONN_EVT_DATA evt_data; P2P_TRACE_DEBUG1 ("nfa_p2p_discovery_cback (): event:0x%02X", event); switch (event) { case NFA_DM_RF_DISC_START_EVT: if (p_data->status == NFC_STATUS_OK) { nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_LISTENING; nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY; } break; case NFA_DM_RF_DISC_ACTIVATED_EVT: nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_ACTIVE; /* notify NFC link activation */ memcpy (&(evt_data.activated.activate_ntf), &(p_data->activate), sizeof (tNFC_ACTIVATE_DEVT)); nfa_dm_conn_cback_event_notify (NFA_ACTIVATED_EVT, &evt_data); if ((p_data->activate.protocol == NFC_PROTOCOL_NFC_DEP) &&(p_data->activate.intf_param.type == NFC_INTERFACE_NFC_DEP)) { nfa_p2p_activate_llcp (p_data); /* stop timer not to deactivate LLCP link on passive mode */ nfa_sys_stop_timer (&nfa_p2p_cb.active_listen_restore_timer); } break; case NFA_DM_RF_DISC_DEACTIVATED_EVT: if ( (nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_ACTIVE) &&(nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_SLEEP) ) { /* this is not for P2P listen ** DM broadcasts deactivaiton event in listen sleep state. */ break; } /* notify deactivation */ if ( (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF) ) { nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_SLEEP; evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP; } else { nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY; evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE; } nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data); break; default: P2P_TRACE_ERROR0 ("Unexpected event"); break; } }