diff options
Diffstat (limited to 'nci')
-rw-r--r-- | nci/jni/Android.mk | 5 | ||||
-rw-r--r-- | nci/jni/IntervalTimer.cpp | 8 | ||||
-rw-r--r-- | nci/jni/JavaClassConstants.h | 1 | ||||
-rw-r--r-- | nci/jni/NativeLlcpConnectionlessSocket.cpp | 81 | ||||
-rw-r--r-- | nci/jni/NativeLlcpServiceSocket.cpp | 3 | ||||
-rw-r--r-- | nci/jni/NativeLlcpSocket.cpp | 90 | ||||
-rwxr-xr-x | nci/jni/NativeNfcManager.cpp | 370 | ||||
-rwxr-xr-x | nci/jni/NativeNfcTag.cpp | 112 | ||||
-rw-r--r-- | nci/jni/NativeP2pDevice.cpp | 10 | ||||
-rwxr-xr-x | nci/jni/NativeSecureElement.cpp | 48 | ||||
-rwxr-xr-x | nci/jni/NfcJniUtil.cpp | 52 | ||||
-rwxr-xr-x | nci/jni/NfcJniUtil.h | 17 | ||||
-rwxr-xr-x | nci/jni/NfcTag.cpp | 225 | ||||
-rw-r--r-- | nci/jni/PeerToPeer.cpp | 130 | ||||
-rw-r--r-- | nci/jni/PeerToPeer.h | 15 | ||||
-rw-r--r-- | nci/jni/RouteDataSet.cpp | 1 | ||||
-rwxr-xr-x | nci/jni/SecureElement.cpp | 119 | ||||
-rwxr-xr-x | nci/jni/SecureElement.h | 11 | ||||
-rwxr-xr-x | nci/src/com/android/nfc/dhimpl/NativeNfcManager.java | 7 | ||||
-rwxr-xr-x | nci/src/com/android/nfc/dhimpl/NativeNfcTag.java | 7 |
20 files changed, 677 insertions, 635 deletions
diff --git a/nci/jni/Android.mk b/nci/jni/Android.mk index 39832fdb..c84ca1a5 100644 --- a/nci/jni/Android.mk +++ b/nci/jni/Android.mk @@ -10,6 +10,8 @@ ifneq ($(NCI_VERSION),) LOCAL_CFLAGS += -DNCI_VERSION=$(NCI_VERSION) -O0 -g endif +LOCAL_CFLAGS += -Wall -Wextra + define all-cpp-files-under $(patsubst ./%,%, \ $(shell cd $(LOCAL_PATH) ; \ @@ -26,6 +28,7 @@ LOCAL_C_INCLUDES += \ external/libxml2/include \ external/icu4c/common \ frameworks/native/include \ + libcore/include \ $(NFA)/include \ $(NFA)/brcm \ $(NFC)/include \ @@ -42,6 +45,7 @@ LOCAL_SHARED_LIBRARIES := \ libnativehelper \ libcutils \ libutils \ + liblog \ libnfc-nci \ libstlport @@ -51,4 +55,3 @@ LOCAL_MODULE := libnfc_nci_jni LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) - diff --git a/nci/jni/IntervalTimer.cpp b/nci/jni/IntervalTimer.cpp index f71ca8e9..9453451d 100644 --- a/nci/jni/IntervalTimer.cpp +++ b/nci/jni/IntervalTimer.cpp @@ -24,14 +24,14 @@ IntervalTimer::IntervalTimer() { - mTimerId = NULL; + mTimerId = 0; mCb = NULL; } bool IntervalTimer::set(int ms, TIMER_FUNC cb) { - if (mTimerId == NULL) + if (mTimerId == 0) { if (cb == NULL) return false; @@ -69,11 +69,11 @@ IntervalTimer::~IntervalTimer() void IntervalTimer::kill() { - if (mTimerId == NULL) + if (mTimerId == 0) return; timer_delete(mTimerId); - mTimerId = NULL; + mTimerId = 0; mCb = NULL; } diff --git a/nci/jni/JavaClassConstants.h b/nci/jni/JavaClassConstants.h index 30deca94..4b54db8a 100644 --- a/nci/jni/JavaClassConstants.h +++ b/nci/jni/JavaClassConstants.h @@ -22,6 +22,7 @@ namespace android extern jmethodID gCachedNfcManagerNotifyTransactionListeners; extern jmethodID gCachedNfcManagerNotifyLlcpLinkActivation; extern jmethodID gCachedNfcManagerNotifyLlcpLinkDeactivated; + extern jmethodID gCachedNfcManagerNotifyLlcpFirstPacketReceived; extern jmethodID gCachedNfcManagerNotifySeFieldActivated; extern jmethodID gCachedNfcManagerNotifySeFieldDeactivated; extern jmethodID gCachedNfcManagerNotifySeListenActivated; diff --git a/nci/jni/NativeLlcpConnectionlessSocket.cpp b/nci/jni/NativeLlcpConnectionlessSocket.cpp index ecc57e3a..99a4b227 100644 --- a/nci/jni/NativeLlcpConnectionlessSocket.cpp +++ b/nci/jni/NativeLlcpConnectionlessSocket.cpp @@ -19,6 +19,8 @@ #include "OverrideLog.h" #include "NfcJniUtil.h" #include "JavaClassConstants.h" +#include <ScopedLocalRef.h> +#include <ScopedPrimitiveArray.h> extern "C" { #include "nfa_api.h" @@ -57,29 +59,25 @@ static uint32_t sConnlessRecvRemoteSap = 0; *******************************************************************************/ static jboolean nativeLlcpConnectionlessSocket_doSendTo (JNIEnv *e, jobject o, jint nsap, jbyteArray data) { - tNFA_STATUS status = NFA_STATUS_FAILED; - jint handle = 0; - uint8_t* buf = NULL; - uint32_t len = 0; - jclass c = NULL; - jfieldID f = NULL; - ALOGD ("%s: nsap = %d", __FUNCTION__, nsap); - c = e->GetObjectClass (o); - f = e->GetFieldID (c, "mHandle", "I"); - handle = e->GetIntField (o, f); + ScopedLocalRef<jclass> c(e, e->GetObjectClass(o)); + jfieldID f = e->GetFieldID(c.get(), "mHandle", "I"); + jint handle = e->GetIntField(o, f); - buf = (uint8_t*) e->GetByteArrayElements (data, NULL); - len = (uint32_t) e->GetArrayLength (data); + ScopedByteArrayRO bytes(e, data); + if (bytes.get() == NULL) { + return JNI_FALSE; + } + size_t byte_count = bytes.size(); - ALOGD ("NFA_P2pSendUI: len = %d", len); - status = NFA_P2pSendUI ((tNFA_HANDLE) handle, nsap, len, buf); + ALOGD("NFA_P2pSendUI: len = %d", byte_count); + UINT8* raw_ptr = const_cast<UINT8*>(reinterpret_cast<const UINT8*>(&bytes[0])); // TODO: API bug; NFA_P2pSendUI should take const*! + tNFA_STATUS status = NFA_P2pSendUI((tNFA_HANDLE) handle, nsap, byte_count, raw_ptr); - ALOGD ("%s: NFA_P2pSendUI done, status = %d", __FUNCTION__, status); - if (status != NFA_STATUS_OK) - { - ALOGE ("%s: NFA_P2pSendUI failed, status = %d", __FUNCTION__, status); + ALOGD("%s: NFA_P2pSendUI done, status = %d", __FUNCTION__, status); + if (status != NFA_STATUS_OK) { + ALOGE("%s: NFA_P2pSendUI failed, status = %d", __FUNCTION__, status); return JNI_FALSE; } return JNI_TRUE; @@ -169,14 +167,11 @@ void nativeLlcpConnectionlessSocket_abortWait () ** Returns: LlcpPacket Java object. ** *******************************************************************************/ -static jobject nativeLlcpConnectionlessSocket_doReceiveFrom (JNIEnv *e, jobject o, jint linkMiu) +static jobject nativeLlcpConnectionlessSocket_doReceiveFrom (JNIEnv* e, jobject, jint linkMiu) { - jbyteArray receivedData = NULL; - jobject llcpPacket = NULL; - jclass clsLlcpPacket = NULL; - jfieldID f = NULL; - ALOGD ("%s: linkMiu = %d", __FUNCTION__, linkMiu); + jobject llcpPacket = NULL; + ScopedLocalRef<jclass> clsLlcpPacket(e, NULL); if (sConnlessRecvWaitingForData != JNI_FALSE) { @@ -216,8 +211,8 @@ static jobject nativeLlcpConnectionlessSocket_doReceiveFrom (JNIEnv *e, jobject } // Get NativeConnectionless class object - clsLlcpPacket = e->GetObjectClass (llcpPacket); - if (e->ExceptionCheck ()) + clsLlcpPacket.reset(e->GetObjectClass(llcpPacket)); + if (e->ExceptionCheck()) { e->ExceptionClear(); ALOGE ("%s: Get Object class error", __FUNCTION__); @@ -225,17 +220,21 @@ static jobject nativeLlcpConnectionlessSocket_doReceiveFrom (JNIEnv *e, jobject } // Set Llcp Packet remote SAP - f = e->GetFieldID (clsLlcpPacket, "mRemoteSap", "I"); - e->SetIntField (llcpPacket, f, (jbyte) sConnlessRecvRemoteSap); + jfieldID f; + f = e->GetFieldID(clsLlcpPacket.get(), "mRemoteSap", "I"); + e->SetIntField(llcpPacket, f, (jbyte) sConnlessRecvRemoteSap); // Set Llcp Packet Buffer ALOGD ("%s: Received Llcp packet buffer size = %d\n", __FUNCTION__, sConnlessRecvLen); - f = e->GetFieldID (clsLlcpPacket, "mDataBuffer", "[B"); - receivedData = e->NewByteArray (sConnlessRecvLen); - e->SetByteArrayRegion (receivedData, 0, sConnlessRecvLen, (jbyte*) sConnlessRecvBuf); - e->SetObjectField (llcpPacket, f, receivedData); + f = e->GetFieldID(clsLlcpPacket.get(), "mDataBuffer", "[B"); + + { + ScopedLocalRef<jbyteArray> receivedData(e, e->NewByteArray(sConnlessRecvLen)); + e->SetByteArrayRegion(receivedData.get(), 0, sConnlessRecvLen, (jbyte*) sConnlessRecvBuf); + e->SetObjectField(llcpPacket, f, receivedData.get()); + } -TheEnd: +TheEnd: // TODO: should all the "return connectionlessCleanup()"s in this function jump here instead? connectionlessCleanup (); if (sem_destroy (&sConnlessRecvSem)) { @@ -258,20 +257,14 @@ TheEnd: *******************************************************************************/ static jboolean nativeLlcpConnectionlessSocket_doClose (JNIEnv *e, jobject o) { - tNFA_STATUS status = NFA_STATUS_FAILED; - jint handle = 0; - jclass c = NULL; - jfieldID f = NULL; - ALOGD ("%s", __FUNCTION__); - c = e->GetObjectClass (o); - f = e->GetFieldID (c, "mHandle", "I"); - handle = e->GetIntField (o, f); + ScopedLocalRef<jclass> c(e, e->GetObjectClass(o)); + jfieldID f = e->GetFieldID(c.get(), "mHandle", "I"); + jint handle = e->GetIntField(o, f); - status = NFA_P2pDisconnect ((tNFA_HANDLE) handle, FALSE); - if (status != NFA_STATUS_OK) - { + tNFA_STATUS status = NFA_P2pDisconnect((tNFA_HANDLE) handle, FALSE); + if (status != NFA_STATUS_OK) { ALOGE ("%s: disconnect failed, status = %d", __FUNCTION__, status); return JNI_FALSE; } diff --git a/nci/jni/NativeLlcpServiceSocket.cpp b/nci/jni/NativeLlcpServiceSocket.cpp index e1c2bb5d..17145efa 100644 --- a/nci/jni/NativeLlcpServiceSocket.cpp +++ b/nci/jni/NativeLlcpServiceSocket.cpp @@ -44,7 +44,7 @@ namespace android ** Returns: LlcpSocket Java object. ** *******************************************************************************/ -static jobject nativeLlcpServiceSocket_doAccept(JNIEnv *e, jobject o, jint miu, jint rw, jint linearBufferLength) +static jobject nativeLlcpServiceSocket_doAccept(JNIEnv *e, jobject o, jint miu, jint rw, jint /*linearBufferLength*/) { jobject clientSocket = NULL; jclass clsNativeLlcpSocket = NULL; @@ -155,4 +155,3 @@ int register_com_android_nfc_NativeLlcpServiceSocket (JNIEnv* e) } //namespace android - diff --git a/nci/jni/NativeLlcpSocket.cpp b/nci/jni/NativeLlcpSocket.cpp index 74a59b9f..ad03506b 100644 --- a/nci/jni/NativeLlcpSocket.cpp +++ b/nci/jni/NativeLlcpSocket.cpp @@ -16,6 +16,8 @@ #include "OverrideLog.h" #include "PeerToPeer.h" #include "JavaClassConstants.h" +#include <ScopedPrimitiveArray.h> +#include <ScopedUtfChars.h> namespace android @@ -36,20 +38,13 @@ namespace android *******************************************************************************/ static jboolean nativeLlcpSocket_doConnect (JNIEnv* e, jobject o, jint nSap) { - bool stat = false; - jboolean retVal = JNI_FALSE; - ALOGD ("%s: enter; sap=%d", __FUNCTION__, nSap); - PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle (e,o); - - stat = PeerToPeer::getInstance().connectConnOriented (jniHandle, nSap); - - if (stat) - retVal = JNI_TRUE; + PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); + bool stat = PeerToPeer::getInstance().connectConnOriented (jniHandle, nSap); ALOGD ("%s: exit", __FUNCTION__); - return retVal; + return stat ? JNI_TRUE : JNI_FALSE; } @@ -68,22 +63,17 @@ static jboolean nativeLlcpSocket_doConnect (JNIEnv* e, jobject o, jint nSap) static jboolean nativeLlcpSocket_doConnectBy (JNIEnv* e, jobject o, jstring sn) { ALOGD ("%s: enter", __FUNCTION__); - bool stat = false; - jboolean retVal = JNI_FALSE; - - PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle (e,o); - const char* serviceName = e->GetStringUTFChars (sn, JNI_FALSE); //convert jstring, which is unicode, into char* + PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); - stat = PeerToPeer::getInstance().connectConnOriented (jniHandle, serviceName); - - e->ReleaseStringUTFChars (sn, serviceName); //free the string - - if (stat) - retVal = JNI_TRUE; + ScopedUtfChars serviceName(e, sn); + if (serviceName.c_str() == NULL) { + return JNI_FALSE; + } + bool stat = PeerToPeer::getInstance().connectConnOriented(jniHandle, serviceName.c_str()); ALOGD ("%s: exit", __FUNCTION__); - return retVal; + return stat ? JNI_TRUE : JNI_FALSE; } @@ -101,16 +91,12 @@ static jboolean nativeLlcpSocket_doConnectBy (JNIEnv* e, jobject o, jstring sn) static jboolean nativeLlcpSocket_doClose(JNIEnv *e, jobject o) { ALOGD ("%s: enter", __FUNCTION__); - bool stat = false; - jboolean retVal = JNI_FALSE; - - PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle (e,o); - stat = PeerToPeer::getInstance().disconnectConnOriented (jniHandle); + PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); + bool stat = PeerToPeer::getInstance().disconnectConnOriented (jniHandle); - retVal = JNI_TRUE; ALOGD ("%s: exit", __FUNCTION__); - return retVal; + return JNI_TRUE; // TODO: stat? } @@ -129,15 +115,12 @@ static jboolean nativeLlcpSocket_doClose(JNIEnv *e, jobject o) static jboolean nativeLlcpSocket_doSend (JNIEnv* e, jobject o, jbyteArray data) { ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter", __FUNCTION__); - uint8_t* dataBuffer = (uint8_t*) e->GetByteArrayElements (data, NULL); - uint32_t dataBufferLen = (uint32_t) e->GetArrayLength (data); - bool stat = false; - PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle (e,o); + ScopedByteArrayRO bytes(e, data); - stat = PeerToPeer::getInstance().send (jniHandle, dataBuffer, dataBufferLen); - - e->ReleaseByteArrayElements (data, (jbyte*) dataBuffer, JNI_ABORT); + PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); + UINT8* raw_ptr = const_cast<UINT8*>(reinterpret_cast<const UINT8*>(&bytes[0])); // TODO: API bug: send should take const*! + bool stat = PeerToPeer::getInstance().send(jniHandle, raw_ptr, bytes.size()); ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit", __FUNCTION__); return stat ? JNI_TRUE : JNI_FALSE; @@ -159,24 +142,20 @@ static jboolean nativeLlcpSocket_doSend (JNIEnv* e, jobject o, jbyteArray data) static jint nativeLlcpSocket_doReceive(JNIEnv *e, jobject o, jbyteArray origBuffer) { ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter", __FUNCTION__); - uint8_t* dataBuffer = (uint8_t*) e->GetByteArrayElements (origBuffer, NULL); - uint32_t dataBufferLen = (uint32_t) e->GetArrayLength (origBuffer); - uint16_t actualLen = 0; - bool stat = false; - jint retval = 0; - PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle (e,o); + ScopedByteArrayRW bytes(e, origBuffer); - stat = PeerToPeer::getInstance().receive (jniHandle, dataBuffer, dataBufferLen, actualLen); + PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); + uint16_t actualLen = 0; + bool stat = PeerToPeer::getInstance().receive(jniHandle, reinterpret_cast<UINT8*>(&bytes[0]), bytes.size(), actualLen); - if (stat && (actualLen>0)) - { + jint retval = 0; + if (stat && (actualLen>0)) { retval = actualLen; - } - else + } else { retval = -1; + } - e->ReleaseByteArrayElements (origBuffer, (jbyte*) dataBuffer, 0); ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit; actual len=%d", __FUNCTION__, retval); return retval; } @@ -196,12 +175,9 @@ static jint nativeLlcpSocket_doReceive(JNIEnv *e, jobject o, jbyteArray origBuff static jint nativeLlcpSocket_doGetRemoteSocketMIU (JNIEnv* e, jobject o) { ALOGD ("%s: enter", __FUNCTION__); - bool stat = false; - - PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle (e,o); - jint miu = 0; - miu = PeerToPeer::getInstance().getRemoteMaxInfoUnit (jniHandle); + PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); + jint miu = PeerToPeer::getInstance().getRemoteMaxInfoUnit(jniHandle); ALOGD ("%s: exit", __FUNCTION__); return miu; @@ -222,12 +198,9 @@ static jint nativeLlcpSocket_doGetRemoteSocketMIU (JNIEnv* e, jobject o) static jint nativeLlcpSocket_doGetRemoteSocketRW (JNIEnv* e, jobject o) { ALOGD ("%s: enter", __FUNCTION__); - bool stat = false; - jint rw = 0; - PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle (e,o); - - rw = PeerToPeer::getInstance().getRemoteRecvWindow (jniHandle); + PeerToPeer::tJNI_HANDLE jniHandle = (PeerToPeer::tJNI_HANDLE) nfc_jni_get_nfc_socket_handle(e, o); + jint rw = PeerToPeer::getInstance().getRemoteRecvWindow (jniHandle); ALOGD ("%s: exit", __FUNCTION__); return rw; @@ -268,4 +241,3 @@ int register_com_android_nfc_NativeLlcpSocket (JNIEnv* e) } //namespace android - diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp index 61fc0520..e4ea20e2 100755 --- a/nci/jni/NativeNfcManager.cpp +++ b/nci/jni/NativeNfcManager.cpp @@ -27,6 +27,8 @@ #include "PowerSwitch.h" #include "JavaClassConstants.h" #include "Pn544Interop.h" +#include <ScopedLocalRef.h> +#include <ScopedUtfChars.h> extern "C" { @@ -35,11 +37,9 @@ extern "C" #include "rw_api.h" #include "nfa_ee_api.h" #include "nfc_brcm_defs.h" - #include "nfa_cho_api.h" #include "ce_api.h" } -extern UINT8 *p_nfa_dm_lptd_cfg; extern UINT8 *p_nfa_dm_start_up_cfg; extern const UINT8 nfca_version_string []; namespace android @@ -76,6 +76,7 @@ namespace android jmethodID gCachedNfcManagerNotifyTransactionListeners; jmethodID gCachedNfcManagerNotifyLlcpLinkActivation; jmethodID gCachedNfcManagerNotifyLlcpLinkDeactivated; + jmethodID gCachedNfcManagerNotifyLlcpFirstPacketReceived; jmethodID gCachedNfcManagerNotifySeFieldActivated; jmethodID gCachedNfcManagerNotifySeFieldDeactivated; jmethodID gCachedNfcManagerNotifySeListenActivated; @@ -90,6 +91,7 @@ namespace android void doStartupConfig (); void startStopPolling (bool isStartPolling); void startRfDiscovery (bool isStart); + void setUiccIdleTimeout (bool enable); } @@ -109,20 +111,15 @@ static SyncEvent sNfaEnableEvent; //event for NFA_Enable() static SyncEvent sNfaDisableEvent; //event for NFA_Disable() static SyncEvent sNfaEnableDisablePollingEvent; //event for NFA_EnablePolling(), NFA_DisablePolling() static SyncEvent sNfaSetConfigEvent; // event for Set_Config.... +static SyncEvent sNfaGetConfigEvent; // event for Get_Config.... static bool sIsNfaEnabled = false; static bool sDiscoveryEnabled = false; //is polling for tag? static bool sIsDisabling = false; static bool sRfEnabled = false; // whether RF discovery is enabled static bool sSeRfActive = false; // whether RF with SE is likely active static bool sP2pActive = false; // whether p2p was last active -static int sConnlessSap = 0; -static int sConnlessLinkMiu = 0; static bool sAbortConnlessWait = false; static bool sIsSecElemSelected = false; //has NFC service selected a sec elem -static UINT8 * sOriginalLptdCfg = NULL; -static UINT8 sNewLptdCfg[LPTD_PARAM_LEN]; -static UINT32 sConfigUpdated = 0; -#define CONFIG_UPDATE_LPTD (1 << 0) #define CONFIG_UPDATE_TECH_MASK (1 << 1) #define DEFAULT_TECH_MASK (NFA_TECHNOLOGY_MASK_A \ | NFA_TECHNOLOGY_MASK_B \ @@ -130,7 +127,8 @@ static UINT32 sConfigUpdated = 0; | NFA_TECHNOLOGY_MASK_ISO15693 \ | NFA_TECHNOLOGY_MASK_B_PRIME \ | NFA_TECHNOLOGY_MASK_A_ACTIVE \ - | NFA_TECHNOLOGY_MASK_F_ACTIVE) + | NFA_TECHNOLOGY_MASK_F_ACTIVE \ + | NFA_TECHNOLOGY_MASK_KOVIO) static void nfaConnectionCallback (UINT8 event, tNFA_CONN_EVT_DATA *eventData); @@ -138,6 +136,8 @@ static void nfaDeviceManagementCallback (UINT8 event, tNFA_DM_CBACK_DATA *eventD static bool isPeerToPeer (tNFA_ACTIVATED& activated); static bool isListenMode(tNFA_ACTIVATED& activated); +static UINT16 sCurrentConfigLen; +static UINT8 sConfig[256]; ///////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// @@ -210,7 +210,13 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat tNFA_STATUS status = NFA_STATUS_FAILED; ALOGD("%s: event= %u", __FUNCTION__, connEvent); - if (gIsTagDeactivating && connEvent != NFA_DEACTIVATED_EVT && connEvent != NFA_PRESENCE_CHECK_EVT && connEvent != NFA_DATA_EVT) + // TODO this if can probably be completely removed. It's unclear why this + // was present in the initial code drop - either to work around NFCC, + // stack or certain NFC tags bugs. Until we verify removing it doesn't + // break things, leave it be. + if (gIsTagDeactivating && connEvent != NFA_DEACTIVATED_EVT && + connEvent != NFA_PRESENCE_CHECK_EVT && connEvent != NFA_DATA_EVT && + connEvent != NFA_RW_INTF_ERROR_EVT) { // special case to switching frame interface for ISO_DEP tags gIsTagDeactivating = false; @@ -294,7 +300,7 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat case NFA_ACTIVATED_EVT: // NFC link/protocol activated ALOGD("%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d", __FUNCTION__, gIsSelectingRfInterface, sIsDisabling); - if (sIsDisabling) + if (sIsDisabling || !sIsNfaEnabled) break; NfcTag::getInstance().setActivationState (); @@ -319,13 +325,15 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat } else { ALOGE ("%s: Failed to disable RF field events", __FUNCTION__); } + // For the SE, consider the field to be on while p2p is active. + SecureElement::getInstance().notifyRfFieldEvent (true); } else if (pn544InteropIsBusy() == false) { NfcTag::getInstance().connectionEventHandler (connEvent, eventData); // We know it is not activating for P2P. If it activated in - // listen mode then it is likely for and SE transaction. + // listen mode then it is likely for an SE transaction. // Send the RF Event. if (isListenMode(eventData->activated)) { @@ -358,21 +366,27 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat { if (sSeRfActive) { sSeRfActive = false; - SecureElement::getInstance().notifyListenModeState (false); + if (!sIsDisabling && sIsNfaEnabled) + SecureElement::getInstance().notifyListenModeState (false); } else if (sP2pActive) { sP2pActive = false; // Make sure RF field events are re-enabled - ALOGD("%s: NFA_ACTIVATED_EVT; is p2p", __FUNCTION__); + ALOGD("%s: NFA_DEACTIVATED_EVT; is p2p", __FUNCTION__); // Disable RF field events in case of p2p UINT8 nfa_enable_rf_events[] = { 0x01 }; - ALOGD ("%s: Enabling RF field events", __FUNCTION__); - status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, sizeof(nfa_enable_rf_events), - &nfa_enable_rf_events[0]); - if (status == NFA_STATUS_OK) { - ALOGD ("%s: Enabled RF field events", __FUNCTION__); - } else { - ALOGE ("%s: Failed to enable RF field events", __FUNCTION__); + if (!sIsDisabling && sIsNfaEnabled) + { + ALOGD ("%s: Enabling RF field events", __FUNCTION__); + status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, sizeof(nfa_enable_rf_events), + &nfa_enable_rf_events[0]); + if (status == NFA_STATUS_OK) { + ALOGD ("%s: Enabled RF field events", __FUNCTION__); + } else { + ALOGE ("%s: Failed to enable RF field events", __FUNCTION__); + } + // Consider the field to be off at this point + SecureElement::getInstance().notifyRfFieldEvent (false); } } } @@ -462,12 +476,14 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat ALOGD("%s: NFA_LLCP_DEACTIVATED_EVT", __FUNCTION__); PeerToPeer::getInstance().llcpDeactivatedHandler (getNative(0, 0), eventData->llcp_deactivated); break; - + case NFA_LLCP_FIRST_PACKET_RECEIVED_EVT: // Received first packet over llcp + ALOGD("%s: NFA_LLCP_FIRST_PACKET_RECEIVED_EVT", __FUNCTION__); + PeerToPeer::getInstance().llcpFirstPacketHandler (getNative(0, 0)); + break; case NFA_PRESENCE_CHECK_EVT: ALOGD("%s: NFA_PRESENCE_CHECK_EVT", __FUNCTION__); nativeNfcTag_doPresenceCheckResult (eventData->status); break; - case NFA_FORMAT_CPLT_EVT: ALOGD("%s: NFA_FORMAT_CPLT_EVT: status=0x%X", __FUNCTION__, eventData->status); nativeNfcTag_formatStatus (eventData->status == NFA_STATUS_OK); @@ -507,14 +523,9 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat *******************************************************************************/ static jboolean nfcManager_initNativeStruc (JNIEnv* e, jobject o) { - nfc_jni_native_data* nat = NULL; - jclass cls = NULL; - jobject obj = NULL; - jfieldID f = 0; - ALOGD ("%s: enter", __FUNCTION__); - nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); + nfc_jni_native_data* nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); if (nat == NULL) { ALOGE ("%s: fail allocate native data", __FUNCTION__); @@ -522,50 +533,52 @@ static jboolean nfcManager_initNativeStruc (JNIEnv* e, jobject o) } memset (nat, 0, sizeof(*nat)); - e->GetJavaVM (&(nat->vm)); - nat->env_version = e->GetVersion (); - nat->manager = e->NewGlobalRef (o); + e->GetJavaVM(&(nat->vm)); + nat->env_version = e->GetVersion(); + nat->manager = e->NewGlobalRef(o); - cls = e->GetObjectClass (o); - f = e->GetFieldID (cls, "mNative", "I"); - e->SetIntField (o, f, (jint)nat); + ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o)); + jfieldID f = e->GetFieldID(cls.get(), "mNative", "I"); + e->SetIntField(o, f, (jint)nat); /* Initialize native cached references */ - gCachedNfcManagerNotifyNdefMessageListeners = e->GetMethodID (cls, + gCachedNfcManagerNotifyNdefMessageListeners = e->GetMethodID(cls.get(), "notifyNdefMessageListeners", "(Lcom/android/nfc/dhimpl/NativeNfcTag;)V"); - gCachedNfcManagerNotifyTransactionListeners = e->GetMethodID (cls, + gCachedNfcManagerNotifyTransactionListeners = e->GetMethodID(cls.get(), "notifyTransactionListeners", "([B)V"); - gCachedNfcManagerNotifyLlcpLinkActivation = e->GetMethodID (cls, + gCachedNfcManagerNotifyLlcpLinkActivation = e->GetMethodID(cls.get(), "notifyLlcpLinkActivation", "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); - gCachedNfcManagerNotifyLlcpLinkDeactivated = e->GetMethodID (cls, + gCachedNfcManagerNotifyLlcpLinkDeactivated = e->GetMethodID(cls.get(), "notifyLlcpLinkDeactivated", "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); - sCachedNfcManagerNotifyTargetDeselected = e->GetMethodID (cls, + gCachedNfcManagerNotifyLlcpFirstPacketReceived = e->GetMethodID(cls.get(), + "notifyLlcpLinkFirstPacketReceived", "(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V"); + sCachedNfcManagerNotifyTargetDeselected = e->GetMethodID(cls.get(), "notifyTargetDeselected","()V"); - gCachedNfcManagerNotifySeFieldActivated = e->GetMethodID (cls, + gCachedNfcManagerNotifySeFieldActivated = e->GetMethodID(cls.get(), "notifySeFieldActivated", "()V"); - gCachedNfcManagerNotifySeFieldDeactivated = e->GetMethodID (cls, + gCachedNfcManagerNotifySeFieldDeactivated = e->GetMethodID(cls.get(), "notifySeFieldDeactivated", "()V"); - gCachedNfcManagerNotifySeListenActivated = e->GetMethodID (cls, + gCachedNfcManagerNotifySeListenActivated = e->GetMethodID(cls.get(), "notifySeListenActivated", "()V"); - gCachedNfcManagerNotifySeListenDeactivated = e->GetMethodID (cls, + gCachedNfcManagerNotifySeListenDeactivated = e->GetMethodID(cls.get(), "notifySeListenDeactivated", "()V"); - sCachedNfcManagerNotifySeApduReceived = e->GetMethodID(cls, + sCachedNfcManagerNotifySeApduReceived = e->GetMethodID(cls.get(), "notifySeApduReceived", "([B)V"); - sCachedNfcManagerNotifySeMifareAccess = e->GetMethodID(cls, + sCachedNfcManagerNotifySeMifareAccess = e->GetMethodID(cls.get(), "notifySeMifareAccess", "([B)V"); - sCachedNfcManagerNotifySeEmvCardRemoval = e->GetMethodID(cls, + sCachedNfcManagerNotifySeEmvCardRemoval = e->GetMethodID(cls.get(), "notifySeEmvCardRemoval", "()V"); - if (nfc_jni_cache_object(e,gNativeNfcTagClassName, &(nat->cached_NfcTag)) == -1) + if (nfc_jni_cache_object(e, gNativeNfcTagClassName, &(nat->cached_NfcTag)) == -1) { ALOGE ("%s: fail cache NativeNfcTag", __FUNCTION__); return JNI_FALSE; } - if (nfc_jni_cache_object(e,gNativeP2pDeviceClassName, &(nat->cached_P2pDevice)) == -1) + if (nfc_jni_cache_object(e, gNativeP2pDeviceClassName, &(nat->cached_P2pDevice)) == -1) { ALOGE ("%s: fail cache NativeP2pDevice", __FUNCTION__); return JNI_FALSE; @@ -624,14 +637,32 @@ void nfaDeviceManagementCallback (UINT8 dmEvent, tNFA_DM_CBACK_DATA* eventData) case NFA_DM_GET_CONFIG_EVT: /* Result of NFA_GetConfig */ ALOGD ("%s: NFA_DM_GET_CONFIG_EVT", __FUNCTION__); + { + SyncEventGuard guard (sNfaGetConfigEvent); + if (eventData->status == NFA_STATUS_OK && + eventData->get_config.tlv_size <= sizeof(sConfig)) + { + sCurrentConfigLen = eventData->get_config.tlv_size; + memcpy(sConfig, eventData->get_config.param_tlvs, eventData->get_config.tlv_size); + } + else + { + ALOGE("%s: NFA_DM_GET_CONFIG failed", __FUNCTION__); + sCurrentConfigLen = 0; + } + sNfaGetConfigEvent.notifyOne(); + } break; case NFA_DM_RF_FIELD_EVT: ALOGD ("%s: NFA_DM_RF_FIELD_EVT; status=0x%X; field status=%u", __FUNCTION__, eventData->rf_field.status, eventData->rf_field.rf_field_status); + if (sIsDisabling || !sIsNfaEnabled) + break; - if (!sIsDisabling && eventData->rf_field.status == NFA_STATUS_OK) - SecureElement::getInstance().notifyRfFieldEvent (eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON); + if (!sP2pActive && eventData->rf_field.status == NFA_STATUS_OK) + SecureElement::getInstance().notifyRfFieldEvent ( + eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON); break; case NFA_DM_NFCC_TRANSPORT_ERR_EVT: @@ -735,9 +766,7 @@ static jboolean nfcManager_doInitialize (JNIEnv* e, jobject o) NFC_SetTraceLevel (num); RW_SetTraceLevel (num); NFA_SetTraceLevel (num); - NFA_ChoSetTraceLevel (num); NFA_P2pSetTraceLevel (num); - NFA_SnepSetTraceLevel (num); sNfaEnableEvent.wait(); //wait for NFA command to finish } } @@ -768,10 +797,6 @@ static jboolean nfcManager_doInitialize (JNIEnv* e, jobject o) ALOGD ("%s: tag polling tech mask=0x%X", __FUNCTION__, nat->tech_mask); } - // Always restore LPTD Configuration to the stack default. - if (sOriginalLptdCfg != NULL) - p_nfa_dm_lptd_cfg = sOriginalLptdCfg; - // if this value exists, set polling interval. if (GetNumValue(NAME_NFA_DM_DISC_DURATION_POLL, &num, sizeof(num))) NFA_SetRfDiscoveryDuration(num); @@ -884,7 +909,7 @@ static void nfcManager_enableDiscovery (JNIEnv* e, jobject o) ** Returns: None ** *******************************************************************************/ -void nfcManager_disableDiscovery (JNIEnv* e, jobject o) +void nfcManager_disableDiscovery (JNIEnv*, jobject) { tNFA_STATUS status = NFA_STATUS_OK; ALOGD ("%s: enter;", __FUNCTION__); @@ -918,10 +943,52 @@ void nfcManager_disableDiscovery (JNIEnv* e, jobject o) if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::DISCOVERY)) PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); + // We may have had RF field notifications that did not cause + // any activate/deactive events. For example, caused by wireless + // charging orbs. Those may cause us to go to sleep while the last + // field event was indicating a field. To prevent sticking in that + // state, always reset the rf field status when we disable discovery. + SecureElement::getInstance().resetRfFieldStatus(); TheEnd: ALOGD ("%s: exit", __FUNCTION__); } +void setUiccIdleTimeout (bool enable) +{ + // This method is *NOT* thread-safe. Right now + // it is only called from the same thread so it's + // not an issue. + tNFA_STATUS stat = NFA_STATUS_OK; + UINT8 swp_cfg_byte0 = 0x00; + { + SyncEventGuard guard (sNfaGetConfigEvent); + stat = NFA_GetConfig(1, new tNFA_PMID[1] {0xC2}); + if (stat != NFA_STATUS_OK) + { + ALOGE("%s: NFA_GetConfig failed", __FUNCTION__); + return; + } + sNfaGetConfigEvent.wait (); + if (sCurrentConfigLen < 4 || sConfig[1] != 0xC2) { + ALOGE("%s: Config TLV length %d returned is too short", __FUNCTION__, + sCurrentConfigLen); + return; + } + swp_cfg_byte0 = sConfig[3]; + } + SyncEventGuard guard(sNfaSetConfigEvent); + if (enable) + swp_cfg_byte0 |= 0x01; + else + swp_cfg_byte0 &= ~0x01; + + stat = NFA_SetConfig(0xC2, 1, &swp_cfg_byte0); + if (stat == NFA_STATUS_OK) + sNfaSetConfigEvent.wait (); + else + ALOGE("%s: Could not configure UICC idle timeout feature", __FUNCTION__); + return; +} /******************************************************************************* ** ** Function nfc_jni_cache_object_local @@ -931,35 +998,26 @@ TheEnd: ** Returns -1 on failure, 0 on success ** *******************************************************************************/ -int nfc_jni_cache_object_local (JNIEnv *e, const char *className, jobject *cachedObj) +static int nfc_jni_cache_object_local (JNIEnv *e, const char *className, jobject *cachedObj) { - jclass cls = NULL; - jobject obj = NULL; - jmethodID ctor = 0; - - cls = e->FindClass (className); - if(cls == NULL) - { + ScopedLocalRef<jclass> cls(e, e->FindClass(className)); + if(cls.get() == NULL) { ALOGE ("%s: find class error", __FUNCTION__); return -1; } - ctor = e->GetMethodID (cls, "<init>", "()V"); - obj = e->NewObject (cls, ctor); - if (obj == NULL) - { + jmethodID ctor = e->GetMethodID(cls.get(), "<init>", "()V"); + jobject obj = e->NewObject(cls.get(), ctor); + if (obj == NULL) { ALOGE ("%s: create object error", __FUNCTION__); return -1; } - *cachedObj = e->NewLocalRef (obj); - if (*cachedObj == NULL) - { - e->DeleteLocalRef (obj); + *cachedObj = obj; + if (*cachedObj == NULL) { ALOGE ("%s: global ref error", __FUNCTION__); return -1; } - e->DeleteLocalRef (obj); return 0; } @@ -980,20 +1038,16 @@ int nfc_jni_cache_object_local (JNIEnv *e, const char *className, jobject *cache ** Returns: NativeLlcpServiceSocket Java object. ** *******************************************************************************/ -static jobject nfcManager_doCreateLlcpServiceSocket (JNIEnv* e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength) +static jobject nfcManager_doCreateLlcpServiceSocket (JNIEnv* e, jobject, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength) { - bool stat = false; - jobject serviceSocket = NULL; - jclass clsNativeLlcpServiceSocket = NULL; - jfieldID f = 0; PeerToPeer::tJNI_HANDLE jniHandle = PeerToPeer::getInstance().getNewJniHandle (); - const char* serviceName = e->GetStringUTFChars (sn, JNI_FALSE); //convert jstring, which is unicode, into char* - std::string serviceName2 (serviceName); - e->ReleaseStringUTFChars (sn, serviceName); //free the string - ALOGD ("%s: enter: sap=%i; name=%s; miu=%i; rw=%i; buffLen=%i", __FUNCTION__, nSap, serviceName2.c_str(), miu, rw, linearBufferLength); + ScopedUtfChars serviceName(e, sn); + + ALOGD ("%s: enter: sap=%i; name=%s; miu=%i; rw=%i; buffLen=%i", __FUNCTION__, nSap, serviceName.c_str(), miu, rw, linearBufferLength); /* Create new NativeLlcpServiceSocket object */ + jobject serviceSocket = NULL; if (nfc_jni_cache_object(e, gNativeLlcpServiceSocketClassName, &(serviceSocket)) == -1) { ALOGE ("%s: Llcp socket object creation error", __FUNCTION__); @@ -1001,7 +1055,7 @@ static jobject nfcManager_doCreateLlcpServiceSocket (JNIEnv* e, jobject o, jint } /* Get NativeLlcpServiceSocket class object */ - clsNativeLlcpServiceSocket = e->GetObjectClass (serviceSocket); + ScopedLocalRef<jclass> clsNativeLlcpServiceSocket(e, e->GetObjectClass(serviceSocket)); if (e->ExceptionCheck()) { e->ExceptionClear(); @@ -1009,30 +1063,32 @@ static jobject nfcManager_doCreateLlcpServiceSocket (JNIEnv* e, jobject o, jint return NULL; } - if (!PeerToPeer::getInstance().registerServer (jniHandle, serviceName2.c_str())) + if (!PeerToPeer::getInstance().registerServer (jniHandle, serviceName.c_str())) { ALOGE("%s: RegisterServer error", __FUNCTION__); return NULL; } + jfieldID f; + /* Set socket handle to be the same as the NfaHandle*/ - f = e->GetFieldID (clsNativeLlcpServiceSocket, "mHandle", "I"); - e->SetIntField (serviceSocket, f, (jint) jniHandle); + f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mHandle", "I"); + e->SetIntField(serviceSocket, f, (jint) jniHandle); ALOGD ("%s: socket Handle = 0x%X", __FUNCTION__, jniHandle); /* Set socket linear buffer length */ - f = e->GetFieldID (clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I"); - e->SetIntField (serviceSocket, f,(jint)linearBufferLength); + f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalLinearBufferLength", "I"); + e->SetIntField(serviceSocket, f,(jint)linearBufferLength); ALOGD ("%s: buffer length = %d", __FUNCTION__, linearBufferLength); /* Set socket MIU */ - f = e->GetFieldID (clsNativeLlcpServiceSocket, "mLocalMiu", "I"); - e->SetIntField (serviceSocket, f,(jint)miu); + f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalMiu", "I"); + e->SetIntField(serviceSocket, f,(jint)miu); ALOGD ("%s: MIU = %d", __FUNCTION__, miu); /* Set socket RW */ - f = e->GetFieldID (clsNativeLlcpServiceSocket, "mLocalRw", "I"); - e->SetIntField (serviceSocket, f,(jint)rw); + f = e->GetFieldID(clsNativeLlcpServiceSocket.get(), "mLocalRw", "I"); + e->SetIntField(serviceSocket, f,(jint)rw); ALOGD ("%s: RW = %d", __FUNCTION__, rw); sLastError = 0; @@ -1052,7 +1108,7 @@ static jobject nfcManager_doCreateLlcpServiceSocket (JNIEnv* e, jobject o, jint ** Returns: Last error code. ** *******************************************************************************/ -static jint nfcManager_doGetLastError(JNIEnv* e, jobject o) +static jint nfcManager_doGetLastError(JNIEnv*, jobject) { ALOGD ("%s: last error=%i", __FUNCTION__, sLastError); return sLastError; @@ -1070,7 +1126,7 @@ static jint nfcManager_doGetLastError(JNIEnv* e, jobject o) ** Returns: True if ok. ** *******************************************************************************/ -static jboolean nfcManager_doDeinitialize (JNIEnv* e, jobject o) +static jboolean nfcManager_doDeinitialize (JNIEnv*, jobject) { ALOGD ("%s: enter", __FUNCTION__); @@ -1131,50 +1187,48 @@ static jboolean nfcManager_doDeinitialize (JNIEnv* e, jobject o) ** Returns: NativeLlcpSocket Java object. ** *******************************************************************************/ -static jobject nfcManager_doCreateLlcpSocket (JNIEnv* e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength) +static jobject nfcManager_doCreateLlcpSocket (JNIEnv* e, jobject, jint nSap, jint miu, jint rw, jint linearBufferLength) { ALOGD ("%s: enter; sap=%d; miu=%d; rw=%d; buffer len=%d", __FUNCTION__, nSap, miu, rw, linearBufferLength); - jobject clientSocket = NULL; - jclass clsNativeLlcpSocket; - jfieldID f; - PeerToPeer::tJNI_HANDLE jniHandle = PeerToPeer::getInstance().getNewJniHandle (); - bool stat = false; - stat = PeerToPeer::getInstance().createClient (jniHandle, miu, rw); + PeerToPeer::tJNI_HANDLE jniHandle = PeerToPeer::getInstance().getNewJniHandle (); + bool stat = PeerToPeer::getInstance().createClient (jniHandle, miu, rw); /* Create new NativeLlcpSocket object */ + jobject clientSocket = NULL; if (nfc_jni_cache_object_local(e, gNativeLlcpSocketClassName, &(clientSocket)) == -1) { ALOGE ("%s: fail Llcp socket creation", __FUNCTION__); - goto TheEnd; + return clientSocket; } /* Get NativeConnectionless class object */ - clsNativeLlcpSocket = e->GetObjectClass (clientSocket); + ScopedLocalRef<jclass> clsNativeLlcpSocket(e, e->GetObjectClass(clientSocket)); if (e->ExceptionCheck()) { e->ExceptionClear(); ALOGE ("%s: fail get class object", __FUNCTION__); - goto TheEnd; + return clientSocket; } + jfieldID f; + /* Set socket SAP */ - f = e->GetFieldID (clsNativeLlcpSocket, "mSap", "I"); + f = e->GetFieldID (clsNativeLlcpSocket.get(), "mSap", "I"); e->SetIntField (clientSocket, f, (jint) nSap); /* Set socket handle */ - f = e->GetFieldID (clsNativeLlcpSocket, "mHandle", "I"); + f = e->GetFieldID (clsNativeLlcpSocket.get(), "mHandle", "I"); e->SetIntField (clientSocket, f, (jint) jniHandle); /* Set socket MIU */ - f = e->GetFieldID (clsNativeLlcpSocket, "mLocalMiu", "I"); + f = e->GetFieldID (clsNativeLlcpSocket.get(), "mLocalMiu", "I"); e->SetIntField (clientSocket, f, (jint) miu); /* Set socket RW */ - f = e->GetFieldID (clsNativeLlcpSocket, "mLocalRw", "I"); + f = e->GetFieldID (clsNativeLlcpSocket.get(), "mLocalRw", "I"); e->SetIntField (clientSocket, f, (jint) rw); -TheEnd: ALOGD ("%s: exit", __FUNCTION__); return clientSocket; } @@ -1193,7 +1247,7 @@ TheEnd: ** Returns: NativeLlcpConnectionlessSocket Java object. ** *******************************************************************************/ -static jobject nfcManager_doCreateLlcpConnectionlessSocket (JNIEnv *e, jobject o, jint nSap, jstring sn) +static jobject nfcManager_doCreateLlcpConnectionlessSocket (JNIEnv *, jobject, jint nSap, jstring /*sn*/) { ALOGD ("%s: nSap=0x%X", __FUNCTION__, nSap); return NULL; @@ -1211,7 +1265,7 @@ static jobject nfcManager_doCreateLlcpConnectionlessSocket (JNIEnv *e, jobject o ** Returns: List of secure element handles. ** *******************************************************************************/ -static jintArray nfcManager_doGetSecureElementList(JNIEnv *e, jobject o) +static jintArray nfcManager_doGetSecureElementList(JNIEnv* e, jobject) { ALOGD ("%s", __FUNCTION__); return SecureElement::getInstance().getListOfEeHandles (e); @@ -1229,11 +1283,17 @@ static jintArray nfcManager_doGetSecureElementList(JNIEnv *e, jobject o) ** Returns: None ** *******************************************************************************/ -static void nfcManager_doSelectSecureElement(JNIEnv *e, jobject o) +static void nfcManager_doSelectSecureElement(JNIEnv*, jobject) { ALOGD ("%s: enter", __FUNCTION__); bool stat = true; + if (sIsSecElemSelected) + { + ALOGD ("%s: already selected", __FUNCTION__); + goto TheEnd; + } + PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER); if (sRfEnabled) { @@ -1241,22 +1301,14 @@ static void nfcManager_doSelectSecureElement(JNIEnv *e, jobject o) startRfDiscovery (false); } - if (sIsSecElemSelected) - { - ALOGD ("%s: already selected", __FUNCTION__); - goto TheEnd; - } - stat = SecureElement::getInstance().activate (0xABCDEF); if (stat) SecureElement::getInstance().routeToSecureElement (); sIsSecElemSelected = true; -TheEnd: startRfDiscovery (true); - PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_ROUTING); - +TheEnd: ALOGD ("%s: exit", __FUNCTION__); } @@ -1272,7 +1324,7 @@ TheEnd: ** Returns: None ** *******************************************************************************/ -static void nfcManager_doDeselectSecureElement(JNIEnv *e, jobject o) +static void nfcManager_doDeselectSecureElement(JNIEnv*, jobject) { ALOGD ("%s: enter", __FUNCTION__); bool stat = false; @@ -1362,7 +1414,7 @@ static bool isListenMode(tNFA_ACTIVATED& activated) ** Returns: True ** *******************************************************************************/ -static jboolean nfcManager_doCheckLlcp(JNIEnv *e, jobject o) +static jboolean nfcManager_doCheckLlcp(JNIEnv*, jobject) { ALOGD("%s", __FUNCTION__); return JNI_TRUE; @@ -1378,7 +1430,7 @@ static jboolean nfcManager_doCheckLlcp(JNIEnv *e, jobject o) ** Returns: True ** *******************************************************************************/ -static jboolean nfcManager_doActivateLlcp(JNIEnv *e, jobject o) +static jboolean nfcManager_doActivateLlcp(JNIEnv*, jobject) { ALOGD("%s", __FUNCTION__); return JNI_TRUE; @@ -1394,7 +1446,7 @@ static jboolean nfcManager_doActivateLlcp(JNIEnv *e, jobject o) ** Returns: None ** *******************************************************************************/ -static void nfcManager_doAbort(JNIEnv *e, jobject o) +static void nfcManager_doAbort(JNIEnv*, jobject) { ALOGE("%s: abort()", __FUNCTION__); abort(); @@ -1410,7 +1462,7 @@ static void nfcManager_doAbort(JNIEnv *e, jobject o) ** Returns: True ** *******************************************************************************/ -static jboolean nfcManager_doDownload(JNIEnv *e, jobject o) +static jboolean nfcManager_doDownload(JNIEnv*, jobject) { ALOGD("%s", __FUNCTION__); return JNI_TRUE; @@ -1426,7 +1478,7 @@ static jboolean nfcManager_doDownload(JNIEnv *e, jobject o) ** Returns: None ** *******************************************************************************/ -static void nfcManager_doResetTimeouts(JNIEnv *e, jobject o) +static void nfcManager_doResetTimeouts(JNIEnv*, jobject) { ALOGD ("%s: %d millisec", __FUNCTION__, DEFAULT_GENERAL_TRANS_TIMEOUT); gGeneralTransceiveTimeout = DEFAULT_GENERAL_TRANS_TIMEOUT; @@ -1445,7 +1497,7 @@ static void nfcManager_doResetTimeouts(JNIEnv *e, jobject o) ** Returns: True if ok. ** *******************************************************************************/ -static bool nfcManager_doSetTimeout(JNIEnv *e, jobject o, jint tech, jint timeout) +static bool nfcManager_doSetTimeout(JNIEnv*, jobject, jint /*tech*/, jint timeout) { if (timeout <= 0) { @@ -1471,7 +1523,7 @@ static bool nfcManager_doSetTimeout(JNIEnv *e, jobject o, jint tech, jint timeou ** Returns: Timeout value. ** *******************************************************************************/ -static jint nfcManager_doGetTimeout(JNIEnv *e, jobject o, jint tech) +static jint nfcManager_doGetTimeout(JNIEnv*, jobject, jint /*tech*/) { ALOGD ("%s: timeout=%d", __FUNCTION__, gGeneralTransceiveTimeout); return gGeneralTransceiveTimeout; @@ -1489,7 +1541,7 @@ static jint nfcManager_doGetTimeout(JNIEnv *e, jobject o, jint tech) ** Returns: Text dump. ** *******************************************************************************/ -static jstring nfcManager_doDump(JNIEnv *e, jobject o) +static jstring nfcManager_doDump(JNIEnv* e, jobject) { char buffer[100]; snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", /*libnfc_llc_error_count*/ 0); @@ -1541,7 +1593,7 @@ static void nfcManager_doSetP2pInitiatorModes (JNIEnv *e, jobject o, jint modes) ** Returns: None. ** *******************************************************************************/ -static void nfcManager_doSetP2pTargetModes (JNIEnv *e, jobject o, jint modes) +static void nfcManager_doSetP2pTargetModes (JNIEnv*, jobject, jint modes) { ALOGD ("%s: modes=0x%X", __FUNCTION__, modes); // Map in the right modes @@ -1693,23 +1745,6 @@ void doStartupConfig() struct nfc_jni_native_data *nat = getNative(0, 0); tNFA_STATUS stat = NFA_STATUS_FAILED; - // Enable the "RC workaround" to allow our stack/firmware to work with a retail - // Nexus S that causes IOP issues. Only enable if value exists and set to 1. - if (GetNumValue(NAME_USE_NXP_P2P_RC_WORKAROUND, &num, sizeof(num)) && (num == 1)) - { -#if (NCI_VERSION > NCI_VERSION_20791B0) - UINT8 nfa_dm_rc_workaround[] = { 0x03, 0x0f, 0xab }; -#else - UINT8 nfa_dm_rc_workaround[] = { 0x01, 0x0f, 0xab, 0x01 }; -#endif - - ALOGD ("%s: Configure RC work-around", __FUNCTION__); - SyncEventGuard guard (sNfaSetConfigEvent); - stat = NFA_SetConfig(NCI_PARAM_ID_FW_WORKAROUND, sizeof(nfa_dm_rc_workaround), &nfa_dm_rc_workaround[0]); - if (stat == NFA_STATUS_OK) - sNfaSetConfigEvent.wait (); - } - // If polling for Active mode, set the ordering so that we choose Active over Passive mode first. if (nat && (nat->tech_mask & (NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE))) { @@ -1719,41 +1754,6 @@ void doStartupConfig() if (stat == NFA_STATUS_OK) sNfaSetConfigEvent.wait (); } - - // Set configuration to allow UICC to Power off if there is no traffic. - if (GetNumValue(NAME_UICC_IDLE_TIMEOUT, &num, sizeof(num)) && (num != 0)) - { - // 61 => The least significant bit of this byte enables the power off when Idle mode. - // 00 87 93 03 == > These 4 bytes form a 4 byte value which decides the idle timeout(in us) - // value to trigger the uicc deactivation. - // e.g. in current example its value is 0x3938700 i.e. 60000000 is 60 seconds. - UINT8 swpcfg_param[] = { 0x61, 0x00, 0x82, 0x04, 0x20, 0xA1, 0x07, 0x00, - 0x90, 0xD0, 0x03, 0x00, 0x00, 0x87, 0x93, 0x03 }; - - ALOGD ("%s: Configure UICC idle-timeout to %lu ms", __FUNCTION__, num); - - // Set the timeout from the .conf file value. - num *= 1000; - UINT8 * p = &swpcfg_param[12]; - UINT32_TO_STREAM(p, num) - - SyncEventGuard guard (sNfaSetConfigEvent); - stat = NFA_SetConfig(NCI_PARAM_ID_SWPCFG, sizeof(swpcfg_param), &swpcfg_param[0]); - if (stat == NFA_STATUS_OK) - sNfaSetConfigEvent.wait (); - } - - // Set antenna tuning configuration if configured. -#define PREINIT_DSP_CFG_SIZE 30 - UINT8 preinit_dsp_param[PREINIT_DSP_CFG_SIZE]; - - if (GetStrValue(NAME_PREINIT_DSP_CFG, (char*)&preinit_dsp_param[0], sizeof(preinit_dsp_param))) - { - SyncEventGuard guard (sNfaSetConfigEvent); - stat = NFA_SetConfig(NCI_PARAM_ID_PREINIT_DSP_CFG, sizeof(preinit_dsp_param), &preinit_dsp_param[0]); - if (stat == NFA_STATUS_OK) - sNfaSetConfigEvent.wait (); - } } diff --git a/nci/jni/NativeNfcTag.cpp b/nci/jni/NativeNfcTag.cpp index 0ba7b21a..86666683 100755 --- a/nci/jni/NativeNfcTag.cpp +++ b/nci/jni/NativeNfcTag.cpp @@ -26,6 +26,8 @@ #include "IntervalTimer.h" #include "JavaClassConstants.h" #include "Pn544Interop.h" +#include <ScopedLocalRef.h> +#include <ScopedPrimitiveArray.h> extern "C" { @@ -244,7 +246,7 @@ static void ndefHandlerCallback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *eventD ** Returns: NDEF message. ** *******************************************************************************/ -static jbyteArray nativeNfcTag_doRead (JNIEnv *e, jobject o) +static jbyteArray nativeNfcTag_doRead (JNIEnv* e, jobject) { ALOGD ("%s: enter", __FUNCTION__); tNFA_STATUS status = NFA_STATUS_FAILED; @@ -277,7 +279,6 @@ static jbyteArray nativeNfcTag_doRead (JNIEnv *e, jobject o) else { ALOGD ("%s: create emtpy buffer", __FUNCTION__); - static uint8_t* empty = (uint8_t*) ""; sReadDataLen = 0; sReadData = (uint8_t*) malloc (1); buf = e->NewByteArray (sReadDataLen); @@ -348,20 +349,18 @@ void nativeNfcTag_formatStatus (bool isOk) ** Returns: True if ok. ** *******************************************************************************/ -static jboolean nativeNfcTag_doWrite (JNIEnv *e, jobject o, jbyteArray buf) +static jboolean nativeNfcTag_doWrite (JNIEnv* e, jobject, jbyteArray buf) { jboolean result = JNI_FALSE; tNFA_STATUS status = 0; - UINT32 len = 0; - UINT8* p_data = NULL; const int maxBufferSize = 1024; UINT8 buffer[maxBufferSize] = { 0 }; UINT32 curDataSize = 0; - len = (UINT32) e->GetArrayLength (buf); - p_data = (UINT8*) e->GetByteArrayElements (buf, NULL); + ScopedByteArrayRO bytes(e, buf); + UINT8* p_data = const_cast<UINT8*>(reinterpret_cast<const UINT8*>(&bytes[0])); // TODO: const-ness API bug in NFA_RwWriteNDef! - ALOGD ("%s: enter; len = %lu", __FUNCTION__, len); + ALOGD ("%s: enter; len = %zu", __FUNCTION__, bytes.size()); /* Create the write semaphore */ if (sem_init (&sWriteSem, 0, 0) == -1) @@ -387,9 +386,9 @@ static jboolean nativeNfcTag_doWrite (JNIEnv *e, jobject o, jbyteArray buf) goto TheEnd; } ALOGD ("%s: try write", __FUNCTION__); - status = NFA_RwWriteNDef (p_data, len); + status = NFA_RwWriteNDef (p_data, bytes.size()); } - else if (len == 0) + else if (bytes.size() == 0) { //if (NXP TagWriter wants to erase tag) then create and write an empty ndef message NDEF_MsgInit (buffer, maxBufferSize, &curDataSize); @@ -400,7 +399,7 @@ static jboolean nativeNfcTag_doWrite (JNIEnv *e, jobject o, jbyteArray buf) else { ALOGD ("%s: NFA_RwWriteNDef", __FUNCTION__); - status = NFA_RwWriteNDef (p_data, len); + status = NFA_RwWriteNDef (p_data, bytes.size()); } if (status != NFA_STATUS_OK) @@ -483,7 +482,7 @@ void nativeNfcTag_doDeactivateStatus (int status) ** Returns: Must return NXP status code, which NFC service expects. ** *******************************************************************************/ -static jint nativeNfcTag_doConnect (JNIEnv *e, jobject o, jint targetHandle) +static jint nativeNfcTag_doConnect (JNIEnv*, jobject, jint targetHandle) { ALOGD ("%s: targetHandle = %d", __FUNCTION__, targetHandle); int i = targetHandle; @@ -671,7 +670,7 @@ static bool switchRfInterface (tNFA_INTF_TYPE rfInterface) ** Returns: Status code. ** *******************************************************************************/ -static jint nativeNfcTag_doReconnect (JNIEnv *e, jobject o) +static jint nativeNfcTag_doReconnect (JNIEnv*, jobject) { ALOGD ("%s: enter", __FUNCTION__); int retCode = NFCSTATUS_SUCCESS; @@ -684,6 +683,13 @@ static jint nativeNfcTag_doReconnect (JNIEnv *e, jobject o) goto TheEnd; } + // special case for Kovio + if (NfcTag::getInstance ().mTechList [0] == TARGET_TYPE_KOVIO_BARCODE) + { + ALOGD ("%s: fake out reconnect for Kovio", __FUNCTION__); + goto TheEnd; + } + // this is only supported for type 2 or 4 (ISO_DEP) tags if (natTag.mTechLibNfcTypes[0] == NFA_PROTOCOL_ISO_DEP) retCode = reSelect(NFA_INTERFACE_ISO_DEP); @@ -726,7 +732,7 @@ static jint nativeNfcTag_doHandleReconnect (JNIEnv *e, jobject o, jint targetHan ** Returns: True if ok. ** *******************************************************************************/ -static jboolean nativeNfcTag_doDisconnect (JNIEnv *e, jobject o) +static jboolean nativeNfcTag_doDisconnect (JNIEnv*, jobject) { ALOGD ("%s: enter", __FUNCTION__); struct nfc_jni_native_data *nat = getNative (0, 0); @@ -800,15 +806,13 @@ void nativeNfcTag_doTransceiveStatus (uint8_t* buf, uint32_t bufLen) ** Returns: Response from tag. ** *******************************************************************************/ -static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray data, jboolean raw, jintArray statusTargetLost) +static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject, jbyteArray data, jboolean raw, jintArray statusTargetLost) { ALOGD ("%s: enter; raw=%u; timeout = %d", __FUNCTION__, raw, gGeneralTransceiveTimeout); bool fNeedToSwitchBack = false; nfc_jni_native_data *nat = getNative (0, 0); bool waitOk = false; bool isNack = false; - uint8_t *buf = NULL; - uint32_t bufLen = 0; jint *targetLost = NULL; if (NfcTag::getInstance ().getActivationState () != NfcTag::Active) @@ -827,8 +831,9 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da NfcTag& natTag = NfcTag::getInstance (); // get input buffer and length from java call - buf = (uint8_t *) e->GetByteArrayElements (data, NULL); - bufLen = (uint32_t) e->GetArrayLength (data); + ScopedByteArrayRO bytes(e, data); + uint8_t* buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); // TODO: API bug; NFA_SendRawFrame should take const*! + size_t bufLen = bytes.size(); if (statusTargetLost) { @@ -838,7 +843,7 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da } sSwitchBackTimer.kill (); - jbyteArray result = NULL; + ScopedLocalRef<jbyteArray> result(e, NULL); do { if (sNeedToSwitchRf) @@ -855,7 +860,7 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da sTransceiveDataLen = 0; { SyncEventGuard g (sTransceiveEvent); - tNFA_STATUS status = NFA_SendRawFrame (buf, bufLen); + tNFA_STATUS status = NFA_SendRawFrame (buf, bufLen, NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY); if (status != NFA_STATUS_OK) { ALOGE ("%s: fail send; error=%d", __FUNCTION__, status); @@ -892,10 +897,9 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da { if (!isNack) { // marshall data to java for return - result = e->NewByteArray (sTransceiveDataLen); - if (result != NULL) - { - e->SetByteArrayRegion (result, 0, sTransceiveDataLen, (jbyte *) sTransceiveData); + result.reset(e->NewByteArray(sTransceiveDataLen)); + if (result.get() != NULL) { + e->SetByteArrayRegion(result.get(), 0, sTransceiveDataLen, (jbyte *) sTransceiveData); } else ALOGE ("%s: Failed to allocate java byte array", __FUNCTION__); @@ -908,7 +912,6 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da } while (0); sWaitingForTransceive = false; - e->ReleaseByteArrayElements (data, (jbyte *) buf, JNI_ABORT); if (targetLost) e->ReleaseIntArrayElements (statusTargetLost, targetLost, 0); @@ -919,7 +922,7 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da } ALOGD ("%s: exit", __FUNCTION__); - return result; + return result.release(); } @@ -936,7 +939,7 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da ** Returns: Type of tag represented by NFC Service. ** *******************************************************************************/ -static jint nativeNfcTag_doGetNdefType (JNIEnv *e, jobject o, jint libnfcType, jint javaType) +static jint nativeNfcTag_doGetNdefType (JNIEnv*, jobject, jint libnfcType, jint javaType) { ALOGD ("%s: enter; libnfc type=%d; java type=%d", __FUNCTION__, libnfcType, javaType); jint ndefType = NDEF_UNKNOWN_TYPE; @@ -1064,13 +1067,35 @@ void nativeNfcTag_doCheckNdefResult (tNFA_STATUS status, uint32_t maxSize, uint3 ** Returns: Status code; 0 is success. ** *******************************************************************************/ -static jint nativeNfcTag_doCheckNdef (JNIEnv *e, jobject o, jintArray ndefInfo) +static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject, jintArray ndefInfo) { tNFA_STATUS status = NFA_STATUS_FAILED; jint* ndef = NULL; ALOGD ("%s: enter", __FUNCTION__); + // special case for Kovio + if (NfcTag::getInstance ().mTechList [0] == TARGET_TYPE_KOVIO_BARCODE) + { + ALOGD ("%s: Kovio tag, no NDEF", __FUNCTION__); + ndef = e->GetIntArrayElements (ndefInfo, 0); + ndef[0] = 0; + ndef[1] = NDEF_MODE_READ_ONLY; + e->ReleaseIntArrayElements (ndefInfo, ndef, 0); + return NFA_STATUS_FAILED; + } + + // special case for Kovio + if (NfcTag::getInstance ().mTechList [0] == TARGET_TYPE_KOVIO_BARCODE) + { + ALOGD ("%s: Kovio tag, no NDEF", __FUNCTION__); + ndef = e->GetIntArrayElements (ndefInfo, 0); + ndef[0] = 0; + ndef[1] = NDEF_MODE_READ_ONLY; + e->ReleaseIntArrayElements (ndefInfo, ndef, 0); + return NFA_STATUS_FAILED; + } + /* Create the write semaphore */ if (sem_init (&sCheckNdefSem, 0, 0) == -1) { @@ -1202,12 +1227,29 @@ void nativeNfcTag_doPresenceCheckResult (tNFA_STATUS status) ** Returns: True if tag is in RF field. ** *******************************************************************************/ -static jboolean nativeNfcTag_doPresenceCheck (JNIEnv *e, jobject o) +static jboolean nativeNfcTag_doPresenceCheck (JNIEnv*, jobject) { ALOGD ("%s", __FUNCTION__); tNFA_STATUS status = NFA_STATUS_OK; jboolean isPresent = JNI_FALSE; + // Special case for Kovio. The deactivation would have already occurred + // but was ignored so that normal tag opertions could complete. Now we + // want to process as if the deactivate just happened. + if (NfcTag::getInstance ().mTechList [0] == TARGET_TYPE_KOVIO_BARCODE) + { + ALOGD ("%s: Kovio, force deactivate handling", __FUNCTION__); + tNFA_DEACTIVATED deactivated = {NFA_DEACTIVATE_TYPE_IDLE}; + + NfcTag::getInstance().setDeactivationState (deactivated); + nativeNfcTag_resetPresenceCheck(); + NfcTag::getInstance().connectionEventHandler (NFA_DEACTIVATED_EVT, NULL); + nativeNfcTag_abortWaits(); + NfcTag::getInstance().abort (); + + return JNI_FALSE; + } + if (nfcManager_isNfcActive() == false) { ALOGD ("%s: NFC is no longer active.", __FUNCTION__); @@ -1265,9 +1307,9 @@ static jboolean nativeNfcTag_doPresenceCheck (JNIEnv *e, jobject o) ** Returns: True if formattable. ** *******************************************************************************/ -static jboolean nativeNfcTag_doIsNdefFormatable (JNIEnv *e, - jobject o, jint libNfcType, jbyteArray uidBytes, jbyteArray pollBytes, - jbyteArray actBytes) +static jboolean nativeNfcTag_doIsNdefFormatable (JNIEnv*, + jobject, jint /*libNfcType*/, jbyteArray, jbyteArray, + jbyteArray) { jboolean isFormattable = JNI_FALSE; @@ -1321,7 +1363,7 @@ static jboolean nativeNfcTag_doIsIsoDepNdefFormatable (JNIEnv *e, jobject o, jby ** Returns: True if ok. ** *******************************************************************************/ -static jboolean nativeNfcTag_doNdefFormat (JNIEnv *e, jobject o, jbyteArray key) +static jboolean nativeNfcTag_doNdefFormat (JNIEnv*, jobject, jbyteArray) { ALOGD ("%s: enter", __FUNCTION__); tNFA_STATUS status = NFA_STATUS_OK; @@ -1379,7 +1421,7 @@ void nativeNfcTag_doMakeReadonlyResult (tNFA_STATUS status) ** Returns: True if ok. ** *******************************************************************************/ -static jboolean nativeNfcTag_doMakeReadonly (JNIEnv *e, jobject o, jbyteArray key) +static jboolean nativeNfcTag_doMakeReadonly (JNIEnv*, jobject, jbyteArray) { jboolean result = JNI_FALSE; tNFA_STATUS status; diff --git a/nci/jni/NativeP2pDevice.cpp b/nci/jni/NativeP2pDevice.cpp index 57f9dad0..fffa46b5 100644 --- a/nci/jni/NativeP2pDevice.cpp +++ b/nci/jni/NativeP2pDevice.cpp @@ -23,35 +23,35 @@ namespace android { -static jboolean nativeP2pDeviceDoConnect (JNIEnv* e, jobject o) +static jboolean nativeP2pDeviceDoConnect (JNIEnv*, jobject) { ALOGD ("%s", __FUNCTION__); return JNI_TRUE; } -static jboolean nativeP2pDeviceDoDisconnect (JNIEnv* e, jobject o) +static jboolean nativeP2pDeviceDoDisconnect (JNIEnv*, jobject) { ALOGD ("%s", __FUNCTION__); return JNI_TRUE; } -static jbyteArray nativeP2pDeviceDoTransceive (JNIEnv* e, jobject o, jbyteArray data) +static jbyteArray nativeP2pDeviceDoTransceive (JNIEnv*, jobject, jbyteArray) { ALOGD ("%s", __FUNCTION__); return NULL; } -static jbyteArray nativeP2pDeviceDoReceive (JNIEnv* e, jobject o) +static jbyteArray nativeP2pDeviceDoReceive (JNIEnv*, jobject) { ALOGD ("%s", __FUNCTION__); return NULL; } -static jboolean nativeP2pDeviceDoSend (JNIEnv* e, jobject o, jbyteArray buf) +static jboolean nativeP2pDeviceDoSend (JNIEnv*, jobject, jbyteArray) { ALOGD ("%s", __FUNCTION__); return JNI_TRUE; diff --git a/nci/jni/NativeSecureElement.cpp b/nci/jni/NativeSecureElement.cpp index 1a2a73a0..fea2e151 100755 --- a/nci/jni/NativeSecureElement.cpp +++ b/nci/jni/NativeSecureElement.cpp @@ -17,7 +17,7 @@ #include "SecureElement.h" #include "JavaClassConstants.h" #include "PowerSwitch.h" - +#include <ScopedPrimitiveArray.h> namespace android { @@ -27,6 +27,13 @@ extern void com_android_nfc_NfcManager_disableDiscovery (JNIEnv* e, jobject o); extern void com_android_nfc_NfcManager_enableDiscovery (JNIEnv* e, jobject o, jint mode); extern int gGeneralTransceiveTimeout; +// These must match the EE_ERROR_ types in NfcService.java +static const int EE_ERROR_IO = -1; +static const int EE_ERROR_ALREADY_OPEN = -2; +static const int EE_ERROR_INIT = -3; +static const int EE_ERROR_LISTEN_MODE = -4; +static const int EE_ERROR_EXT_FIELD = -5; +static const int EE_ERROR_NFC_DISABLED = -6; /******************************************************************************* ** @@ -36,23 +43,25 @@ extern int gGeneralTransceiveTimeout; ** e: JVM environment. ** o: Java object. ** -** Returns: Handle of secure element. 0 is failure. +** Returns: Handle of secure element. values < 0 represent failure. ** *******************************************************************************/ -static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv* e, jobject o) +static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobject) { ALOGD("%s: enter", __FUNCTION__); bool stat = true; - jint secElemHandle = 0; + jint secElemHandle = EE_ERROR_INIT; SecureElement &se = SecureElement::getInstance(); if (se.isActivatedInListenMode()) { ALOGD("Denying SE open due to SE listen mode active"); + secElemHandle = EE_ERROR_LISTEN_MODE; goto TheEnd; } if (se.isRfFieldOn()) { ALOGD("Denying SE open due to SE in active RF field"); + secElemHandle = EE_ERROR_EXT_FIELD; goto TheEnd; } //tell the controller to power up to get ready for sec elem operations @@ -69,9 +78,13 @@ static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv* e, job //establish a pipe to sec elem stat = se.connectEE(); if (stat) + { secElemHandle = se.mActiveEeHandle; + } else + { se.deactivate (0); + } } //if code fails to connect to the secure element, and nothing is active, then @@ -99,7 +112,7 @@ TheEnd: ** Returns: True if ok. ** *******************************************************************************/ -static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv* e, jobject o, jint handle) +static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle) { ALOGD("%s: enter; handle=0x%04x", __FUNCTION__, handle); bool stat = false; @@ -133,29 +146,23 @@ static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIE ** Returns: Buffer of received data. ** *******************************************************************************/ -static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject o, jint handle, jbyteArray data) +static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data) { - UINT8* buf = NULL; - INT32 buflen = 0; const INT32 recvBufferMaxSize = 1024; UINT8 recvBuffer [recvBufferMaxSize]; INT32 recvBufferActualSize = 0; - jbyteArray result = NULL; - buf = (UINT8*) e->GetByteArrayElements (data, NULL); - buflen = e->GetArrayLength (data); + ScopedByteArrayRW bytes(e, data); - ALOGD("%s: enter; handle=0x%X; buf len=%ld", __FUNCTION__, handle, buflen); - SecureElement::getInstance().transceive (buf, buflen, recvBuffer, recvBufferMaxSize, recvBufferActualSize, gGeneralTransceiveTimeout); + ALOGD("%s: enter; handle=0x%X; buf len=%zu", __FUNCTION__, handle, bytes.size()); + SecureElement::getInstance().transceive(reinterpret_cast<UINT8*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, gGeneralTransceiveTimeout); //copy results back to java - result = e->NewByteArray (recvBufferActualSize); - if (result != NULL) - { - e->SetByteArrayRegion (result, 0, recvBufferActualSize, (jbyte *) recvBuffer); + jbyteArray result = e->NewByteArray(recvBufferActualSize); + if (result != NULL) { + e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer); } - e->ReleaseByteArrayElements (data, (jbyte *) buf, JNI_ABORT); ALOGD("%s: exit: recv len=%ld", __FUNCTION__, recvBufferActualSize); return result; } @@ -173,7 +180,7 @@ static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject o, jin ** Returns: Secure element's unique ID. ** *******************************************************************************/ -static jbyteArray nativeNfcSecureElement_doGetUid (JNIEnv* e, jobject o, jint handle) +static jbyteArray nativeNfcSecureElement_doGetUid (JNIEnv*, jobject, jint handle) { ALOGD("%s: enter; handle=0x%X", __FUNCTION__, handle); jbyteArray secureElementUid = NULL; @@ -197,7 +204,7 @@ static jbyteArray nativeNfcSecureElement_doGetUid (JNIEnv* e, jobject o, jint ha ** Returns: Array of technologies. ** *******************************************************************************/ -static jintArray nativeNfcSecureElement_doGetTechList (JNIEnv* e, jobject o, jint handle) +static jintArray nativeNfcSecureElement_doGetTechList (JNIEnv*, jobject, jint handle) { ALOGD("%s: enter; handle=0x%X", __FUNCTION__, handle); jintArray techList = NULL; @@ -242,4 +249,3 @@ int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e) } // namespace android - diff --git a/nci/jni/NfcJniUtil.cpp b/nci/jni/NfcJniUtil.cpp index 9921caed..2bac97b0 100755 --- a/nci/jni/NfcJniUtil.cpp +++ b/nci/jni/NfcJniUtil.cpp @@ -15,6 +15,7 @@ */ #include "NfcJniUtil.h" #include <errno.h> +#include <ScopedLocalRef.h> /******************************************************************************* @@ -28,11 +29,13 @@ ** Returns: JNI version. ** *******************************************************************************/ -jint JNI_OnLoad (JavaVM *jvm, void *reserved) +jint JNI_OnLoad (JavaVM* jvm, void*) { ALOGD ("%s: enter", __FUNCTION__); JNIEnv *e = NULL; + ALOGI("NFC Service: loading nci JNI"); + // Check JNI version if (jvm->GetEnv ((void **) &e, JNI_VERSION_1_6)) return JNI_ERR; @@ -71,33 +74,24 @@ namespace android *******************************************************************************/ int nfc_jni_cache_object (JNIEnv *e, const char *className, jobject *cachedObj) { - jclass cls = NULL; - jobject obj = NULL; - jmethodID ctor = 0; - - cls = e->FindClass (className); - if(cls == NULL) - { - ALOGE ("%s: find class error", __FUNCTION__); + ScopedLocalRef<jclass> cls(e, e->FindClass(className)); + if (cls.get() == NULL) { + ALOGE("%s: find class error", __FUNCTION__); return -1; } - ctor = e->GetMethodID (cls, "<init>", "()V"); - obj = e->NewObject (cls, ctor); - if (obj == NULL) - { - ALOGE ("%s: create object error", __FUNCTION__); + jmethodID ctor = e->GetMethodID(cls.get(), "<init>", "()V"); + ScopedLocalRef<jobject> obj(e, e->NewObject(cls.get(), ctor)); + if (obj.get() == NULL) { + ALOGE("%s: create object error", __FUNCTION__); return -1; } - *cachedObj = e->NewGlobalRef (obj); - if (*cachedObj == NULL) - { - e->DeleteLocalRef (obj); - ALOGE ("%s: global ref error", __FUNCTION__); + *cachedObj = e->NewGlobalRef(obj.get()); + if (*cachedObj == NULL) { + ALOGE("%s: global ref error", __FUNCTION__); return -1; } - e->DeleteLocalRef (obj); return 0; } @@ -115,12 +109,9 @@ int nfc_jni_cache_object (JNIEnv *e, const char *className, jobject *cachedObj) *******************************************************************************/ int nfc_jni_get_nfc_socket_handle (JNIEnv *e, jobject o) { - jclass c = NULL; - jfieldID f = 0; - - c = e->GetObjectClass (o); - f = e->GetFieldID (c, "mHandle", "I"); - return e->GetIntField (o, f); + ScopedLocalRef<jclass> c(e, e->GetObjectClass(o)); + jfieldID f = e->GetFieldID(c.get(), "mHandle", "I"); + return e->GetIntField(o, f); } @@ -137,13 +128,10 @@ int nfc_jni_get_nfc_socket_handle (JNIEnv *e, jobject o) *******************************************************************************/ struct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o) { - jclass c = NULL; - jfieldID f = 0; - + ScopedLocalRef<jclass> c(e, e->GetObjectClass(o)); + jfieldID f = e->GetFieldID(c.get(), "mNative", "I"); /* Retrieve native structure address */ - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mNative", "I"); - return (struct nfc_jni_native_data*)e->GetIntField(o, f); + return (struct nfc_jni_native_data*) e->GetIntField(o, f); } diff --git a/nci/jni/NfcJniUtil.h b/nci/jni/NfcJniUtil.h index 8caa0b88..a8b5faa4 100755 --- a/nci/jni/NfcJniUtil.h +++ b/nci/jni/NfcJniUtil.h @@ -15,6 +15,7 @@ */ #pragma once +#undef LOG_TAG #define LOG_TAG "BrcmNfcJni" #include <JNIHelp.h> #include <jni.h> @@ -83,6 +84,7 @@ #define TARGET_TYPE_NDEF_FORMATABLE 7 #define TARGET_TYPE_MIFARE_CLASSIC 8 #define TARGET_TYPE_MIFARE_UL 9 +#define TARGET_TYPE_KOVIO_BARCODE 10 //define a few NXP error codes that NFC service expects; @@ -131,6 +133,21 @@ struct nfc_jni_native_data }; +class ScopedAttach { + public: + ScopedAttach(JavaVM* vm, JNIEnv** env) : vm_(vm) { + vm_->AttachCurrentThread(env, NULL); + } + + ~ScopedAttach() { + vm_->DetachCurrentThread(); + } + + private: + JavaVM* vm_; +}; + + extern "C" { jint JNI_OnLoad(JavaVM *jvm, void *reserved); diff --git a/nci/jni/NfcTag.cpp b/nci/jni/NfcTag.cpp index b94355fb..de006565 100755 --- a/nci/jni/NfcTag.cpp +++ b/nci/jni/NfcTag.cpp @@ -20,6 +20,9 @@ #include "OverrideLog.h" #include "NfcTag.h" #include "JavaClassConstants.h" +#include <ScopedLocalRef.h> +#include <ScopedPrimitiveArray.h> + extern "C" { #include "rw_int.h" @@ -348,8 +351,8 @@ void NfcTag::discoverTechnologies (tNFA_ACTIVATED& activationData) break; case NFC_PROTOCOL_KOVIO: - ALOGE ("%s: Kovio", fn); - mNumTechList--; // no tech classes for Kovio + ALOGD ("%s: Kovio", fn); + mTechList [mNumTechList] = TARGET_TYPE_KOVIO_BARCODE; break; default: @@ -491,63 +494,53 @@ void NfcTag::createNativeNfcTag (tNFA_ACTIVATED& activationData) { static const char fn [] = "NfcTag::createNativeNfcTag"; ALOGD ("%s: enter", fn); - JNIEnv* e = NULL; - jclass tag_cls = NULL; - jmethodID ctor = NULL; - jobject tag = NULL; - //acquire a pointer to the Java virtual machine - mNativeData->vm->AttachCurrentThread (&e, NULL); - if (e == NULL) - { + JNIEnv* e = NULL; + ScopedAttach attach(mNativeData->vm, &e); + if (e == NULL) { ALOGE("%s: jni env is null", fn); - goto TheEnd; + return; } - tag_cls = e->GetObjectClass (mNativeData->cached_NfcTag); - if (e->ExceptionCheck()) - { + ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(mNativeData->cached_NfcTag)); + if (e->ExceptionCheck()) { e->ExceptionClear(); ALOGE("%s: failed to get class", fn); - goto TheEnd; + return; } //create a new Java NativeNfcTag object - ctor = e->GetMethodID (tag_cls, "<init>", "()V"); - tag = e->NewObject (tag_cls, ctor); + jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V"); + ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor)); //fill NativeNfcTag's mProtocols, mTechList, mTechHandles, mTechLibNfcTypes - fillNativeNfcTagMembers1 (e, tag_cls, tag); + fillNativeNfcTagMembers1(e, tag_cls.get(), tag.get()); //fill NativeNfcTag's members: mHandle, mConnectedTechnology - fillNativeNfcTagMembers2 (e, tag_cls, tag, activationData); + fillNativeNfcTagMembers2(e, tag_cls.get(), tag.get(), activationData); //fill NativeNfcTag's members: mTechPollBytes - fillNativeNfcTagMembers3 (e, tag_cls, tag, activationData); + fillNativeNfcTagMembers3(e, tag_cls.get(), tag.get(), activationData); //fill NativeNfcTag's members: mTechActBytes - fillNativeNfcTagMembers4 (e, tag_cls, tag, activationData); + fillNativeNfcTagMembers4(e, tag_cls.get(), tag.get(), activationData); //fill NativeNfcTag's members: mUid - fillNativeNfcTagMembers5 (e, tag_cls, tag, activationData); + fillNativeNfcTagMembers5(e, tag_cls.get(), tag.get(), activationData); if (mNativeData->tag != NULL) { - e->DeleteGlobalRef (mNativeData->tag); + e->DeleteGlobalRef(mNativeData->tag); } - mNativeData->tag = e->NewGlobalRef (tag); + mNativeData->tag = e->NewGlobalRef(tag.get()); //notify NFC service about this new tag ALOGD ("%s: try notify nfc service", fn); - e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyNdefMessageListeners, tag); - if (e->ExceptionCheck()) - { + e->CallVoidMethod(mNativeData->manager, android::gCachedNfcManagerNotifyNdefMessageListeners, tag.get()); + if (e->ExceptionCheck()) { e->ExceptionClear(); ALOGE ("%s: fail notify nfc service", fn); } - e->DeleteLocalRef (tag); -TheEnd: - mNativeData->vm->DetachCurrentThread (); ALOGD ("%s: exit", fn); } @@ -568,36 +561,35 @@ void NfcTag::fillNativeNfcTagMembers1 (JNIEnv* e, jclass tag_cls, jobject tag) { static const char fn [] = "NfcTag::fillNativeNfcTagMembers1"; ALOGD ("%s", fn); - jfieldID f = NULL; //create objects that represent NativeNfcTag's member variables - jintArray techList = e->NewIntArray (mNumTechList); - jintArray handleList = e->NewIntArray (mNumTechList); - jintArray typeList = e->NewIntArray (mNumTechList); + ScopedLocalRef<jintArray> techList(e, e->NewIntArray(mNumTechList)); + ScopedLocalRef<jintArray> handleList(e, e->NewIntArray(mNumTechList)); + ScopedLocalRef<jintArray> typeList(e, e->NewIntArray(mNumTechList)); - jint* technologies = e->GetIntArrayElements (techList, NULL); - jint* handles = e->GetIntArrayElements (handleList, NULL); - jint* types = e->GetIntArrayElements (typeList, NULL); - for (int i = 0; i < mNumTechList; i++) { - mNativeData->tProtocols [i] = mTechLibNfcTypes [i]; - mNativeData->handles [i] = mTechHandles [i]; - technologies [i] = mTechList [i]; - handles [i] = mTechHandles [i]; - types [i] = mTechLibNfcTypes [i]; + ScopedIntArrayRW technologies(e, techList.get()); + ScopedIntArrayRW handles(e, handleList.get()); + ScopedIntArrayRW types(e, typeList.get()); + for (int i = 0; i < mNumTechList; i++) { + mNativeData->tProtocols [i] = mTechLibNfcTypes [i]; + mNativeData->handles [i] = mTechHandles [i]; + technologies [i] = mTechList [i]; + handles [i] = mTechHandles [i]; + types [i] = mTechLibNfcTypes [i]; + } } - e->ReleaseIntArrayElements (techList, technologies, 0); - e->ReleaseIntArrayElements (handleList, handles, 0); - e->ReleaseIntArrayElements (typeList, types, 0); - f = e->GetFieldID (tag_cls, "mTechList", "[I"); - e->SetObjectField (tag, f, techList); + jfieldID f = NULL; + + f = e->GetFieldID(tag_cls, "mTechList", "[I"); + e->SetObjectField(tag, f, techList.get()); - f = e->GetFieldID (tag_cls, "mTechHandles", "[I"); - e->SetObjectField (tag, f, handleList); + f = e->GetFieldID(tag_cls, "mTechHandles", "[I"); + e->SetObjectField(tag, f, handleList.get()); - f = e->GetFieldID (tag_cls, "mTechLibNfcTypes", "[I"); - e->SetObjectField (tag, f, typeList); + f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I"); + e->SetObjectField(tag, f, typeList.get()); } @@ -617,14 +609,12 @@ void NfcTag::fillNativeNfcTagMembers1 (JNIEnv* e, jclass tag_cls, jobject tag) ** *******************************************************************************/ //fill NativeNfcTag's members: mHandle, mConnectedTechnology -void NfcTag::fillNativeNfcTagMembers2 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData) +void NfcTag::fillNativeNfcTagMembers2 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& /*activationData*/) { static const char fn [] = "NfcTag::fillNativeNfcTagMembers2"; ALOGD ("%s", fn); - jfieldID f = NULL; - - f = e->GetFieldID (tag_cls, "mConnectedTechIndex", "I"); - e->SetIntField (tag, f, (jint) 0); + jfieldID f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I"); + e->SetIntField(tag, f, (jint) 0); } @@ -646,9 +636,9 @@ void NfcTag::fillNativeNfcTagMembers2 (JNIEnv* e, jclass tag_cls, jobject tag, t void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData) { static const char fn [] = "NfcTag::fillNativeNfcTagMembers3"; - jfieldID f = NULL; - jbyteArray pollBytes = e->NewByteArray (0); - jobjectArray techPollBytes = e->NewObjectArray (mNumTechList, e->GetObjectClass(pollBytes), 0); + ScopedLocalRef<jbyteArray> pollBytes(e, e->NewByteArray(0)); + ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(pollBytes.get())); + ScopedLocalRef<jobjectArray> techPollBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0)); int len = 0; for (int i = 0; i < mNumTechList; i++) @@ -661,9 +651,8 @@ void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, t case NFC_DISCOVERY_TYPE_LISTEN_A: case NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE: ALOGD ("%s: tech A", fn); - pollBytes = e->NewByteArray (2); - e->SetByteArrayRegion (pollBytes, 0, 2, - (jbyte*) mTechParams [i].param.pa.sens_res); + pollBytes.reset(e->NewByteArray(2)); + e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte*) mTechParams [i].param.pa.sens_res); break; case NFC_DISCOVERY_TYPE_POLL_B: @@ -680,11 +669,11 @@ void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, t ALOGD ("%s: tech B; TARGET_TYPE_ISO14443_3B", fn); len = mTechParams [i].param.pb.sensb_res_len; len = len - 4; //subtract 4 bytes for NFCID0 at byte 2 through 5 - pollBytes = e->NewByteArray (len); - e->SetByteArrayRegion (pollBytes, 0, len, (jbyte*) (mTechParams [i].param.pb.sensb_res+4)); + pollBytes.reset(e->NewByteArray(len)); + e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) (mTechParams [i].param.pb.sensb_res+4)); + } else { + pollBytes.reset(e->NewByteArray(0)); } - else - pollBytes = e->NewByteArray (0); break; case NFC_DISCOVERY_TYPE_POLL_F: @@ -718,9 +707,9 @@ void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, t result [9] = (UINT8) systemCode; ALOGD ("%s: tech F; sys code=0x%X 0x%X", fn, result [8], result [9]); } - pollBytes = e->NewByteArray (len); - e->SetByteArrayRegion (pollBytes, 0, len, (jbyte*) result); - } + pollBytes.reset(e->NewByteArray(len)); + e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) result); + } break; case NFC_DISCOVERY_TYPE_POLL_ISO15693: @@ -731,20 +720,20 @@ void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, t //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags(); uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid}; - pollBytes = e->NewByteArray (2); - e->SetByteArrayRegion (pollBytes, 0, 2, (jbyte *) data); + pollBytes.reset(e->NewByteArray(2)); + e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte *) data); } break; default: ALOGE ("%s: tech unknown ????", fn); - pollBytes = e->NewByteArray(0); + pollBytes.reset(e->NewByteArray(0)); break; } //switch: every type of technology - e->SetObjectArrayElement (techPollBytes, i, pollBytes); + e->SetObjectArrayElement(techPollBytes.get(), i, pollBytes.get()); } //for: every technology in the array - f = e->GetFieldID (tag_cls, "mTechPollBytes", "[[B"); - e->SetObjectField (tag, f, techPollBytes); + jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B"); + e->SetObjectField(tag, f, techPollBytes.get()); } @@ -766,11 +755,9 @@ void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, t void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData) { static const char fn [] = "NfcTag::fillNativeNfcTagMembers4"; - jfieldID f = NULL; - jbyteArray actBytes = e->NewByteArray (0); - jobjectArray techActBytes = e->NewObjectArray (mNumTechList, e->GetObjectClass(actBytes), 0); - jbyteArray uid = NULL; - int len = 0; + ScopedLocalRef<jbyteArray> actBytes(e, e->NewByteArray(0)); + ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(actBytes.get())); + ScopedLocalRef<jobjectArray> techActBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0)); for (int i = 0; i < mNumTechList; i++) { @@ -780,18 +767,16 @@ void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, t case NFC_PROTOCOL_T1T: { ALOGD ("%s: T1T; tech A", fn); - actBytes = e->NewByteArray (1); - e->SetByteArrayRegion (actBytes, 0, 1, - (jbyte*) &mTechParams [i].param.pa.sel_rsp); + actBytes.reset(e->NewByteArray(1)); + e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp); } break; - case NFC_PROTOCOL_T2T: + case NFC_PROTOCOL_T2T: // TODO: why is this code a duplicate of NFC_PROTOCOL_T1T? { ALOGD ("%s: T2T; tech A", fn); - actBytes = e->NewByteArray (1); - e->SetByteArrayRegion (actBytes, 0, 1, - (jbyte*) &mTechParams [i].param.pa.sel_rsp); + actBytes.reset(e->NewByteArray(1)); + e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp); } break; @@ -799,7 +784,7 @@ void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, t { ALOGD ("%s: T3T; felica; tech F", fn); //really, there is no data - actBytes = e->NewByteArray (0); + actBytes.reset(e->NewByteArray(0)); } break; @@ -819,14 +804,14 @@ void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, t { tNFC_INTF_PA_ISO_DEP& pa_iso = activationData.activate_ntf.intf_param.intf_param.pa_iso; ALOGD ("%s: T4T; ISO_DEP for tech A; copy historical bytes; len=%u", fn, pa_iso.his_byte_len); - actBytes = e->NewByteArray (pa_iso.his_byte_len); + actBytes.reset(e->NewByteArray(pa_iso.his_byte_len)); if (pa_iso.his_byte_len > 0) - e->SetByteArrayRegion (actBytes, 0, pa_iso.his_byte_len, (jbyte*) (pa_iso.his_byte)); + e->SetByteArrayRegion(actBytes.get(), 0, pa_iso.his_byte_len, (jbyte*) (pa_iso.his_byte)); } else { ALOGE ("%s: T4T; ISO_DEP for tech A; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type); - actBytes = e->NewByteArray (0); + actBytes.reset(e->NewByteArray(0)); } } else if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B) || @@ -841,26 +826,26 @@ void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, t { tNFC_INTF_PB_ISO_DEP& pb_iso = activationData.activate_ntf.intf_param.intf_param.pb_iso; ALOGD ("%s: T4T; ISO_DEP for tech B; copy response bytes; len=%u", fn, pb_iso.hi_info_len); - actBytes = e->NewByteArray (pb_iso.hi_info_len); + actBytes.reset(e->NewByteArray(pb_iso.hi_info_len)); if (pb_iso.hi_info_len > 0) - e->SetByteArrayRegion (actBytes, 0, pb_iso.hi_info_len, (jbyte*) (pb_iso.hi_info)); + e->SetByteArrayRegion(actBytes.get(), 0, pb_iso.hi_info_len, (jbyte*) (pb_iso.hi_info)); } else { ALOGE ("%s: T4T; ISO_DEP for tech B; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type); - actBytes = e->NewByteArray (0); + actBytes.reset(e->NewByteArray(0)); } } } else if (mTechList [i] == TARGET_TYPE_ISO14443_3A) //is TagTechnology.NFC_A by Java API { ALOGD ("%s: T4T; tech A", fn); - actBytes = e->NewByteArray (1); - e->SetByteArrayRegion (actBytes, 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp); + actBytes.reset(e->NewByteArray(1)); + e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp); } else { - actBytes = e->NewByteArray (0); + actBytes.reset(e->NewByteArray(0)); } } //case NFC_PROTOCOL_ISO_DEP: //t4t break; @@ -872,20 +857,20 @@ void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, t //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags(); uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid}; - actBytes = e->NewByteArray (2); - e->SetByteArrayRegion (actBytes, 0, 2, (jbyte *) data); + actBytes.reset(e->NewByteArray(2)); + e->SetByteArrayRegion(actBytes.get(), 0, 2, (jbyte *) data); } break; default: ALOGD ("%s: tech unknown ????", fn); - actBytes = e->NewByteArray (0); + actBytes.reset(e->NewByteArray(0)); break; }//switch - e->SetObjectArrayElement (techActBytes, i, actBytes); + e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get()); } //for: every technology in the array - f = e->GetFieldID (tag_cls, "mTechActBytes", "[[B"); - e->SetObjectField (tag, f, techActBytes); + jfieldID f = e->GetFieldID (tag_cls, "mTechActBytes", "[[B"); + e->SetObjectField(tag, f, techActBytes.get()); } @@ -907,17 +892,16 @@ void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, t void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData) { static const char fn [] = "NfcTag::fillNativeNfcTagMembers5"; - jfieldID f = NULL; int len = 0; - jbyteArray uid = NULL; + ScopedLocalRef<jbyteArray> uid(e, NULL); switch (mTechParams [0].mode) { case NFC_DISCOVERY_TYPE_POLL_KOVIO: ALOGD ("%s: Kovio", fn); len = mTechParams [0].param.pk.uid_len; - uid = e->NewByteArray (len); - e->SetByteArrayRegion (uid, 0, len, + uid.reset(e->NewByteArray(len)); + e->SetByteArrayRegion(uid.get(), 0, len, (jbyte*) &mTechParams [0].param.pk.uid); break; @@ -927,8 +911,8 @@ void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, t case NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE: ALOGD ("%s: tech A", fn); len = mTechParams [0].param.pa.nfcid1_len; - uid = e->NewByteArray (len); - e->SetByteArrayRegion (uid, 0, len, + uid.reset(e->NewByteArray(len)); + e->SetByteArrayRegion(uid.get(), 0, len, (jbyte*) &mTechParams [0].param.pa.nfcid1); break; @@ -937,8 +921,8 @@ void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, t case NFC_DISCOVERY_TYPE_LISTEN_B: case NFC_DISCOVERY_TYPE_LISTEN_B_PRIME: ALOGD ("%s: tech B", fn); - uid = e->NewByteArray (NFC_NFCID0_MAX_LEN); - e->SetByteArrayRegion (uid, 0, NFC_NFCID0_MAX_LEN, + uid.reset(e->NewByteArray(NFC_NFCID0_MAX_LEN)); + e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID0_MAX_LEN, (jbyte*) &mTechParams [0].param.pb.nfcid0); break; @@ -947,8 +931,8 @@ void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, t case NFC_DISCOVERY_TYPE_LISTEN_F: case NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE: ALOGD ("%s: tech F", fn); - uid = e->NewByteArray (NFC_NFCID2_LEN); - e->SetByteArrayRegion (uid, 0, NFC_NFCID2_LEN, + uid.reset(e->NewByteArray(NFC_NFCID2_LEN)); + e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID2_LEN, (jbyte*) &mTechParams [0].param.pf.nfcid2); break; @@ -959,18 +943,18 @@ void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, t jbyte data [I93_UID_BYTE_LEN]; //8 bytes for (int i=0; i<I93_UID_BYTE_LEN; ++i) //reverse the ID data[i] = activationData.params.i93.uid [I93_UID_BYTE_LEN - i - 1]; - uid = e->NewByteArray (I93_UID_BYTE_LEN); - e->SetByteArrayRegion (uid, 0, I93_UID_BYTE_LEN, data); + uid.reset(e->NewByteArray(I93_UID_BYTE_LEN)); + e->SetByteArrayRegion(uid.get(), 0, I93_UID_BYTE_LEN, data); } break; default: ALOGE ("%s: tech unknown ????", fn); - uid = e->NewByteArray (0); + uid.reset(e->NewByteArray(0)); break; - } //if - f = e->GetFieldID(tag_cls, "mUid", "[B"); - e->SetObjectField(tag, f, uid); + } + jfieldID f = e->GetFieldID(tag_cls, "mUid", "[B"); + e->SetObjectField(tag, f, uid.get()); } @@ -1322,4 +1306,3 @@ void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data) } } } - diff --git a/nci/jni/PeerToPeer.cpp b/nci/jni/PeerToPeer.cpp index b40e3663..087cd7ad 100644 --- a/nci/jni/PeerToPeer.cpp +++ b/nci/jni/PeerToPeer.cpp @@ -23,6 +23,16 @@ #include "llcp_defs.h" #include "config.h" #include "JavaClassConstants.h" +#include <ScopedLocalRef.h> + +/* Some older PN544-based solutions would only send the first SYMM back + * (as an initiator) after the full LTO (750ms). But our connect timer + * starts immediately, and hence we may timeout if the timer is set to + * 1000 ms. Worse, this causes us to immediately connect to the NPP + * socket, causing concurrency issues in that stack. Increase the default + * timeout to 2000 ms, giving us enough time to complete the first connect. + */ +#define LLCP_DATA_LINK_TIMEOUT 2000 using namespace android; @@ -55,7 +65,6 @@ PeerToPeer::PeerToPeer () | NFA_TECHNOLOGY_MASK_F_ACTIVE), mNextJniHandle (1) { - unsigned long num = 0; memset (mServers, 0, sizeof(mServers)); memset (mClients, 0, sizeof(mClients)); } @@ -202,9 +211,7 @@ 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; sp<P2pServer> pSrv = NULL; - UINT8 serverSap = NFA_P2P_ANY_SAP; mMutex.lock(); // Check if already registered @@ -293,18 +300,14 @@ void PeerToPeer::llcpActivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_ACTIV { static const char fn [] = "PeerToPeer::llcpActivatedHandler"; ALOGD ("%s: enter", fn); - JNIEnv* e = NULL; - jclass tag_cls = NULL; - jobject tag = NULL; - jmethodID ctor = 0; - jfieldID f = 0; //no longer need to receive NDEF message from a tag android::nativeNfcTag_deregisterNdefTypeHandler (); mRemoteWKS = activated.remote_wks; - nat->vm->AttachCurrentThread (&e, NULL); + JNIEnv* e = NULL; + ScopedAttach attach(nat->vm, &e); if (e == NULL) { ALOGE ("%s: jni env is null", fn); @@ -312,57 +315,47 @@ void PeerToPeer::llcpActivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_ACTIV } ALOGD ("%s: get object class", fn); - tag_cls = e->GetObjectClass (nat->cached_P2pDevice); - if (e->ExceptionCheck()) - { + ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_P2pDevice)); + if (e->ExceptionCheck()) { e->ExceptionClear(); ALOGE ("%s: fail get p2p device", fn); - goto TheEnd; + return; } ALOGD ("%s: instantiate", fn); /* New target instance */ - ctor = e->GetMethodID (tag_cls, "<init>", "()V"); - tag = e->NewObject (tag_cls, ctor); + jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V"); + ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor)); /* Set P2P Target mode */ - f = e->GetFieldID (tag_cls, "mMode", "I"); + jfieldID f = e->GetFieldID(tag_cls.get(), "mMode", "I"); - if (activated.is_initiator == TRUE) - { + if (activated.is_initiator == TRUE) { ALOGD ("%s: p2p initiator", fn); - e->SetIntField (tag, f, (jint) MODE_P2P_INITIATOR); - } - else - { + e->SetIntField(tag.get(), f, (jint) MODE_P2P_INITIATOR); + } else { ALOGD ("%s: p2p target", fn); - e->SetIntField (tag, f, (jint) MODE_P2P_TARGET); + e->SetIntField(tag.get(), f, (jint) MODE_P2P_TARGET); } /* Set tag handle */ - f = e->GetFieldID (tag_cls, "mHandle", "I"); - e->SetIntField (tag, f, (jint) 0x1234); // ?? This handle is not used for anything + f = e->GetFieldID(tag_cls.get(), "mHandle", "I"); + e->SetIntField(tag.get(), f, (jint) 0x1234); // ?? This handle is not used for anything - if (nat->tag != NULL) - { - e->DeleteGlobalRef (nat->tag); + if (nat->tag != NULL) { + e->DeleteGlobalRef(nat->tag); } - nat->tag = e->NewGlobalRef (tag); + nat->tag = e->NewGlobalRef(tag.get()); ALOGD ("%s: notify nfc service", fn); /* Notify manager that new a P2P device was found */ - e->CallVoidMethod (nat->manager, android::gCachedNfcManagerNotifyLlcpLinkActivation, tag); - if (e->ExceptionCheck()) - { + e->CallVoidMethod(nat->manager, android::gCachedNfcManagerNotifyLlcpLinkActivation, tag.get()); + if (e->ExceptionCheck()) { e->ExceptionClear(); ALOGE ("%s: fail notify", fn); } - e->DeleteLocalRef (tag); - -TheEnd: - nat->vm->DetachCurrentThread (); ALOGD ("%s: exit", fn); } @@ -378,13 +371,13 @@ TheEnd: ** Returns: None ** *******************************************************************************/ -void PeerToPeer::llcpDeactivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_DEACTIVATED& deactivated) +void PeerToPeer::llcpDeactivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_DEACTIVATED& /*deactivated*/) { static const char fn [] = "PeerToPeer::llcpDeactivatedHandler"; ALOGD ("%s: enter", fn); - JNIEnv* e = NULL; - nat->vm->AttachCurrentThread (&e, NULL); + JNIEnv* e = NULL; + ScopedAttach attach(nat->vm, &e); if (e == NULL) { ALOGE ("%s: jni env is null", fn); @@ -400,14 +393,36 @@ void PeerToPeer::llcpDeactivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_DEA ALOGE ("%s: fail notify", fn); } - nat->vm->DetachCurrentThread (); - //let the tag-reading code handle NDEF data event android::nativeNfcTag_registerNdefTypeHandler (); ALOGD ("%s: exit", fn); } +void PeerToPeer::llcpFirstPacketHandler (nfc_jni_native_data* nat) +{ + static const char fn [] = "PeerToPeer::llcpFirstPacketHandler"; + ALOGD ("%s: enter", fn); + JNIEnv* e = NULL; + ScopedAttach attach(nat->vm, &e); + if (e == NULL) + { + ALOGE ("%s: jni env is null", fn); + return; + } + + ALOGD ("%s: notify nfc service", fn); + /* Notify manager that the LLCP is lost or deactivated */ + e->CallVoidMethod (nat->manager, android::gCachedNfcManagerNotifyLlcpFirstPacketReceived, nat->tag); + if (e->ExceptionCheck()) + { + e->ExceptionClear(); + ALOGE ("%s: fail notify", fn); + } + + ALOGD ("%s: exit", fn); + +} /******************************************************************************* ** ** Function: accept @@ -424,10 +439,6 @@ void PeerToPeer::llcpDeactivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_DEA bool PeerToPeer::accept (tJNI_HANDLE serverJniHandle, tJNI_HANDLE connJniHandle, int maxInfoUnit, int recvWindow) { static const char fn [] = "PeerToPeer::accept"; - tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - sp<NfaConn> *pConn = NULL; - bool stat = false; - int ii = 0; sp<P2pServer> pSrv = NULL; ALOGD ("%s: enter; server jni handle: %u; conn jni handle: %u; maxInfoUnit: %d; recvWindow: %d", fn, @@ -565,11 +576,10 @@ bool PeerToPeer::createClient (tJNI_HANDLE jniHandle, UINT16 miu, UINT8 rw) 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++) + for (size_t ii = 0; ii < sMax; ii++) { if ((mClients[ii] != NULL) && (mClients[ii]->mClientConn->mJniHandle == jniHandle)) { @@ -583,7 +593,7 @@ void PeerToPeer::removeConn(tJNI_HANDLE jniHandle) } // If the connection is for a server, just delete the connection - for (ii = 0; ii < sMax; ii++) + for (size_t ii = 0; ii < sMax; ii++) { if (mServers[ii] != NULL) { @@ -781,11 +791,9 @@ sp<P2pClient> PeerToPeer::findClientCon (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++) + for (size_t ii = 0; ii < sMax; ii++) { if ( (mClients[ii] != NULL) && (mClients[ii]->mClientConn->mNfaConnHandle == nfaConnHandle) ) { @@ -794,7 +802,7 @@ sp<NfaConn> PeerToPeer::findConnection (tNFA_HANDLE nfaConnHandle) } // Not found yet. Look through all the server control blocks - for (ii = 0; ii < sMax; ii++) + for (size_t ii = 0; ii < sMax; ii++) { if (mServers[ii] != NULL) { @@ -822,11 +830,9 @@ sp<NfaConn> PeerToPeer::findConnection (tNFA_HANDLE nfaConnHandle) *******************************************************************************/ 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++) + for (size_t ii = 0; ii < sMax; ii++) { if ( (mClients[ii] != NULL) && (mClients[ii]->mClientConn->mJniHandle == jniHandle) ) { @@ -835,7 +841,7 @@ sp<NfaConn> PeerToPeer::findConnection (tJNI_HANDLE jniHandle) } // Not found yet. Look through all the server control blocks - for (ii = 0; ii < sMax; ii++) + for (size_t ii = 0; ii < sMax; ii++) { if (mServers[ii] != NULL) { @@ -1142,7 +1148,6 @@ void PeerToPeer::handleNfcOnOff (bool isOn) { static const char fn [] = "PeerToPeer::handleNfcOnOff"; ALOGD ("%s: enter; is on=%u", fn, isOn); - tNFA_STATUS stat = NFA_STATUS_FAILED; mIsP2pListening = false; // In both cases, P2P will not be listening @@ -1155,10 +1160,8 @@ void PeerToPeer::handleNfcOnOff (bool isOn) } else { - int ii = 0, jj = 0; - // Disconnect through all the clients - for (ii = 0; ii < sMax; ii++) + for (size_t ii = 0; ii < sMax; ii++) { if (mClients[ii] != NULL) { @@ -1183,7 +1186,7 @@ void PeerToPeer::handleNfcOnOff (bool isOn) } //loop // Now look through all the server control blocks - for (ii = 0; ii < sMax; ii++) + for (size_t ii = 0; ii < sMax; ii++) { if (mServers[ii] != NULL) { @@ -1515,7 +1518,7 @@ void PeerToPeer::nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* ev ** Returns: None ** *******************************************************************************/ -void PeerToPeer::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* eventData) +void PeerToPeer::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* /*eventData*/) { switch (event) { @@ -1597,7 +1600,7 @@ bool P2pServer::registerWithStack() 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_DATA_LINK_TIMEOUT, LLCP_DELAY_TIME_TO_SEND_FIRST_PDU); if (stat != NFA_STATUS_OK) ALOGE ("%s: fail set LLCP config; error=0x%X", fn, stat); @@ -1837,4 +1840,3 @@ NfaConn::NfaConn() mRemoteRecvWindow (0) { } - diff --git a/nci/jni/PeerToPeer.h b/nci/jni/PeerToPeer.h index 3e8ffec0..11733f3e 100644 --- a/nci/jni/PeerToPeer.h +++ b/nci/jni/PeerToPeer.h @@ -26,7 +26,6 @@ extern "C" { #include "nfa_p2p_api.h" - #include "nfa_snep_api.h" } class P2pServer; @@ -121,6 +120,7 @@ public: *******************************************************************************/ void llcpDeactivatedHandler (nfc_jni_native_data* nativeData, tNFA_LLCP_DEACTIVATED& deactivated); + void llcpFirstPacketHandler(nfc_jni_native_data* nativeData); /******************************************************************************* ** @@ -393,19 +393,6 @@ private: Mutex mDisconnectMutex; // synchronize the disconnect operation Mutex mNewJniHandleMutex; // synchronize the creation of a new JNI handle - /******************************************************************************* - ** - ** Function: snepClientCallback - ** - ** Description: Receive SNEP-related events from the stack. - ** snepEvent: Event code. - ** eventData: Event data. - ** - ** Returns: None - ** - *******************************************************************************/ - static void snepClientCallback (tNFA_SNEP_EVT snepEvent, tNFA_SNEP_EVT_DATA *eventData); - /******************************************************************************* ** diff --git a/nci/jni/RouteDataSet.cpp b/nci/jni/RouteDataSet.cpp index 1458776b..e0a918f8 100644 --- a/nci/jni/RouteDataSet.cpp +++ b/nci/jni/RouteDataSet.cpp @@ -528,6 +528,7 @@ void RouteDataSet::printDiagnostic () ALOGD ("%s: ee h=0x%X; protocol=0x%X", fn, proto->mNfaEeHandle, proto->mProtocol); } break; + // TODO: RouteData::TechnologyRoute isn't handled --- bug? } } diff --git a/nci/jni/SecureElement.cpp b/nci/jni/SecureElement.cpp index a4c4d57e..101bd38c 100755 --- a/nci/jni/SecureElement.cpp +++ b/nci/jni/SecureElement.cpp @@ -20,6 +20,7 @@ */ #include <semaphore.h> #include <errno.h> +#include <ScopedLocalRef.h> #include "OverrideLog.h" #include "SecureElement.h" #include "config.h" @@ -40,6 +41,7 @@ bool gUseStaticPipe = false; // if true, use gGatePipe as static pipe id. if namespace android { extern void startRfDiscovery (bool isStart); + extern void setUiccIdleTimeout (bool enable); } ////////////////////////////////////////////// @@ -149,7 +151,6 @@ bool SecureElement::initialize (nfc_jni_native_data* native) { static const char fn [] = "SecureElement::initialize"; tNFA_STATUS nfaStat; - UINT8 xx = 0, yy = 0; unsigned long num = 0; ALOGD ("%s: enter", fn); @@ -177,6 +178,8 @@ bool SecureElement::initialize (nfc_jni_native_data* native) mbNewEE = true; mNewPipeId = 0; mNewSourceGate = 0; + mRfFieldIsOn = false; + mActivatedInListenMode = false; mCurrentRouteSelection = NoRoute; memset (mEeInfo, 0, sizeof(mEeInfo)); memset (&mUiccInfo, 0, sizeof(mUiccInfo)); @@ -201,7 +204,7 @@ bool SecureElement::initialize (nfc_jni_native_data* native) } // If the controller has an HCI Network, register for that - for (xx = 0; xx < mActualNumEe; xx++) + for (size_t xx = 0; xx < mActualNumEe; xx++) { if ((mEeInfo[xx].num_interface > 0) && (mEeInfo[xx].ee_interface[0] == NCI_NFCEE_INTERFACE_HCI_ACCESS) ) { @@ -245,7 +248,6 @@ void SecureElement::finalize () { static const char fn [] = "SecureElement::finalize"; ALOGD ("%s: enter", fn); - tNFA_STATUS nfaStat = NFA_STATUS_FAILED; NFA_EeDeregister (nfaEeCallback); @@ -281,7 +283,6 @@ bool SecureElement::getEeInfo() static const char fn [] = "SecureElement::getEeInfo"; ALOGD ("%s: enter; mbNewEE=%d, mActualNumEe=%d", fn, mbNewEE, mActualNumEe); tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - UINT8 xx = 0, yy = 0; // If mbNewEE is true then there is new EE info. if (mbNewEE) @@ -309,7 +310,7 @@ bool SecureElement::getEeInfo() fn, xx, mEeInfo[xx].ee_handle, eeStatusToString(mEeInfo[xx].ee_status), mEeInfo[xx].num_interface, mEeInfo[xx].ee_interface[0], mEeInfo[xx].ee_interface[1], mEeInfo[xx].num_tlvs); - for (yy = 0; yy < mEeInfo[xx].num_tlvs; yy++) + for (size_t yy = 0; yy < mEeInfo[xx].num_tlvs; yy++) { ALOGD ("%s: EE[%u] TLV[%u] Tag: 0x%02x Len: %u Values[]: 0x%02x 0x%02x 0x%02x ...", fn, xx, yy, mEeInfo[xx].ee_tlv[yy].tag, mEeInfo[xx].ee_tlv[yy].len, mEeInfo[xx].ee_tlv[yy].info[0], @@ -404,7 +405,6 @@ jintArray SecureElement::getListOfEeHandles (JNIEnv* e) ALOGD ("%s: enter", fn); if (mNumEePresent == 0) return NULL; - jintArray list = NULL; if (!mIsInit) { @@ -416,7 +416,7 @@ jintArray SecureElement::getListOfEeHandles (JNIEnv* e) if (! getEeInfo()) return (NULL); - list = e->NewIntArray (mNumEePresent); //allocate array + jintArray list = e->NewIntArray (mNumEePresent); //allocate array jint jj = 0; int cnt = 0; for (int ii = 0; ii < mActualNumEe && cnt < mNumEePresent; ii++) @@ -430,7 +430,6 @@ jintArray SecureElement::getListOfEeHandles (JNIEnv* e) jj = mEeInfo[ii].ee_handle & ~NFA_HANDLE_GROUP_EE; e->SetIntArrayRegion (list, cnt++, 1, &jj); } - //e->DeleteLocalRef (list); ALOGD("%s: exit", fn); return list; @@ -537,8 +536,6 @@ bool SecureElement::activate (jint seID) bool SecureElement::deactivate (jint seID) { static const char fn [] = "SecureElement::deactivate"; - tNFA_STATUS nfaStat = NFA_STATUS_FAILED; - int numDeactivatedEe = 0; bool retval = false; ALOGD ("%s: enter; seID=0x%X, mActiveEeHandle=0x%X", fn, seID, mActiveEeHandle); @@ -588,41 +585,37 @@ void SecureElement::notifyTransactionListenersOfAid (const UINT8* aidBuffer, UIN static const char fn [] = "SecureElement::notifyTransactionListenersOfAid"; ALOGD ("%s: enter; aid len=%u", fn, aidBufferLen); - if (aidBufferLen == 0) - return; + if (aidBufferLen == 0) { + return; + } - jobject tlvJavaArray = NULL; JNIEnv* e = NULL; - UINT8* tlv = 0; - const UINT16 tlvMaxLen = aidBufferLen + 10; - UINT16 tlvActualLen = 0; - bool stat = false; - - mNativeData->vm->AttachCurrentThread (&e, NULL); + ScopedAttach attach(mNativeData->vm, &e); if (e == NULL) { ALOGE ("%s: jni env is null", fn); return; } - tlv = new UINT8 [tlvMaxLen]; + const UINT16 tlvMaxLen = aidBufferLen + 10; + UINT8* tlv = new UINT8 [tlvMaxLen]; if (tlv == NULL) { ALOGE ("%s: fail allocate tlv", fn); - goto TheEnd; + return; } memcpy (tlv, aidBuffer, aidBufferLen); - tlvActualLen = aidBufferLen; + UINT16 tlvActualLen = aidBufferLen; - tlvJavaArray = e->NewByteArray (tlvActualLen); - if (tlvJavaArray == NULL) + ScopedLocalRef<jobject> tlvJavaArray(e, e->NewByteArray(tlvActualLen)); + if (tlvJavaArray.get() == NULL) { ALOGE ("%s: fail allocate array", fn); goto TheEnd; } - e->SetByteArrayRegion ((jbyteArray)tlvJavaArray, 0, tlvActualLen, (jbyte *)tlv); + e->SetByteArrayRegion ((jbyteArray)tlvJavaArray.get(), 0, tlvActualLen, (jbyte *)tlv); if (e->ExceptionCheck()) { e->ExceptionClear(); @@ -630,7 +623,7 @@ void SecureElement::notifyTransactionListenersOfAid (const UINT8* aidBuffer, UIN goto TheEnd; } - e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyTransactionListeners, tlvJavaArray); + e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyTransactionListeners, tlvJavaArray.get()); if (e->ExceptionCheck()) { e->ExceptionClear(); @@ -639,9 +632,6 @@ void SecureElement::notifyTransactionListenersOfAid (const UINT8* aidBuffer, UIN } TheEnd: - if (tlvJavaArray) - e->DeleteLocalRef (tlvJavaArray); - mNativeData->vm->DetachCurrentThread (); delete [] tlv; ALOGD ("%s: exit", fn); } @@ -698,6 +688,9 @@ bool SecureElement::connectEE () // Disable RF discovery completely while the DH is connected android::startRfDiscovery(false); + // Disable UICC idle timeout while the DH is connected + android::setUiccIdleTimeout (false); + mNewSourceGate = 0; if (gGatePipe == -1) @@ -878,12 +871,17 @@ bool SecureElement::disconnectEE (jint seID) else ALOGE ("%s: fail dealloc gate; error=0x%X", fn, nfaStat); } + mIsPiping = false; + + // Re-enable UICC low-power mode + android::setUiccIdleTimeout (true); // Re-enable RF discovery // Note that it only effactuates the current configuration, // so if polling/listening were configured OFF (forex because // the screen was off), they will stay OFF with this call. android::startRfDiscovery(true); + return true; } @@ -1007,11 +1005,11 @@ TheEnd: *******************************************************************************/ void SecureElement::notifyListenModeState (bool isActivated) { static const char fn [] = "SecureElement::notifyListenMode"; - JNIEnv *e = NULL; ALOGD ("%s: enter; listen mode active=%u", fn, isActivated); - mNativeData->vm->AttachCurrentThread (&e, NULL); + JNIEnv* e = NULL; + ScopedAttach attach(mNativeData->vm, &e); if (e == NULL) { ALOGE ("%s: jni env is null", fn); @@ -1032,7 +1030,6 @@ void SecureElement::notifyListenModeState (bool isActivated) { ALOGE ("%s: fail notify", fn); } - mNativeData->vm->DetachCurrentThread (); ALOGD ("%s: exit", fn); } @@ -1049,11 +1046,10 @@ void SecureElement::notifyListenModeState (bool isActivated) { void SecureElement::notifyRfFieldEvent (bool isActive) { static const char fn [] = "SecureElement::notifyRfFieldEvent"; - JNIEnv *e = NULL; - ALOGD ("%s: enter; is active=%u", fn, isActive); - mNativeData->vm->AttachCurrentThread (&e, NULL); + JNIEnv* e = NULL; + ScopedAttach attach(mNativeData->vm, &e); if (e == NULL) { ALOGE ("%s: jni env is null", fn); @@ -1081,7 +1077,33 @@ void SecureElement::notifyRfFieldEvent (bool isActive) e->ExceptionClear(); ALOGE ("%s: fail notify", fn); } - mNativeData->vm->DetachCurrentThread (); + ALOGD ("%s: exit", fn); +} + +/******************************************************************************* +** +** Function: resetRfFieldStatus +** +** Description: Resets the field status. +** isActive: Whether any secure element is activated. +** +** Returns: None +** +*******************************************************************************/ +void SecureElement::resetRfFieldStatus () +{ + static const char fn [] = "SecureElement::resetRfFieldStatus`"; + ALOGD ("%s: enter;"); + + mMutex.lock(); + mRfFieldIsOn = false; + int ret = clock_gettime (CLOCK_MONOTONIC, &mLastRfFieldToggle); + if (ret == -1) { + ALOGE("%s: clock_gettime failed", fn); + // There is no good choice here... + } + mMutex.unlock(); + ALOGD ("%s: exit", fn); } @@ -1134,9 +1156,9 @@ bool SecureElement::getUiccId (tNFA_HANDLE eeHandle, jbyteArray& uid) static const char fn [] = "SecureElement::getUiccId"; ALOGD ("%s: ee h=0x%X", fn, eeHandle); bool retval = false; - JNIEnv* e = NULL; - mNativeData->vm->AttachCurrentThread (&e, NULL); + JNIEnv* e = NULL; + ScopedAttach attach(mNativeData->vm, &e); if (e == NULL) { ALOGE ("%s: jni env is null", fn); @@ -1146,8 +1168,9 @@ bool SecureElement::getUiccId (tNFA_HANDLE eeHandle, jbyteArray& uid) findUiccByHandle (eeHandle); //cannot get UID from the stack; nothing to do -TheEnd: - mNativeData->vm->DetachCurrentThread (); + // TODO: uid is unused --- bug? + + // TODO: retval is always false --- bug? ALOGD ("%s: exit; ret=%u", fn, retval); return retval; } @@ -1169,10 +1192,9 @@ bool SecureElement::getTechnologyList (tNFA_HANDLE eeHandle, jintArray& techList static const char fn [] = "SecureElement::getTechnologyList"; ALOGD ("%s: ee h=0x%X", fn, eeHandle); bool retval = false; - JNIEnv* e = NULL; - jint theList = 0; - mNativeData->vm->AttachCurrentThread (&e, NULL); + JNIEnv* e = NULL; + ScopedAttach attach(mNativeData->vm, &e); if (e == NULL) { ALOGE ("%s: jni env is null", fn); @@ -1181,6 +1203,8 @@ bool SecureElement::getTechnologyList (tNFA_HANDLE eeHandle, jintArray& techList tNFA_EE_DISCOVER_INFO *pUICC = findUiccByHandle (eeHandle); + // TODO: theList is written but not set --- bug? + jint theList = 0; if (pUICC->la_protocol != 0) theList = TARGET_TYPE_ISO14443_3A; else if (pUICC->lb_protocol != 0) @@ -1192,8 +1216,9 @@ bool SecureElement::getTechnologyList (tNFA_HANDLE eeHandle, jintArray& techList else theList = TARGET_TYPE_UNKNOWN; -TheEnd: - mNativeData->vm->DetachCurrentThread (); + // TODO: techList is neither read nor written --- bug? + + // TODO: retval is always false --- bug? ALOGD ("%s: exit; ret=%u", fn, retval); return retval; } @@ -1213,7 +1238,6 @@ void SecureElement::adjustRoutes (RouteSelection selection) { static const char fn [] = "SecureElement::adjustRoutes"; ALOGD ("%s: enter; selection=%u", fn, selection); - tNFA_STATUS nfaStat = NFA_STATUS_FAILED; RouteDataSet::Database* db = mRouteDataSet.getDatabase (RouteDataSet::DefaultRouteDatabase); if (selection == SecElemRoute) @@ -2035,7 +2059,7 @@ const char* SecureElement::eeStatusToString (UINT8 status) ** Returns: None ** *******************************************************************************/ -void SecureElement::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* eventData) +void SecureElement::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* /*eventData*/) { switch (event) { @@ -2176,4 +2200,3 @@ bool SecureElement::isBusy () ALOGD ("SecureElement::isBusy: %u", retval); return retval; } - diff --git a/nci/jni/SecureElement.h b/nci/jni/SecureElement.h index 1758590c..c537b2bc 100755 --- a/nci/jni/SecureElement.h +++ b/nci/jni/SecureElement.h @@ -185,6 +185,17 @@ public: /******************************************************************************* ** + ** Function: resetRfFieldStatus (); + ** + ** Description: Resets the field status. + ** + ** Returns: None + ** + *******************************************************************************/ + void resetRfFieldStatus (); + + /******************************************************************************* + ** ** Function: storeUiccInfo ** ** Description: Store a copy of the execution environment information from the stack. diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java index d045ae2a..aea5f972 100755 --- a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java +++ b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java @@ -359,6 +359,13 @@ public class NativeNfcManager implements DeviceHost { mListener.onLlcpLinkDeactivated(device); } + /** + * Notifies first packet received from remote LLCP + */ + private void notifyLlcpLinkFirstPacketReceived(NativeP2pDevice device) { + mListener.onLlcpFirstPacketReceived(device); + } + private void notifySeFieldActivated() { mListener.onRemoteFieldActivated(); } diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java b/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java index eb8410f9..d0fc6d9d 100755 --- a/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java +++ b/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java @@ -28,6 +28,7 @@ import android.nfc.tech.NfcA; import android.nfc.tech.NfcB; import android.nfc.tech.NfcF; import android.nfc.tech.NfcV; +import android.nfc.tech.NfcBarcode; import android.nfc.tech.TagTechnology; import android.os.Bundle; import android.util.Log; @@ -702,6 +703,12 @@ public class NativeNfcTag implements TagEndpoint { break; } + case TagTechnology.NFC_BARCODE: { + // hard code this for now, this is the only valid type + extras.putInt(NfcBarcode.EXTRA_BARCODE_TYPE, NfcBarcode.TYPE_KOVIO); + break; + } + default: { // Leave the entry in the array null continue; |