diff options
Diffstat (limited to 'nci/jni/PeerToPeer.cpp')
-rw-r--r-- | nci/jni/PeerToPeer.cpp | 520 |
1 files changed, 309 insertions, 211 deletions
diff --git a/nci/jni/PeerToPeer.cpp b/nci/jni/PeerToPeer.cpp index bf18df5..78132b8 100644 --- a/nci/jni/PeerToPeer.cpp +++ b/nci/jni/PeerToPeer.cpp @@ -15,6 +15,8 @@ #include "config.h" #include "JavaClassConstants.h" +using namespace android; + namespace android { extern void nativeNfcTag_registerNdefTypeHandler (); @@ -23,7 +25,7 @@ namespace android PeerToPeer PeerToPeer::sP2p; -const std::string PeerToPeer::sSnepServiceName ("urn:nfc:sn:snep"); +const std::string P2pServer::sSnepServiceName ("urn:nfc:sn:snep"); /******************************************************************************* @@ -100,15 +102,16 @@ void PeerToPeer::initialize () /******************************************************************************* ** -** Function: findServer +** Function: findServerLocked ** ** Description: Find a PeerToPeer object by connection handle. +** Assumes mMutex is already held ** nfaP2pServerHandle: Connectin handle. ** ** Returns: PeerToPeer object. ** *******************************************************************************/ -P2pServer *PeerToPeer::findServer (tNFA_HANDLE nfaP2pServerHandle) +sp<P2pServer> PeerToPeer::findServerLocked (tNFA_HANDLE nfaP2pServerHandle) { for (int i = 0; i < sMax; i++) { @@ -126,15 +129,16 @@ P2pServer *PeerToPeer::findServer (tNFA_HANDLE nfaP2pServerHandle) /******************************************************************************* ** -** Function: findServer +** Function: findServerLocked ** ** Description: Find a PeerToPeer object by connection handle. +** Assumes mMutex is already held ** serviceName: service name. ** ** Returns: PeerToPeer object. ** *******************************************************************************/ -P2pServer *PeerToPeer::findServer (tJNI_HANDLE jniHandle) +sp<P2pServer> PeerToPeer::findServerLocked (tJNI_HANDLE jniHandle) { for (int i = 0; i < sMax; i++) { @@ -152,15 +156,16 @@ P2pServer *PeerToPeer::findServer (tJNI_HANDLE jniHandle) /******************************************************************************* ** -** Function: findServer +** Function: findServerLocked ** ** Description: Find a PeerToPeer object by service name +** Assumes mMutex is already heldf ** serviceName: service name. ** ** Returns: PeerToPeer object. ** *******************************************************************************/ -P2pServer *PeerToPeer::findServer (const char *serviceName) +sp<P2pServer> PeerToPeer::findServerLocked (const char *serviceName) { for (int i = 0; i < sMax; i++) { @@ -189,16 +194,18 @@ bool PeerToPeer::registerServer (tJNI_HANDLE jniHandle, const char *serviceName) static const char fn [] = "PeerToPeer::registerServer"; ALOGD ("%s: enter; service name: %s JNI handle: %u", fn, serviceName, jniHandle); tNFA_STATUS stat = NFA_STATUS_OK; - P2pServer *pSrv = NULL; + sp<P2pServer> pSrv = NULL; UINT8 serverSap = NFA_P2P_ANY_SAP; + mMutex.lock(); // Check if already registered - if ((pSrv = findServer(serviceName)) != NULL) + if ((pSrv = findServerLocked(serviceName)) != NULL) { ALOGD ("%s: service name=%s already registered, handle: 0x%04x", fn, serviceName, pSrv->mNfaP2pServerHandle); // Update JNI handle pSrv->mJniHandle = jniHandle; + mMutex.unlock(); return (true); } @@ -206,14 +213,13 @@ bool PeerToPeer::registerServer (tJNI_HANDLE jniHandle, const char *serviceName) { if (mServers[ii] == NULL) { - pSrv = mServers[ii] = new P2pServer; - pSrv->mServiceName.assign (serviceName); - pSrv->mJniHandle = jniHandle; + pSrv = mServers[ii] = new P2pServer(jniHandle, serviceName); ALOGD ("%s: added new p2p server index: %d handle: %u name: %s", fn, ii, jniHandle, serviceName); break; } } + mMutex.unlock(); if (pSrv == NULL) { @@ -221,58 +227,14 @@ bool PeerToPeer::registerServer (tJNI_HANDLE jniHandle, const char *serviceName) return (false); } - /********************** - default values for all LLCP parameters: - - 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) - ************************/ - stat = NFA_P2pSetLLCPConfig (LLCP_MIU, - LLCP_OPT_VALUE, - LLCP_WAITING_TIME, - LLCP_LTO_VALUE, - 0, //use 0 for infinite timeout for symmetry procedure when acting as initiator - 0, //use 0 for infinite timeout for symmetry procedure when acting as target - LLCP_DELAY_RESP_TIME, - LLCP_DATA_LINK_CONNECTION_TOUT, - LLCP_DELAY_TIME_TO_SEND_FIRST_PDU); - if (stat != NFA_STATUS_OK) - ALOGE ("%s: fail set LLCP config; error=0x%X", fn, stat); - - if (sSnepServiceName.compare(serviceName) == 0) - serverSap = LLCP_SAP_SNEP; //LLCP_SAP_SNEP == 4 - - { - SyncEventGuard guard (pSrv->mRegServerEvent); - stat = NFA_P2pRegisterServer (serverSap, NFA_P2P_DLINK_TYPE, const_cast<char*>(serviceName), nfaServerCallback); - if (stat != NFA_STATUS_OK) - { - ALOGE ("%s: fail register p2p server; error=0x%X", fn, stat); - removeServer (jniHandle); - return (false); - } - ALOGD ("%s: wait for listen-completion event", fn); - // Wait for NFA_P2P_REG_SERVER_EVT - pSrv->mRegServerEvent.wait (); - } - - if (pSrv->mNfaP2pServerHandle == NFA_HANDLE_INVALID) - { + if (pSrv->registerWithStack()) { + ALOGD ("%s: got new p2p server h=0x%X", fn, pSrv->mNfaP2pServerHandle); + return (true); + } else { ALOGE ("%s: invalid server handle", fn); removeServer (jniHandle); return (false); } - else - { - ALOGD ("%s: got new p2p server h=0x%X", fn, pSrv->mNfaP2pServerHandle); - return (true); - } } @@ -290,6 +252,8 @@ void PeerToPeer::removeServer (tJNI_HANDLE jniHandle) { static const char fn [] = "PeerToPeer::removeServer"; + AutoMutex mutex(mMutex); + for (int i = 0; i < sMax; i++) { if ( (mServers[i] != NULL) && (mServers[i]->mJniHandle == jniHandle) ) @@ -297,7 +261,6 @@ void PeerToPeer::removeServer (tJNI_HANDLE jniHandle) ALOGD ("%s: server jni_handle: %u; nfa_handle: 0x%04x; name: %s; index=%d", fn, jniHandle, mServers[i]->mNfaP2pServerHandle, mServers[i]->mServiceName.c_str(), i); - delete mServers [i]; mServers [i] = NULL; return; } @@ -453,70 +416,24 @@ bool PeerToPeer::accept (tJNI_HANDLE serverJniHandle, tJNI_HANDLE connJniHandle, { static const char fn [] = "PeerToPeer::accept"; tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - NfaConn *pConn = NULL; + sp<NfaConn> *pConn = NULL; bool stat = false; int ii = 0; - P2pServer *pSrv = NULL; + sp<P2pServer> pSrv = NULL; ALOGD ("%s: enter; server jni handle: %u; conn jni handle: %u; maxInfoUnit: %d; recvWindow: %d", fn, serverJniHandle, connJniHandle, maxInfoUnit, recvWindow); - if ((pSrv = findServer (serverJniHandle)) == NULL) + mMutex.lock(); + if ((pSrv = findServerLocked (serverJniHandle)) == NULL) { ALOGE ("%s: unknown server jni handle: %u", fn, serverJniHandle); + mMutex.unlock(); return (false); } + mMutex.unlock(); - // First, find a free connection block to handle the connection - for (ii = 0; ii < MAX_NFA_CONNS_PER_SERVER; ii++) - { - if (pSrv->mServerConn[ii] == NULL) - { - ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; allocate server conn index: %u", fn, - serverJniHandle, connJniHandle, ii); - pSrv->mServerConn[ii] = new NfaConn; - pSrv->mServerConn[ii]->mJniHandle = connJniHandle; - break; - } - } - - if (ii == MAX_NFA_CONNS_PER_SERVER) - { - ALOGE ("%s: fail allocate connection block", fn); - return (false); - } - - { - // Wait for NFA_P2P_CONN_REQ_EVT or NFA_NDEF_DATA_EVT when remote device requests connection - SyncEventGuard guard (pSrv->mConnRequestEvent); - ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; server conn index: %u; wait for incoming connection", fn, - serverJniHandle, connJniHandle, ii); - pSrv->mConnRequestEvent.wait(); - ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; server conn index: %u; nfa conn h: 0x%X; got incoming connection", fn, - serverJniHandle, connJniHandle, ii, pSrv->mServerConn[ii]->mNfaConnHandle); - } - - if (pSrv->mServerConn[ii]->mNfaConnHandle == NFA_HANDLE_INVALID) - { - delete (pSrv->mServerConn[ii]); - pSrv->mServerConn[ii] = NULL; - ALOGD ("%s: no handle assigned", fn); - return (false); - } - - ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; server conn index: %u; nfa conn h: 0x%X; try accept", fn, - serverJniHandle, connJniHandle, ii, pSrv->mServerConn[ii]->mNfaConnHandle); - nfaStat = NFA_P2pAcceptConn (pSrv->mServerConn[ii]->mNfaConnHandle, maxInfoUnit, recvWindow); - - if (nfaStat != NFA_STATUS_OK) - { - ALOGE ("%s: fail to accept remote; error=0x%X", fn, nfaStat); - return (false); - } - - ALOGD ("%s: exit; serverJniHandle: %u; connJniHandle: %u; server conn index: %u; nfa conn h: 0x%X", fn, - serverJniHandle, connJniHandle, ii, pSrv->mServerConn[ii]->mNfaConnHandle); - return (true); + return pSrv->accept(serverJniHandle, connJniHandle, maxInfoUnit, recvWindow); } @@ -534,13 +451,16 @@ bool PeerToPeer::deregisterServer (tJNI_HANDLE jniHandle) static const char fn [] = "PeerToPeer::deregisterServer"; ALOGD ("%s: enter; JNI handle: %u", fn, jniHandle); tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - P2pServer *pSrv = NULL; + sp<P2pServer> pSrv = NULL; - if ((pSrv = findServer (jniHandle)) == NULL) + mMutex.lock(); + if ((pSrv = findServerLocked (jniHandle)) == NULL) { ALOGE ("%s: unknown service handle: %u", fn, jniHandle); + mMutex.unlock(); return (false); } + mMutex.unlock(); { // Server does not call NFA_P2pDisconnect(), so unblock the accept() @@ -579,39 +499,44 @@ bool PeerToPeer::createClient (tJNI_HANDLE jniHandle, UINT16 miu, UINT8 rw) int i = 0; ALOGD ("%s: enter: jni h: %u miu: %u rw: %u", fn, jniHandle, miu, rw); + mMutex.lock(); + sp<P2pClient> client = NULL; for (i = 0; i < sMax; i++) { if (mClients[i] == NULL) { - mClients [i] = new P2pClient; + mClients [i] = client = new P2pClient(); - mClients [i]->mClientConn.mJniHandle = jniHandle; - mClients [i]->mClientConn.mMaxInfoUnit = miu; - mClients [i]->mClientConn.mRecvWindow = rw; + mClients [i]->mClientConn->mJniHandle = jniHandle; + mClients [i]->mClientConn->mMaxInfoUnit = miu; + mClients [i]->mClientConn->mRecvWindow = rw; break; } } + mMutex.unlock(); - if (i == sMax) + if (client == NULL) { ALOGE ("%s: fail", fn); return (false); } - ALOGD ("%s: pClient: 0x%p assigned for client jniHandle: %u", fn, mClients[i], jniHandle); + ALOGD ("%s: pClient: 0x%p assigned for client jniHandle: %u", fn, client.get(), jniHandle); - SyncEventGuard guard (mClients[i]->mRegisteringEvent); - NFA_P2pRegisterClient (NFA_P2P_DLINK_TYPE, nfaClientCallback); - mClients[i]->mRegisteringEvent.wait(); //wait for NFA_P2P_REG_CLIENT_EVT + { + SyncEventGuard guard (mClients[i]->mRegisteringEvent); + NFA_P2pRegisterClient (NFA_P2P_DLINK_TYPE, nfaClientCallback); + mClients[i]->mRegisteringEvent.wait(); //wait for NFA_P2P_REG_CLIENT_EVT + } if (mClients[i]->mNfaP2pClientHandle != NFA_HANDLE_INVALID) { - ALOGD ("%s: exit; new client jniHandle: %u NFA Handle: 0x%04x", fn, jniHandle, mClients[i]->mClientConn.mNfaConnHandle); + ALOGD ("%s: exit; new client jniHandle: %u NFA Handle: 0x%04x", fn, jniHandle, client->mClientConn->mNfaConnHandle); return (true); } else { - ALOGE ("%s: FAILED; new client jniHandle: %u NFA Handle: 0x%04x", fn, jniHandle, mClients[i]->mClientConn.mNfaConnHandle); + ALOGE ("%s: FAILED; new client jniHandle: %u NFA Handle: 0x%04x", fn, jniHandle, client->mClientConn->mNfaConnHandle); removeConn (jniHandle); return (false); } @@ -633,15 +558,15 @@ void PeerToPeer::removeConn(tJNI_HANDLE jniHandle) static const char fn[] = "PeerToPeer::removeConn"; int ii = 0, jj = 0; + AutoMutex mutex(mMutex); // If the connection is a for a client, delete the client itself for (ii = 0; ii < sMax; ii++) { - if (mClients[ii] && (mClients[ii]->mClientConn.mJniHandle == jniHandle)) + if ((mClients[ii] != NULL) && (mClients[ii]->mClientConn->mJniHandle == jniHandle)) { if (mClients[ii]->mNfaP2pClientHandle != NFA_HANDLE_INVALID) NFA_P2pDeregister (mClients[ii]->mNfaP2pClientHandle); - delete mClients[ii]; mClients[ii] = NULL; ALOGD ("%s: deleted client handle: %u index: %u", fn, jniHandle, ii); return; @@ -653,17 +578,8 @@ void PeerToPeer::removeConn(tJNI_HANDLE jniHandle) { if (mServers[ii] != NULL) { - for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) - { - if ( (mServers[ii]->mServerConn[jj] != NULL) - && (mServers[ii]->mServerConn[jj]->mJniHandle == jniHandle) ) - { - ALOGD ("%s: delete server conn jni h: %u; index: %d; server jni h: %u", - fn, mServers[ii]->mServerConn[jj]->mJniHandle, jj, mServers[ii]->mJniHandle); - delete mServers[ii]->mServerConn[jj]; - mServers[ii]->mServerConn[jj] = NULL; - return; - } + if (mServers[ii]->removeServerConnection(jniHandle)) { + return; } } } @@ -731,7 +647,7 @@ bool PeerToPeer::createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceN static const char fn [] = "PeerToPeer::createDataLinkConn"; ALOGD ("%s: enter", fn); tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - P2pClient *pClient = NULL; + sp<P2pClient> pClient = NULL; if ((pClient = findClient (jniHandle)) == NULL) { @@ -745,21 +661,21 @@ bool PeerToPeer::createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceN if (serviceName) nfaStat = NFA_P2pConnectByName (pClient->mNfaP2pClientHandle, - const_cast<char*>(serviceName), pClient->mClientConn.mMaxInfoUnit, - pClient->mClientConn.mRecvWindow); + const_cast<char*>(serviceName), pClient->mClientConn->mMaxInfoUnit, + pClient->mClientConn->mRecvWindow); else if (destinationSap) nfaStat = NFA_P2pConnectBySap (pClient->mNfaP2pClientHandle, destinationSap, - pClient->mClientConn.mMaxInfoUnit, pClient->mClientConn.mRecvWindow); + pClient->mClientConn->mMaxInfoUnit, pClient->mClientConn->mRecvWindow); if (nfaStat == NFA_STATUS_OK) { - ALOGD ("%s: wait for connected event mConnectingEvent: 0x%p", fn, pClient); + ALOGD ("%s: wait for connected event mConnectingEvent: 0x%p", fn, pClient.get()); pClient->mConnectingEvent.wait(); } } if (nfaStat == NFA_STATUS_OK) { - if (pClient->mClientConn.mNfaConnHandle == NFA_HANDLE_INVALID) + if (pClient->mClientConn->mNfaConnHandle == NFA_HANDLE_INVALID) { removeConn (jniHandle); nfaStat = NFA_STATUS_FAILED; @@ -788,11 +704,12 @@ bool PeerToPeer::createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceN ** Returns: PeerToPeer object. ** *******************************************************************************/ -P2pClient *PeerToPeer::findClient (tNFA_HANDLE nfaConnHandle) +sp<P2pClient> PeerToPeer::findClient (tNFA_HANDLE nfaConnHandle) { + AutoMutex mutex(mMutex); for (int i = 0; i < sMax; i++) { - if (mClients[i] && (mClients[i]->mNfaP2pClientHandle == nfaConnHandle)) + if ((mClients[i] != NULL) && (mClients[i]->mNfaP2pClientHandle == nfaConnHandle)) return (mClients[i]); } return (NULL); @@ -809,11 +726,12 @@ P2pClient *PeerToPeer::findClient (tNFA_HANDLE nfaConnHandle) ** Returns: PeerToPeer object. ** *******************************************************************************/ -P2pClient *PeerToPeer::findClient (tJNI_HANDLE jniHandle) +sp<P2pClient> PeerToPeer::findClient (tJNI_HANDLE jniHandle) { + AutoMutex mutex(mMutex); for (int i = 0; i < sMax; i++) { - if (mClients[i] && (mClients[i]->mClientConn.mJniHandle == jniHandle)) + if ((mClients[i] != NULL) && (mClients[i]->mClientConn->mJniHandle == jniHandle)) return (mClients[i]); } return (NULL); @@ -830,11 +748,12 @@ P2pClient *PeerToPeer::findClient (tJNI_HANDLE jniHandle) ** Returns: PeerToPeer object. ** *******************************************************************************/ -P2pClient *PeerToPeer::findClientCon (tNFA_HANDLE nfaConnHandle) +sp<P2pClient> PeerToPeer::findClientCon (tNFA_HANDLE nfaConnHandle) { + AutoMutex mutex(mMutex); for (int i = 0; i < sMax; i++) { - if (mClients[i] && (mClients[i]->mClientConn.mNfaConnHandle == nfaConnHandle)) + if ((mClients[i] != NULL) && (mClients[i]->mClientConn->mNfaConnHandle == nfaConnHandle)) return (mClients[i]); } return (NULL); @@ -851,16 +770,18 @@ P2pClient *PeerToPeer::findClientCon (tNFA_HANDLE nfaConnHandle) ** Returns: PeerToPeer object. ** *******************************************************************************/ -NfaConn *PeerToPeer::findConnection (tNFA_HANDLE nfaConnHandle) +sp<NfaConn> PeerToPeer::findConnection (tNFA_HANDLE nfaConnHandle) { int ii = 0, jj = 0; + AutoMutex mutex(mMutex); // First, look through all the client control blocks for (ii = 0; ii < sMax; ii++) { if ( (mClients[ii] != NULL) - && (mClients[ii]->mClientConn.mNfaConnHandle == nfaConnHandle) ) - return (&mClients[ii]->mClientConn); + && (mClients[ii]->mClientConn->mNfaConnHandle == nfaConnHandle) ) { + return mClients[ii]->mClientConn; + } } // Not found yet. Look through all the server control blocks @@ -868,11 +789,9 @@ NfaConn *PeerToPeer::findConnection (tNFA_HANDLE nfaConnHandle) { if (mServers[ii] != NULL) { - for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) - { - if ( (mServers[ii]->mServerConn[jj] != NULL) - && (mServers[ii]->mServerConn[jj]->mNfaConnHandle == nfaConnHandle) ) - return (mServers[ii]->mServerConn[jj]); + sp<NfaConn> conn = mServers[ii]->findServerConnection(nfaConnHandle); + if (conn != NULL) { + return conn; } } } @@ -892,16 +811,18 @@ NfaConn *PeerToPeer::findConnection (tNFA_HANDLE nfaConnHandle) ** Returns: PeerToPeer object. ** *******************************************************************************/ -NfaConn *PeerToPeer::findConnection (tJNI_HANDLE jniHandle) +sp<NfaConn> PeerToPeer::findConnection (tJNI_HANDLE jniHandle) { int ii = 0, jj = 0; + AutoMutex mutex(mMutex); // First, look through all the client control blocks for (ii = 0; ii < sMax; ii++) { if ( (mClients[ii] != NULL) - && (mClients[ii]->mClientConn.mJniHandle == jniHandle) ) - return (&mClients[ii]->mClientConn); + && (mClients[ii]->mClientConn->mJniHandle == jniHandle) ) { + return mClients[ii]->mClientConn; + } } // Not found yet. Look through all the server control blocks @@ -909,11 +830,9 @@ NfaConn *PeerToPeer::findConnection (tJNI_HANDLE jniHandle) { if (mServers[ii] != NULL) { - for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) - { - if ( (mServers[ii]->mServerConn[jj] != NULL) - && (mServers[ii]->mServerConn[jj]->mJniHandle == jniHandle) ) - return (mServers[ii]->mServerConn[jj]); + sp<NfaConn> conn = mServers[ii]->findServerConnection(jniHandle); + if (conn != NULL) { + return conn; } } } @@ -939,7 +858,7 @@ bool PeerToPeer::send (tJNI_HANDLE jniHandle, UINT8 *buffer, UINT16 bufferLen) { static const char fn [] = "PeerToPeer::send"; tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - NfaConn *pConn = NULL; + sp<NfaConn> pConn = NULL; if ((pConn = findConnection (jniHandle)) == NULL) { @@ -993,7 +912,7 @@ bool PeerToPeer::receive (tJNI_HANDLE jniHandle, UINT8* buffer, UINT16 bufferLen { static const char fn [] = "PeerToPeer::receive"; ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; jniHandle: %u bufferLen: %u", fn, jniHandle, bufferLen); - NfaConn *pConn = NULL; + sp<NfaConn> pConn = NULL; tNFA_STATUS stat = NFA_STATUS_FAILED; UINT32 actualDataLen2 = 0; BOOLEAN isMoreData = TRUE; @@ -1043,8 +962,8 @@ bool PeerToPeer::disconnectConnOriented (tJNI_HANDLE jniHandle) { static const char fn [] = "PeerToPeer::disconnectConnOriented"; tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - P2pClient *pClient = NULL; - NfaConn *pConn = NULL; + sp<P2pClient> pClient = NULL; + sp<NfaConn> pConn = NULL; ALOGD ("%s: enter; jni handle: %u", fn, jniHandle); @@ -1105,7 +1024,7 @@ bool PeerToPeer::disconnectConnOriented (tJNI_HANDLE jniHandle) UINT16 PeerToPeer::getRemoteMaxInfoUnit (tJNI_HANDLE jniHandle) { static const char fn [] = "PeerToPeer::getRemoteMaxInfoUnit"; - NfaConn *pConn = NULL; + sp<NfaConn> pConn = NULL; if ((pConn = findConnection(jniHandle)) == NULL) { @@ -1131,7 +1050,7 @@ UINT8 PeerToPeer::getRemoteRecvWindow (tJNI_HANDLE jniHandle) { static const char fn [] = "PeerToPeer::getRemoteRecvWindow"; ALOGD ("%s: client jni handle: %u", fn, jniHandle); - NfaConn *pConn = NULL; + sp<NfaConn> pConn = NULL; if ((pConn = findConnection(jniHandle)) == NULL) { @@ -1218,6 +1137,7 @@ void PeerToPeer::handleNfcOnOff (bool isOn) mIsP2pListening = false; // In both cases, P2P will not be listening + AutoMutex mutex(mMutex); if (isOn) { // Start with no clients or servers @@ -1233,21 +1153,21 @@ void PeerToPeer::handleNfcOnOff (bool isOn) { if (mClients[ii] != NULL) { - if (mClients[ii]->mClientConn.mNfaConnHandle == NFA_HANDLE_INVALID) + if (mClients[ii]->mClientConn->mNfaConnHandle == NFA_HANDLE_INVALID) { SyncEventGuard guard (mClients[ii]->mConnectingEvent); mClients[ii]->mConnectingEvent.notifyOne(); } else { - mClients[ii]->mClientConn.mNfaConnHandle = NFA_HANDLE_INVALID; + mClients[ii]->mClientConn->mNfaConnHandle = NFA_HANDLE_INVALID; { - SyncEventGuard guard1 (mClients[ii]->mClientConn.mCongEvent); - mClients[ii]->mClientConn.mCongEvent.notifyOne (); //unblock send() + SyncEventGuard guard1 (mClients[ii]->mClientConn->mCongEvent); + mClients[ii]->mClientConn->mCongEvent.notifyOne (); //unblock send() } { - SyncEventGuard guard2 (mClients[ii]->mClientConn.mReadEvent); - mClients[ii]->mClientConn.mReadEvent.notifyOne (); //unblock receive() + SyncEventGuard guard2 (mClients[ii]->mClientConn->mReadEvent); + mClients[ii]->mClientConn->mReadEvent.notifyOne (); //unblock receive() } } } @@ -1258,21 +1178,7 @@ void PeerToPeer::handleNfcOnOff (bool isOn) { if (mServers[ii] != NULL) { - for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) - { - if (mServers[ii]->mServerConn[jj] != NULL) - { - mServers[ii]->mServerConn[jj]->mNfaConnHandle = NFA_HANDLE_INVALID; - { - SyncEventGuard guard1 (mServers[ii]->mServerConn[jj]->mCongEvent); - mServers[ii]->mServerConn[jj]->mCongEvent.notifyOne (); //unblock write (if congested) - } - { - SyncEventGuard guard2 (mServers[ii]->mServerConn[jj]->mReadEvent); - mServers[ii]->mServerConn[jj]->mReadEvent.notifyOne (); //unblock receive() - } - } - } + mServers[ii]->unblockAll(); } } //loop @@ -1295,8 +1201,8 @@ void PeerToPeer::handleNfcOnOff (bool isOn) void PeerToPeer::nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* eventData) { static const char fn [] = "PeerToPeer::nfaServerCallback"; - P2pServer *pSrv = NULL; - NfaConn *pConn = NULL; + sp<P2pServer> pSrv = NULL; + sp<NfaConn> pConn = NULL; ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; event=0x%X", fn, p2pEvent); @@ -1306,7 +1212,10 @@ void PeerToPeer::nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev ALOGD ("%s: NFA_P2P_REG_SERVER_EVT; handle: 0x%04x; service sap=0x%02x name: %s", fn, eventData->reg_server.server_handle, eventData->reg_server.server_sap, eventData->reg_server.service_name); - if ((pSrv = sP2p.findServer(eventData->reg_server.service_name)) == NULL) + sP2p.mMutex.lock(); + pSrv = sP2p.findServerLocked(eventData->reg_server.service_name); + sP2p.mMutex.unlock(); + if (pSrv == NULL) { ALOGE ("%s: NFA_P2P_REG_SERVER_EVT for unknown service: %s", fn, eventData->reg_server.service_name); } @@ -1330,7 +1239,10 @@ void PeerToPeer::nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; nfa server h=0x%04x; nfa conn h=0x%04x; remote sap=0x%02x", fn, eventData->conn_req.server_handle, eventData->conn_req.conn_handle, eventData->conn_req.remote_sap); - if ((pSrv = sP2p.findServer(eventData->conn_req.server_handle)) == NULL) + sP2p.mMutex.lock(); + pSrv = sP2p.findServerLocked(eventData->conn_req.server_handle); + sP2p.mMutex.unlock(); + if (pSrv == NULL) { ALOGE ("%s: NFA_P2P_CONN_REQ_EVT; unknown server h", fn); return; @@ -1338,7 +1250,7 @@ void PeerToPeer::nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; server jni h=%u", fn, pSrv->mJniHandle); // Look for a connection block that is waiting (handle invalid) - if ((pConn = pSrv->findServerConnection(NFA_HANDLE_INVALID)) == NULL) + if ((pConn = pSrv->findServerConnection((tNFA_HANDLE) NFA_HANDLE_INVALID)) == NULL) { ALOGE ("%s: NFA_P2P_CONN_REQ_EVT; server not listening", fn); } @@ -1446,8 +1358,8 @@ void PeerToPeer::nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev void PeerToPeer::nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* eventData) { static const char fn [] = "PeerToPeer::nfaClientCallback"; - NfaConn *pConn = NULL; - P2pClient *pClient = NULL; + sp<NfaConn> pConn = NULL; + sp<P2pClient> pClient = NULL; ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; event=%u", fn, p2pEvent); @@ -1461,7 +1373,7 @@ void PeerToPeer::nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev } else { - ALOGD ("%s: NFA_P2P_REG_CLIENT_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->reg_client.client_handle, pClient); + ALOGD ("%s: NFA_P2P_REG_CLIENT_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->reg_client.client_handle, pClient.get()); SyncEventGuard guard (pClient->mRegisteringEvent); pClient->mNfaP2pClientHandle = eventData->reg_client.client_handle; @@ -1477,7 +1389,7 @@ void PeerToPeer::nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev } else { - ALOGD ("%s: NFA_P2P_ACTIVATED_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->activated.handle, pClient); + ALOGD ("%s: NFA_P2P_ACTIVATED_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->activated.handle, pClient.get()); } break; @@ -1494,12 +1406,12 @@ void PeerToPeer::nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev else { ALOGD ("%s: NFA_P2P_CONNECTED_EVT; client_handle=0x%04x conn_handle: 0x%04x remote sap=0x%X pClient: 0x%p", fn, - eventData->connected.client_handle, eventData->connected.conn_handle, eventData->connected.remote_sap, pClient); + eventData->connected.client_handle, eventData->connected.conn_handle, eventData->connected.remote_sap, pClient.get()); SyncEventGuard guard (pClient->mConnectingEvent); - pClient->mClientConn.mNfaConnHandle = eventData->connected.conn_handle; - pClient->mClientConn.mRemoteMaxInfoUnit = eventData->connected.remote_miu; - pClient->mClientConn.mRemoteRecvWindow = eventData->connected.remote_rw; + pClient->mClientConn->mNfaConnHandle = eventData->connected.conn_handle; + pClient->mClientConn->mRemoteMaxInfoUnit = eventData->connected.remote_miu; + pClient->mClientConn->mRemoteRecvWindow = eventData->connected.remote_rw; pClient->mConnectingEvent.notifyOne(); //unblock createDataLinkConn() } break; @@ -1641,13 +1553,147 @@ PeerToPeer::tJNI_HANDLE PeerToPeer::getNewJniHandle () ** Returns: None ** *******************************************************************************/ -P2pServer::P2pServer() +P2pServer::P2pServer(PeerToPeer::tJNI_HANDLE jniHandle, const char* serviceName) : mNfaP2pServerHandle (NFA_HANDLE_INVALID), - mJniHandle (0) + mJniHandle (jniHandle) { + mServiceName.assign (serviceName); + memset (mServerConn, 0, sizeof(mServerConn)); } +bool P2pServer::registerWithStack() +{ + static const char fn [] = "P2pServer::registerWithStack"; + ALOGD ("%s: enter; service name: %s JNI handle: %u", fn, mServiceName.c_str(), mJniHandle); + tNFA_STATUS stat = NFA_STATUS_OK; + UINT8 serverSap = NFA_P2P_ANY_SAP; + + /********************** + default values for all LLCP parameters: + - 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) + ************************/ + stat = NFA_P2pSetLLCPConfig (LLCP_MIU, + LLCP_OPT_VALUE, + LLCP_WAITING_TIME, + LLCP_LTO_VALUE, + 0, //use 0 for infinite timeout for symmetry procedure when acting as initiator + 0, //use 0 for infinite timeout for symmetry procedure when acting as target + LLCP_DELAY_RESP_TIME, + LLCP_DATA_LINK_CONNECTION_TOUT, + LLCP_DELAY_TIME_TO_SEND_FIRST_PDU); + if (stat != NFA_STATUS_OK) + ALOGE ("%s: fail set LLCP config; error=0x%X", fn, stat); + + if (sSnepServiceName.compare(mServiceName) == 0) + serverSap = LLCP_SAP_SNEP; //LLCP_SAP_SNEP == 4 + + { + SyncEventGuard guard (mRegServerEvent); + stat = NFA_P2pRegisterServer (serverSap, NFA_P2P_DLINK_TYPE, const_cast<char*>(mServiceName.c_str()), + PeerToPeer::nfaServerCallback); + if (stat != NFA_STATUS_OK) + { + ALOGE ("%s: fail register p2p server; error=0x%X", fn, stat); + return (false); + } + ALOGD ("%s: wait for listen-completion event", fn); + // Wait for NFA_P2P_REG_SERVER_EVT + mRegServerEvent.wait (); + } + + return (mNfaP2pServerHandle != NFA_HANDLE_INVALID); +} + +bool P2pServer::accept(PeerToPeer::tJNI_HANDLE serverJniHandle, PeerToPeer::tJNI_HANDLE connJniHandle, + int maxInfoUnit, int recvWindow) +{ + static const char fn [] = "P2pServer::accept"; + tNFA_STATUS nfaStat = NFA_STATUS_OK; + + sp<NfaConn> connection = allocateConnection(connJniHandle); + if (connection == NULL) { + ALOGE ("%s: failed to allocate new server connection", fn); + return false; + } + + { + // Wait for NFA_P2P_CONN_REQ_EVT or NFA_NDEF_DATA_EVT when remote device requests connection + SyncEventGuard guard (mConnRequestEvent); + ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; wait for incoming connection", fn, + serverJniHandle, connJniHandle); + mConnRequestEvent.wait(); + ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X; got incoming connection", fn, + serverJniHandle, connJniHandle, connection->mNfaConnHandle); + } + + if (connection->mNfaConnHandle == NFA_HANDLE_INVALID) + { + removeServerConnection(connJniHandle); + ALOGD ("%s: no handle assigned", fn); + return (false); + } + + ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X; try accept", fn, + serverJniHandle, connJniHandle, connection->mNfaConnHandle); + nfaStat = NFA_P2pAcceptConn (connection->mNfaConnHandle, maxInfoUnit, recvWindow); + + if (nfaStat != NFA_STATUS_OK) + { + ALOGE ("%s: fail to accept remote; error=0x%X", fn, nfaStat); + return (false); + } + + ALOGD ("%s: exit; serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X", fn, + serverJniHandle, connJniHandle, connection->mNfaConnHandle); + return (true); +} + +void P2pServer::unblockAll() +{ + AutoMutex mutex(mMutex); + for (int jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) + { + if (mServerConn[jj] != NULL) + { + mServerConn[jj]->mNfaConnHandle = NFA_HANDLE_INVALID; + { + SyncEventGuard guard1 (mServerConn[jj]->mCongEvent); + mServerConn[jj]->mCongEvent.notifyOne (); //unblock write (if congested) + } + { + SyncEventGuard guard2 (mServerConn[jj]->mReadEvent); + mServerConn[jj]->mReadEvent.notifyOne (); //unblock receive() + } + } + } +} + +sp<NfaConn> P2pServer::allocateConnection (PeerToPeer::tJNI_HANDLE jniHandle) +{ + AutoMutex mutex(mMutex); + // First, find a free connection block to handle the connection + for (int ii = 0; ii < MAX_NFA_CONNS_PER_SERVER; ii++) + { + if (mServerConn[ii] == NULL) + { + mServerConn[ii] = new NfaConn; + mServerConn[ii]->mJniHandle = jniHandle; + return mServerConn[ii]; + } + } + + return NULL; +} + /******************************************************************************* ** @@ -1659,10 +1705,11 @@ P2pServer::P2pServer() ** Returns: P2pServer object. ** *******************************************************************************/ -NfaConn *P2pServer::findServerConnection (tNFA_HANDLE nfaConnHandle) +sp<NfaConn> P2pServer::findServerConnection (tNFA_HANDLE nfaConnHandle) { int jj = 0; + AutoMutex mutex(mMutex); for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) { if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mNfaConnHandle == nfaConnHandle) ) @@ -1673,7 +1720,57 @@ NfaConn *P2pServer::findServerConnection (tNFA_HANDLE nfaConnHandle) return (NULL); } +/******************************************************************************* +** +** Function: findServerConnection +** +** Description: Find a P2pServer that has the handle. +** nfaConnHandle: NFA connection handle. +** +** Returns: P2pServer object. +** +*******************************************************************************/ +sp<NfaConn> P2pServer::findServerConnection (PeerToPeer::tJNI_HANDLE jniHandle) +{ + int jj = 0; + + AutoMutex mutex(mMutex); + for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) + { + if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mJniHandle == jniHandle) ) + return (mServerConn[jj]); + } + + // If here, not found + return (NULL); +} + +/******************************************************************************* +** +** Function: removeServerConnection +** +** Description: Find a P2pServer that has the handle. +** nfaConnHandle: NFA connection handle. +** +** Returns: P2pServer object. +** +*******************************************************************************/ +bool P2pServer::removeServerConnection (PeerToPeer::tJNI_HANDLE jniHandle) +{ + int jj = 0; + AutoMutex mutex(mMutex); + for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) + { + if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mJniHandle == jniHandle) ) { + mServerConn[jj] = NULL; + return true; + } + } + + // If here, not found + return false; +} ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// @@ -1691,6 +1788,7 @@ P2pClient::P2pClient () : mNfaP2pClientHandle (NFA_HANDLE_INVALID), mIsConnecting (false) { + mClientConn = new NfaConn(); } |