summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jni/com_android_nfc_NativeNfcTag.cpp63
-rwxr-xr-xsrc/com/android/nfc/NativeNfcTag.java53
-rwxr-xr-xsrc/com/android/nfc/NfcService.java54
3 files changed, 98 insertions, 72 deletions
diff --git a/jni/com_android_nfc_NativeNfcTag.cpp b/jni/com_android_nfc_NativeNfcTag.cpp
index ade5307..e724309 100644
--- a/jni/com_android_nfc_NativeNfcTag.cpp
+++ b/jni/com_android_nfc_NativeNfcTag.cpp
@@ -444,13 +444,12 @@ static void set_target_activationBytes(JNIEnv *e, jobject tag,
e->ReleaseIntArrayElements(techList, techId, 0);
}
-static jboolean com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e,
+static jint com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e,
jobject o, phLibNfc_Handle handle)
{
jclass cls;
jfieldID f;
- NFCSTATUS status;
- jboolean result = JNI_FALSE;
+ jint status;
struct nfc_jni_callback_data cb_data;
phLibNfc_sRemoteDevInformation_t* pRemDevInfo = NULL;
@@ -459,6 +458,7 @@ static jboolean com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e,
/* Create the local semaphore */
if (!nfc_cb_data_init(&cb_data, &pRemDevInfo))
{
+ status = NFCSTATUS_NOT_ENOUGH_MEMORY;
goto clean_and_return;
}
@@ -478,11 +478,15 @@ static jboolean com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e,
if(sem_wait(&cb_data.sem))
{
LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
+ status = NFCSTATUS_ABORTED;
goto clean_and_return;
}
-
+
+ status = cb_data.status;
+ TRACE("phLibNfc_RemoteDev_Connect() - Status code = %d", status);
+
/* Connect Status */
- if(cb_data.status != NFCSTATUS_SUCCESS)
+ if(status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
@@ -491,21 +495,18 @@ static jboolean com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e,
set_target_pollBytes(e, o, pRemDevInfo);
set_target_activationBytes(e, o, pRemDevInfo);
- result = JNI_TRUE;
-
clean_and_return:
nfc_cb_data_deinit(&cb_data);
CONCURRENCY_UNLOCK();
- return result;
+ return status;
}
-static jboolean com_android_nfc_NativeNfcTag_doHandleReconnect(JNIEnv *e,
+static jint com_android_nfc_NativeNfcTag_doHandleReconnect(JNIEnv *e,
jobject o, phLibNfc_Handle handle)
{
jclass cls;
jfieldID f;
- NFCSTATUS status;
- jboolean result = JNI_FALSE;
+ jint status;
struct nfc_jni_callback_data cb_data;
phLibNfc_sRemoteDevInformation_t* pRemDevInfo = NULL;
CONCURRENCY_LOCK();
@@ -513,6 +514,7 @@ static jboolean com_android_nfc_NativeNfcTag_doHandleReconnect(JNIEnv *e,
/* Create the local semaphore */
if (!nfc_cb_data_init(&cb_data, &pRemDevInfo))
{
+ status = NFCSTATUS_NOT_ENOUGH_MEMORY;
goto clean_and_return;
}
@@ -532,24 +534,25 @@ static jboolean com_android_nfc_NativeNfcTag_doHandleReconnect(JNIEnv *e,
if(sem_wait(&cb_data.sem))
{
LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
+ status = NFCSTATUS_ABORTED;
goto clean_and_return;
}
+ status = cb_data.status;
+
/* Connect Status */
- if(cb_data.status != NFCSTATUS_SUCCESS)
+ if(status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
- result = JNI_TRUE;
-
clean_and_return:
nfc_cb_data_deinit(&cb_data);
CONCURRENCY_UNLOCK();
- return result;
+ return status;
}
-static jboolean com_android_nfc_NativeNfcTag_doReconnect(JNIEnv *e,
+static jint com_android_nfc_NativeNfcTag_doReconnect(JNIEnv *e,
jobject o)
{
// Reconnect is provided by libnfc by just calling connect again
@@ -563,11 +566,11 @@ static jboolean com_android_nfc_NativeNfcTag_doReconnect(JNIEnv *e,
return com_android_nfc_NativeNfcTag_doConnect(e, o, handle);
}
else {
- return JNI_TRUE;
+ return NFCSTATUS_SUCCESS;
}
}
else {
- return JNI_FALSE;
+ return NFCSTATUS_REJECTED;
}
}
@@ -940,11 +943,10 @@ static jint com_android_nfc_NativeNfcTag_doGetNdefType(JNIEnv *e, jobject o,
return ndefType;
}
-static bool com_android_nfc_NativeNfcTag_doCheckNdef(JNIEnv *e, jobject o, jintArray ndefinfo)
+static jint com_android_nfc_NativeNfcTag_doCheckNdef(JNIEnv *e, jobject o, jintArray ndefinfo)
{
phLibNfc_Handle handle = 0;
- NFCSTATUS status;
- bool result = JNI_FALSE;
+ jint status;
phLibNfc_ChkNdef_Info_t sNdefInfo;
struct nfc_jni_callback_data cb_data;
jint *ndef = e->GetIntArrayElements(ndefinfo, 0);
@@ -955,6 +957,7 @@ static bool com_android_nfc_NativeNfcTag_doCheckNdef(JNIEnv *e, jobject o, jintA
/* Create the local semaphore */
if (!nfc_cb_data_init(&cb_data, NULL))
{
+ status = NFCSTATUS_NOT_ENOUGH_MEMORY;
goto clean_and_return;
}
cb_data.pContext = &sNdefInfo;
@@ -976,16 +979,18 @@ static bool com_android_nfc_NativeNfcTag_doCheckNdef(JNIEnv *e, jobject o, jintA
if(sem_wait(&cb_data.sem))
{
LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
+ status = NFCSTATUS_ABORTED;
goto clean_and_return;
}
- if (cb_data.status != NFCSTATUS_SUCCESS)
+ status = cb_data.status;
+ TRACE("phLibNfc_Ndef_CheckNdef() - Status code = %d", status);
+
+ if (status != NFCSTATUS_SUCCESS)
{
goto clean_and_return;
}
- result = JNI_TRUE;
-
ndef[0] = sNdefInfo.MaxNdefMsgLength;
// Translate the card state to know values for the NFC API
switch (sNdefInfo.NdefCardState) {
@@ -1008,7 +1013,7 @@ clean_and_return:
e->ReleaseIntArrayElements(ndefinfo, ndef, 0);
nfc_cb_data_deinit(&cb_data);
CONCURRENCY_UNLOCK();
- return result;
+ return status;
}
static jboolean com_android_nfc_NativeNfcTag_doPresenceCheck(JNIEnv *e, jobject o)
@@ -1221,19 +1226,19 @@ clean_and_return:
*/
static JNINativeMethod gMethods[] =
{
- {"doConnect", "(I)Z",
+ {"doConnect", "(I)I",
(void *)com_android_nfc_NativeNfcTag_doConnect},
{"doDisconnect", "()Z",
(void *)com_android_nfc_NativeNfcTag_doDisconnect},
- {"doReconnect", "()Z",
+ {"doReconnect", "()I",
(void *)com_android_nfc_NativeNfcTag_doReconnect},
- {"doHandleReconnect", "(I)Z",
+ {"doHandleReconnect", "(I)I",
(void *)com_android_nfc_NativeNfcTag_doHandleReconnect},
{"doTransceive", "([BZ[I)[B",
(void *)com_android_nfc_NativeNfcTag_doTransceive},
{"doGetNdefType", "(II)I",
(void *)com_android_nfc_NativeNfcTag_doGetNdefType},
- {"doCheckNdef", "([I)Z",
+ {"doCheckNdef", "([I)I",
(void *)com_android_nfc_NativeNfcTag_doCheckNdef},
{"doRead", "()[B",
(void *)com_android_nfc_NativeNfcTag_doRead},
diff --git a/src/com/android/nfc/NativeNfcTag.java b/src/com/android/nfc/NativeNfcTag.java
index 94df1d2..1937744 100755
--- a/src/com/android/nfc/NativeNfcTag.java
+++ b/src/com/android/nfc/NativeNfcTag.java
@@ -43,6 +43,8 @@ public class NativeNfcTag {
private int mConnectedTechnology; // Index in mTechList
+ private int mLastStatusCode;
+
private final String TAG = "NativeNfcTag";
private boolean mIsPresent; // Whether the tag is known to be still present
@@ -115,12 +117,12 @@ public class NativeNfcTag {
}
}
- private native boolean doConnect(int handle);
- public synchronized boolean connect(int technology) {
+ private native int doConnect(int handle);
+ public synchronized int connect(int technology) {
if (mWatchdog != null) {
mWatchdog.pause();
}
- boolean isSuccess = false;
+ int status = -1;
for (int i = 0; i < mTechList.length; i++) {
if (mTechList[i] == technology) {
// Get the handle and connect, if not already connected
@@ -139,12 +141,12 @@ public class NativeNfcTag {
// allowed.
if (mConnectedTechnology == -1) {
// Not connected yet
- isSuccess = doConnect(mTechHandles[i]);
+ status = doConnect(mTechHandles[i]);
}
else if ((mConnectedTechnology != -1) &&
(mTechHandles[mConnectedTechnology] != mTechHandles[i])) {
// Connect to a tech with a different handle
- isSuccess = reconnect(mTechHandles[i]);
+ status = reconnect(mTechHandles[i]);
}
else {
// Already connected to a tech with the same handle
@@ -152,24 +154,23 @@ public class NativeNfcTag {
// success
if ((technology == TagTechnology.NDEF) ||
(technology == TagTechnology.NDEF_FORMATABLE)) {
- isSuccess = true;
+ status = 0;
} else {
if ((technology != TagTechnology.ISO_DEP) &&
(hasTechOnHandle(TagTechnology.ISO_DEP, mTechHandles[i]))) {
// Don't allow to connect a -4 tag at a different level
// than IsoDep, as this is not supported by
// libNFC.
- isSuccess = false;
} else {
- isSuccess = true;
+ status = 0;
}
}
}
- if (isSuccess) {
+ if (status == 0) {
mConnectedTechnology = i;
}
} else {
- isSuccess = true; // Already connect to this tech
+ status = 0; // Already connect to this tech
}
break;
}
@@ -177,7 +178,8 @@ public class NativeNfcTag {
if (mWatchdog != null) {
mWatchdog.doResume();
}
- return isSuccess;
+ mLastStatusCode = status;
+ return status;
}
public synchronized void startPresenceChecking() {
@@ -219,28 +221,28 @@ public class NativeNfcTag {
return result;
}
- native boolean doReconnect();
- public synchronized boolean reconnect() {
+ native int doReconnect();
+ public synchronized int reconnect() {
if (mWatchdog != null) {
mWatchdog.pause();
}
- boolean result = doReconnect();
+ int status = doReconnect();
if (mWatchdog != null) {
mWatchdog.doResume();
}
- return result;
+ return status;
}
- native boolean doHandleReconnect(int handle);
- public synchronized boolean reconnect(int handle) {
+ native int doHandleReconnect(int handle);
+ public synchronized int reconnect(int handle) {
if (mWatchdog != null) {
mWatchdog.pause();
}
- boolean result = doHandleReconnect(handle);
+ int status = doHandleReconnect(handle);
if (mWatchdog != null) {
mWatchdog.doResume();
}
- return result;
+ return status;
}
private native byte[] doTransceive(byte[] data, boolean raw, int[] returnCode);
@@ -255,16 +257,17 @@ public class NativeNfcTag {
return result;
}
- private native boolean doCheckNdef(int[] ndefinfo);
- public synchronized boolean checkNdef(int[] ndefinfo) {
+ private native int doCheckNdef(int[] ndefinfo);
+ public synchronized int checkNdef(int[] ndefinfo) {
if (mWatchdog != null) {
mWatchdog.pause();
}
- boolean result = doCheckNdef(ndefinfo);
+ int status = doCheckNdef(ndefinfo);
if (mWatchdog != null) {
mWatchdog.doResume();
}
- return result;
+ mLastStatusCode = status;
+ return status;
}
private native byte[] doRead();
@@ -348,6 +351,10 @@ public class NativeNfcTag {
private NativeNfcTag() {
}
+ public int getLastStatusCode() {
+ return mLastStatusCode;
+ }
+
public int getHandle() {
// This is just a handle for the clients; it can simply use the first
// technology handle we have.
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index 17615fb..acbfc5e 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -225,6 +225,8 @@ public class NfcService extends Application {
static final int MSG_SE_EMV_CARD_REMOVAL = 11;
static final int MSG_SE_MIFARE_ACCESS = 12;
+ static final int STATUS_CODE_TARGET_LOST = 146;
+
// Copied from com.android.nfc_extras to avoid library dependency
// Must keep in sync with com.android.nfc_extras
static final int ROUTE_OFF = 1;
@@ -1305,7 +1307,7 @@ public class NfcService extends Application {
// Note that on most tags, all technologies are behind a single
// handle. This means that the connect at the lower levels
// will do nothing, as the tag is already connected to that handle.
- if (tag.connect(technology)) {
+ if (tag.connect(technology) == 0) {
return ErrorCodes.SUCCESS;
} else {
return ErrorCodes.ERROR_DISCONNECT;
@@ -1326,7 +1328,7 @@ public class NfcService extends Application {
/* find the tag in the hmap */
tag = (NativeNfcTag) findObject(nativeHandle);
if (tag != null) {
- if (tag.reconnect()) {
+ if (tag.reconnect() == 0) {
return ErrorCodes.SUCCESS;
} else {
return ErrorCodes.ERROR_DISCONNECT;
@@ -1392,20 +1394,19 @@ public class NfcService extends Application {
@Override
public boolean isNdef(int nativeHandle) throws RemoteException {
NativeNfcTag tag = null;
- boolean isSuccess = false;
// Check if NFC is enabled
if (!mIsNfcEnabled) {
- return isSuccess;
+ return false;
}
/* find the tag in the hmap */
tag = (NativeNfcTag) findObject(nativeHandle);
int[] ndefInfo = new int[2];
- if (tag != null) {
- isSuccess = tag.checkNdef(ndefInfo);
+ if (tag == null) {
+ return false;
}
- return isSuccess;
+ return tag.checkNdef(ndefInfo) == 0;
}
@Override
@@ -2360,15 +2361,19 @@ public class NfcService extends Application {
int techIndex = 0;
int lastHandleScanned = 0;
boolean ndefFoundAndConnected = false;
+ boolean isTargetLost = false;
NdefMessage[] ndefMsgs = null;
boolean foundFormattable = false;
int formattableHandle = 0;
int formattableTechnology = 0;
+ int status;
- while ((!ndefFoundAndConnected) && (techIndex < technologies.length)) {
+ while ((!ndefFoundAndConnected) && (techIndex < technologies.length) && (!isTargetLost))
+ {
if (handles[techIndex] != lastHandleScanned) {
// We haven't seen this handle yet, connect and checkndef
- if (nativeTag.connect(technologies[techIndex])) {
+ status = nativeTag.connect(technologies[techIndex]);
+ if (status == 0) {
// Check if this type is NDEF formatable
if (!foundFormattable) {
if (nativeTag.isNdefFormatable()) {
@@ -2383,7 +2388,8 @@ public class NfcService extends Application {
} // else, already found formattable technology
int[] ndefinfo = new int[2];
- if (nativeTag.checkNdef(ndefinfo)) {
+ status = nativeTag.checkNdef(ndefinfo);
+ if (status == 0) {
ndefFoundAndConnected = true;
boolean generateEmptyNdef = false;
@@ -2417,10 +2423,17 @@ public class NfcService extends Application {
supportedNdefLength, cardState);
nativeTag.reconnect();
}
- } // else, no NDEF on this tech, continue loop
+ } else { // else, no NDEF on this tech, continue loop
+ Log.d(TAG, "Check NDEF Failed - status = "+ status);
+ if (status == STATUS_CODE_TARGET_LOST) {
+ isTargetLost = true;
+ }
+ }
} else {
- // Connect failed, tag maybe lost. Try next handle
- // anyway.
+ Log.d(TAG, "Connect Failed - status = "+ status);
+ if (status == STATUS_CODE_TARGET_LOST) {
+ isTargetLost = true;
+ }
}
}
lastHandleScanned = handles[techIndex];
@@ -2461,13 +2474,14 @@ public class NfcService extends Application {
dispatchNativeTag(nativeTag, ndefMsgs);
} else {
// No ndef found or connect failed, just try to reconnect and dispatch
- if (nativeTag.reconnect()) {
- nativeTag.startPresenceChecking();
- dispatchNativeTag(nativeTag, null);
- } else {
- Log.w(TAG, "Failed to connect to tag");
- nativeTag.disconnect();
- }
+ if (nativeTag.getLastStatusCode() != STATUS_CODE_TARGET_LOST) {
+ if (nativeTag.reconnect() == 0) {
+ nativeTag.startPresenceChecking();
+ dispatchNativeTag(nativeTag, null);
+ }
+ } else {
+ nativeTag.disconnect();
+ }
}
break;