summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jni/com_android_nfc.cpp114
-rw-r--r--jni/com_android_nfc.h4
-rw-r--r--jni/com_android_nfc_NativeNfcManager.cpp6
-rwxr-xr-xjni/com_android_nfc_NativeNfcSecureElement.cpp8
-rw-r--r--jni/com_android_nfc_NativeNfcTag.cpp29
-rwxr-xr-xsrc/com/android/nfc/NativeNfcTag.java33
-rwxr-xr-xsrc/com/android/nfc/NfcService.java2
7 files changed, 126 insertions, 70 deletions
diff --git a/jni/com_android_nfc.cpp b/jni/com_android_nfc.cpp
index 2bf9685..a46168c 100644
--- a/jni/com_android_nfc.cpp
+++ b/jni/com_android_nfc.cpp
@@ -267,6 +267,29 @@ jint nfc_jni_get_connected_technology(JNIEnv *e, jobject o)
}
+jint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o)
+{
+ jclass c;
+ jfieldID f;
+ jint connectedLibNfcType = -1;
+
+ int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o);
+ c = e->GetObjectClass(o);
+ f = e->GetFieldID(c, "mTechLibNfcTypes", "[I");
+ jintArray libNfcTypes = (jintArray) e->GetObjectField(o, f);
+
+ if ((connectedTechIndex != -1) && (libNfcTypes != NULL) &&
+ (connectedTechIndex < e->GetArrayLength(libNfcTypes))) {
+ jint* types = e->GetIntArrayElements(libNfcTypes, 0);
+ if (types != NULL) {
+ connectedLibNfcType = types[connectedTechIndex];
+ e->ReleaseIntArrayElements(libNfcTypes, types, JNI_ABORT);
+ }
+ }
+ return connectedLibNfcType;
+
+}
+
phLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o)
{
jclass c;
@@ -384,8 +407,8 @@ const char* nfc_jni_get_status_name(NFCSTATUS status)
return "UNKNOWN";
}
-int addTechIfNeeded(int *techList, int* handleList, int listSize, int maxListSize,
- int techToAdd, int handleToAdd) {
+int addTechIfNeeded(int *techList, int* handleList, int* typeList, int listSize,
+ int maxListSize, int techToAdd, int handleToAdd, int typeToAdd) {
bool found = false;
for (int i = 0; i < listSize; i++) {
if (techList[i] == techToAdd) {
@@ -396,6 +419,7 @@ int addTechIfNeeded(int *techList, int* handleList, int listSize, int maxListSiz
if (!found && listSize < maxListSize) {
techList[listSize] = techToAdd;
handleList[listSize] = handleToAdd;
+ typeList[listSize] = typeToAdd;
return listSize + 1;
}
else {
@@ -410,10 +434,13 @@ int addTechIfNeeded(int *techList, int* handleList, int listSize, int maxListSiz
* Utility to get a technology tree and a corresponding handle list from a detected tag.
*/
void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList,
- uint8_t count, jintArray* techList, jintArray* handleList)
+ uint8_t count, jintArray* techList, jintArray* handleList,
+ jintArray* libnfcTypeList)
{
int technologies[MAX_NUM_TECHNOLOGIES];
int handles[MAX_NUM_TECHNOLOGIES];
+ int libnfctypes[MAX_NUM_TECHNOLOGIES];
+
int index = 0;
// TODO: This counts from up to down because on multi-protocols, the
// ISO handle is usually the second, and we prefer the ISO. Should implement
@@ -427,41 +454,40 @@ void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList,
case phNfc_eISO14443_A_PICC:
case phNfc_eISO14443_4A_PICC:
{
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_4, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_3A, handle);
-
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_NDEF_FORMATABLE, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes, index,
+ MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes, index,
+ MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_NDEF_FORMATABLE, handle, type);
break;
}
case phNfc_eISO14443_4B_PICC:
{
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_4, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_3B, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes, index,
+ MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes, index,
+ MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type);
}break;
case phNfc_eISO14443_3A_PICC:
{
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_3A, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
}break;
case phNfc_eISO14443_B_PICC:
{
// TODO a bug in libnfc will cause 14443-3B only cards
// to be returned as this type as well, but these cards
// are very rare. Hence assume it's -4B
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_4, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_3B, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type);
}break;
case phNfc_eISO15693_PICC:
{
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO15693, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO15693, handle, type);
}break;
case phNfc_eMifare_PICC:
{
@@ -474,55 +500,57 @@ void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList,
{
case 0x00:
// could be UL or UL-C
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_MIFARE_UL, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_3A, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_NDEF_FORMATABLE, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_UL, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_NDEF_FORMATABLE, handle, type);
break;
default:
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_MIFARE_CLASSIC, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_3A, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_NDEF_FORMATABLE, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_CLASSIC, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_NDEF_FORMATABLE, handle, type);
break;
}
}break;
case phNfc_eFelica_PICC:
{
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_FELICA, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_FELICA, handle, type);
}break;
case phNfc_eJewel_PICC:
{
-// TODO expose Jewel in the Java APIs
-// index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
-// TARGET_TYPE_JEWEL, handle);
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_ISO14443_3A, handle);
+ // Jewel represented as NfcA
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
}break;
default:
{
- index = addTechIfNeeded(technologies, handles, index, MAX_NUM_TECHNOLOGIES,
- TARGET_TYPE_UNKNOWN, handle);
+ index = addTechIfNeeded(technologies, handles, libnfctypes,
+ index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_UNKNOWN, handle, type);
}
}
}
// Build the Java arrays
*techList = e->NewIntArray(index);
*handleList = e->NewIntArray(index);
+ *libnfcTypeList = e->NewIntArray(index);
jint* techItems = e->GetIntArrayElements(*techList, NULL);
jint* handleItems = e->GetIntArrayElements(*handleList, NULL);
+ jint* typeItems = e->GetIntArrayElements(*libnfcTypeList, NULL);
for (int i = 0; i < index; i++) {
techItems[i] = technologies[i];
handleItems[i] = handles[i];
+ typeItems[i] = libnfctypes[i];
}
e->ReleaseIntArrayElements(*techList, techItems, 0);
e->ReleaseIntArrayElements(*handleList, handleItems, 0);
+ e->ReleaseIntArrayElements(*libnfcTypeList, typeItems, 0);
}
diff --git a/jni/com_android_nfc.h b/jni/com_android_nfc.h
index 8e67d04..035e7d0 100644
--- a/jni/com_android_nfc.h
+++ b/jni/com_android_nfc.h
@@ -187,7 +187,8 @@ nfc_jni_native_monitor_t* nfc_jni_get_monitor(void);
int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak);
void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList,
- uint8_t count, jintArray* techList, jintArray* handleList);
+ uint8_t count, jintArray* techList, jintArray* handleList,
+ jintArray* typeList);
/* P2P */
phLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o);
@@ -195,6 +196,7 @@ jshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o);
/* TAG */
jint nfc_jni_get_connected_technology(JNIEnv *e, jobject o);
+jint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o);
phLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o);
jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o);
diff --git a/jni/com_android_nfc_NativeNfcManager.cpp b/jni/com_android_nfc_NativeNfcManager.cpp
index 5789811..fb943a1 100644
--- a/jni/com_android_nfc_NativeNfcManager.cpp
+++ b/jni/com_android_nfc_NativeNfcManager.cpp
@@ -953,9 +953,10 @@ static void nfc_jni_Discovery_notification_callback(void *pContext,
/* Generate technology list */
jintArray techList;
jintArray handleList;
+ jintArray typeList;
nfc_jni_get_technology_tree(e, psRemoteDevList,
multi_protocol ? uNofRemoteDev : 1,
- &techList, &handleList);
+ &techList, &handleList, &typeList);
/* Push the technology list into the java object */
f = e->GetFieldID(tag_cls, "mTechList", "[I");
@@ -964,6 +965,9 @@ static void nfc_jni_Discovery_notification_callback(void *pContext,
f = e->GetFieldID(tag_cls, "mTechHandles", "[I");
e->SetObjectField(tag, f, handleList);
+ f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I");
+ e->SetObjectField(tag, f, typeList);
+
f = e->GetFieldID(tag_cls, "mConnectedTechnology", "I");
e->SetIntField(tag, f,(jint)-1);
}
diff --git a/jni/com_android_nfc_NativeNfcSecureElement.cpp b/jni/com_android_nfc_NativeNfcSecureElement.cpp
index cd5e181..aec9d2d 100755
--- a/jni/com_android_nfc_NativeNfcSecureElement.cpp
+++ b/jni/com_android_nfc_NativeNfcSecureElement.cpp
@@ -129,7 +129,9 @@ static void com_android_nfc_jni_open_secure_element_notification_callback(void *
/* Set type name */
jintArray techList;
jintArray handleList;
- nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList, &handleList);
+ jintArray typeList;
+ nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList,
+ &handleList, &typeList);
// TODO: Should use the "connected" technology, for now use the first
if (e->GetArrayLength(techList) > 0) {
jint* technologies = e->GetIntArrayElements(techList, 0);
@@ -153,7 +155,9 @@ static void com_android_nfc_jni_open_secure_element_notification_callback(void *
/* Set type name */
jintArray techList;
jintArray handleList;
- nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList, &handleList);
+ jintArray typeList;
+ nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList,
+ &handleList, &typeList);
// TODO: Should use the "connected" technology, for now use the first
if ((techList != NULL) && e->GetArrayLength(techList) > 0) {
diff --git a/jni/com_android_nfc_NativeNfcTag.cpp b/jni/com_android_nfc_NativeNfcTag.cpp
index 79737b9..8eb3354 100644
--- a/jni/com_android_nfc_NativeNfcTag.cpp
+++ b/jni/com_android_nfc_NativeNfcTag.cpp
@@ -517,11 +517,11 @@ static jboolean com_android_nfc_NativeNfcTag_doReconnect(JNIEnv *e,
{
// Reconnect is provided by libnfc by just calling connect again
// on the same handle.
- // Note that some tag types are stateless, hence we do not reconnect
- // those. Currently those are the Jewel and Iso15693 technologies.
- int selectedTech = nfc_jni_get_connected_technology(e, o);
- if (selectedTech != -1) {
- if (selectedTech != TARGET_TYPE_ISO15693) {
+ int libNfcType = nfc_jni_get_connected_technology_libnfc_type(e, o);
+ if (libNfcType != -1) {
+ // Note that some tag types are stateless, hence we do not reconnect
+ // those. Currently those are the Jewel and Iso15693 technologies.
+ if ((libNfcType != phNfc_eJewel_PICC) && (libNfcType != phNfc_eISO15693_PICC)) {
phLibNfc_Handle handle = nfc_jni_get_connected_handle(e,o);
return com_android_nfc_NativeNfcTag_doConnect(e, o, handle);
}
@@ -697,6 +697,7 @@ static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
NFCSTATUS status;
struct nfc_jni_callback_data cb_data;
int selectedTech = 0;
+ int selectedLibNfcType = 0;
jint* technologies = NULL;
bool checkResponseCrc = false;
@@ -710,17 +711,12 @@ static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
}
selectedTech = nfc_jni_get_connected_technology(e, o);
+ selectedLibNfcType = nfc_jni_get_connected_technology_libnfc_type(e, o);
buf = outbuf = (uint8_t *)e->GetByteArrayElements(data, NULL);
buflen = outlen = (uint32_t)e->GetArrayLength(data);
switch (selectedTech) {
-/* TODO figure out how to pipe Jewel commands through from Java
- case TARGET_TYPE_JEWEL:
- transceive_info.cmd.JewelCmd = phNfc_eJewel_Raw;
- transceive_info.addr = 0;
- break;
-*/
case TARGET_TYPE_FELICA:
transceive_info.cmd.FelCmd = phNfc_eFelica_Raw;
transceive_info.addr = 0;
@@ -744,7 +740,12 @@ static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
}
break;
case TARGET_TYPE_ISO14443_3A:
- if (raw) {
+ // Check which libnfc type
+ if (selectedLibNfcType == phNfc_eJewel_PICC) {
+ // For the Jewel pipe, CRC is automatically computed
+ transceive_info.cmd.JewelCmd = phNfc_eJewel_Raw;
+ transceive_info.addr = 0;
+ } else {
transceive_info.cmd.MfCmd = phHal_eMifareRaw;
transceive_info.addr = 0;
// Need to add in the crc here
@@ -754,10 +755,6 @@ static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
nfc_insert_crc_a(outbuf, buflen);
checkResponseCrc = true;
- } else {
- offset = 2;
- transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
- transceive_info.addr = (uint8_t)buf[1];
}
break;
case TARGET_TYPE_ISO14443_4:
diff --git a/src/com/android/nfc/NativeNfcTag.java b/src/com/android/nfc/NativeNfcTag.java
index 5995ea8..c9a2ee7 100755
--- a/src/com/android/nfc/NativeNfcTag.java
+++ b/src/com/android/nfc/NativeNfcTag.java
@@ -34,6 +34,7 @@ public class NativeNfcTag {
private int[] mTechList;
private int[] mTechHandles;
+ private int[] mTechLibNfcTypes;
private Bundle[] mTechExtras;
private byte[][] mTechPollBytes;
private byte[][] mTechActBytes;
@@ -83,12 +84,16 @@ public class NativeNfcTag {
boolean isSuccess = false;
for (int i = 0; i < mTechList.length; i++) {
if (mTechList[i] == technology) {
- // Get the handle and connect
- isSuccess = doConnect(mTechHandles[i]);
- if (isSuccess) {
- mConnectedTechnology = i;
- mWatchdog = new PresenceCheckWatchdog();
- mWatchdog.start();
+ // Get the handle and connect, if not already connected
+ if (mConnectedTechnology != i) {
+ isSuccess = doConnect(mTechHandles[i]);
+ if (isSuccess) {
+ mConnectedTechnology = i;
+ mWatchdog = new PresenceCheckWatchdog();
+ mWatchdog.start();
+ }
+ } else {
+ isSuccess = true; // Already connect to this tech
}
break;
}
@@ -208,12 +213,21 @@ public class NativeNfcTag {
return 0;
}
}
+
+ public int getConnectedLibNfcType() {
+ if (mConnectedTechnology != -1 && mConnectedTechnology < mTechLibNfcTypes.length) {
+ return mTechLibNfcTypes[mConnectedTechnology];
+ } else {
+ return 0;
+ }
+ }
// This method exists to "patch in" the ndef technologies,
// which is done inside Java instead of the native JNI code.
// To not create some nasty dependencies on the order on which things
// are called (most notably getTechExtras()), it needs some additional
// checking.
- public void addNdefTechnology(NdefMessage msg, int handle, int maxLength, int cardState) {
+ public void addNdefTechnology(NdefMessage msg, int handle, int libnfctype,
+ int maxLength, int cardState) {
synchronized (this) {
int[] mNewTechList = new int[mTechList.length + 1];
System.arraycopy(mTechList, 0, mNewTechList, 0, mTechList.length);
@@ -225,6 +239,11 @@ public class NativeNfcTag {
mNewHandleList[mTechHandles.length] = handle;
mTechHandles = mNewHandleList;
+ int[] mNewTypeList = new int[mTechLibNfcTypes.length + 1];
+ System.arraycopy(mTechLibNfcTypes, 0, mNewTypeList, 0, mTechLibNfcTypes.length);
+ mNewTypeList[mTechLibNfcTypes.length] = handle;
+ mTechLibNfcTypes = mNewTypeList;
+
Bundle extras = new Bundle();
extras.putParcelable(Ndef.EXTRA_NDEF_MSG, msg);
extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, maxLength);
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index 66e6f54..3457583 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -2501,6 +2501,7 @@ public class NfcService extends Application {
ndefMsgs[0] = new NdefMessage(buff);
nativeTag.addNdefTechnology(ndefMsgs[0],
nativeTag.getConnectedHandle(),
+ nativeTag.getConnectedLibNfcType(),
supportedNdefLength, cardState);
nativeTag.reconnect();
} catch (FormatException e) {
@@ -2515,6 +2516,7 @@ public class NfcService extends Application {
ndefMsgs = new NdefMessage[] { };
nativeTag.addNdefTechnology(null,
nativeTag.getConnectedHandle(),
+ nativeTag.getConnectedLibNfcType(),
supportedNdefLength, cardState);
nativeTag.reconnect();
}