summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jni/com_android_nfc.cpp96
-rw-r--r--jni/com_android_nfc.h3
-rw-r--r--jni/com_android_nfc_NativeNfcManager.cpp9
-rwxr-xr-xjni/com_android_nfc_NativeNfcSecureElement.cpp41
-rw-r--r--jni/com_android_nfc_NativeNfcTag.cpp77
5 files changed, 153 insertions, 73 deletions
diff --git a/jni/com_android_nfc.cpp b/jni/com_android_nfc.cpp
index c66249b..560a7f2 100644
--- a/jni/com_android_nfc.cpp
+++ b/jni/com_android_nfc.cpp
@@ -254,19 +254,19 @@ phLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o)
return e->GetIntField(o, f);
}
-jstring nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o)
+jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o)
{
jclass c;
jfieldID f;
- jstring type;
+ jintArray techtypes;
c = e->GetObjectClass(o);
- f = e->GetFieldID(c, "mType","Ljava/lang/String;");
+ f = e->GetFieldID(c, "mTechList","[I");
- /* Read the instance field */
- type = (jstring)e->GetObjectField(o, f);
-
- return type;
+ /* Read the techtypes */
+ techtypes = (jintArray) e->GetObjectField(o, f);
+
+ return techtypes;
}
@@ -340,35 +340,57 @@ const char* nfc_jni_get_status_name(NFCSTATUS status)
/*
* Utility to get target type name from its specs
*/
-int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak)
+jintArray nfc_jni_get_technology_tree(JNIEnv* e, phNfc_eRemDevType_t type, uint8_t sak)
{
+ jintArray techList = NULL;
+ jint* techItems;
switch (type)
{
case phNfc_eISO14443_A_PICC:
case phNfc_eISO14443_4A_PICC:
+ {
+ techList = e->NewIntArray(2);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_ISO14443_4;
+ techItems[1] = TARGET_TYPE_ISO14443_3A;
+ e->ReleaseIntArrayElements(techList, techItems,0);
+ break;
+ }
case phNfc_eISO14443_4B_PICC:
{
- return TARGET_TYPE_ISO14443_4;
+ techList = e->NewIntArray(2);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_ISO14443_4;
+ techItems[1] = TARGET_TYPE_ISO14443_3B;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}break;
case phNfc_eISO14443_3A_PICC:
{
- return TARGET_TYPE_ISO14443_3A;
+ techList = e->NewIntArray(1);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_ISO14443_3A;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}break;
case phNfc_eISO14443_B_PICC:
{
- /* Actually this can be -3B or -4B
- * FRI doesn't allow us to tell the diff yet
- * and the API doesn't know type 4B
- * so return 3B for now.
- */
- return TARGET_TYPE_ISO14443_3B;
+ // 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
+ techList = e->NewIntArray(2);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_ISO14443_4;
+ techItems[1] = TARGET_TYPE_ISO14443_3B;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}break;
case phNfc_eISO15693_PICC:
{
- return TARGET_TYPE_ISO15693;
+ techList = e->NewIntArray(1);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_ISO15693;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}break;
case phNfc_eMifare_PICC:
@@ -377,7 +399,12 @@ int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak)
{
case 0x00:
// could be UL or UL-C
- return TARGET_TYPE_MIFARE_UL;
+ techList = e->NewIntArray(2);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_MIFARE_UL;
+ techItems[1] = TARGET_TYPE_ISO14443_3A;
+ e->ReleaseIntArrayElements(techList, techItems,0);
+ break;
case 0x08:
case 0x09:
case 0x10:
@@ -388,30 +415,49 @@ int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak)
case 0x88:
case 0x98:
case 0xB8:
- return TARGET_TYPE_MIFARE_CLASSIC;
+ techList = e->NewIntArray(2);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_MIFARE_CLASSIC;
+ techItems[1] = TARGET_TYPE_ISO14443_3A;
+ e->ReleaseIntArrayElements(techList, techItems,0);
+ break;
case 0x20:
- return TARGET_TYPE_MIFARE_DESFIRE;
+ // This could be DESfire, but libnfc returns that as ISO14443_4
+ // so we shouldn't hit this case
default:
{
- return TARGET_TYPE_UNKNOWN;
+ techList = e->NewIntArray(1);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_UNKNOWN;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}break;
}
}break;
case phNfc_eFelica_PICC:
{
- return TARGET_TYPE_FELICA;
+ techList = e->NewIntArray(1);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_FELICA;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}break;
case phNfc_eJewel_PICC:
{
- return TARGET_TYPE_JEWEL;
+ techList = e->NewIntArray(2);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_JEWEL;
+ techItems[1] = TARGET_TYPE_ISO14443_3A;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}break;
default:
{
- return TARGET_TYPE_UNKNOWN;
+ techList = e->NewIntArray(1);
+ techItems = e->GetIntArrayElements(techList, NULL);
+ techItems[0] = TARGET_TYPE_UNKNOWN;
+ e->ReleaseIntArrayElements(techList, techItems,0);
}
}
- return TARGET_TYPE_UNKNOWN;
+ return techList;
}
} // namespace android
diff --git a/jni/com_android_nfc.h b/jni/com_android_nfc.h
index f3367a0..6d011d8 100644
--- a/jni/com_android_nfc.h
+++ b/jni/com_android_nfc.h
@@ -177,6 +177,7 @@ nfc_jni_native_monitor_t* nfc_jni_init_monitor(void);
nfc_jni_native_monitor_t* nfc_jni_get_monitor(void);
int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak);
+jintArray nfc_jni_get_technology_tree(JNIEnv *e, phNfc_eRemDevType_t type, uint8_t sak);
/* P2P */
phLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o);
@@ -184,7 +185,7 @@ jshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o);
/* TAG */
phLibNfc_Handle nfc_jni_get_nfc_tag_handle(JNIEnv *e, jobject o);
-jstring nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o);
+jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o);
/* LLCP */
phLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o);
diff --git a/jni/com_android_nfc_NativeNfcManager.cpp b/jni/com_android_nfc_NativeNfcManager.cpp
index c36e9cb..73e6ca4 100644
--- a/jni/com_android_nfc_NativeNfcManager.cpp
+++ b/jni/com_android_nfc_NativeNfcManager.cpp
@@ -922,15 +922,8 @@ static void nfc_jni_Discovery_notification_callback(void *pContext,
/* Generate technology list */
jintArray techList;
- int tech = get_technology_type(psRemoteDevList[target_index].psRemoteDevInfo->RemDevType,
+ techList = nfc_jni_get_technology_tree(e, psRemoteDevList[target_index].psRemoteDevInfo->RemDevType,
psRemoteDevList[target_index].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak);
- if (tech != TARGET_TYPE_UNKNOWN) {
- LOGD("Tag tech: %d", tech);
- techList = e->NewIntArray(1);
- e->SetIntArrayRegion(techList, 0, 1, &tech);
- } else {
- techList = e->NewIntArray(0);
- }
/* Push the technology list into the java object */
f = e->GetFieldID(tag_cls, "mTechList", "[I");
diff --git a/jni/com_android_nfc_NativeNfcSecureElement.cpp b/jni/com_android_nfc_NativeNfcSecureElement.cpp
index ca000c2..345c402 100755
--- a/jni/com_android_nfc_NativeNfcSecureElement.cpp
+++ b/jni/com_android_nfc_NativeNfcSecureElement.cpp
@@ -106,7 +106,7 @@ static void com_android_nfc_jni_open_secure_element_notification_callback(void *
uint8_t uNofRemoteDev,
NFCSTATUS status)
{
- JNIEnv *e;
+ JNIEnv *e = (JNIEnv *)pContext;
NFCSTATUS ret;
int i;
@@ -127,13 +127,22 @@ static void com_android_nfc_jni_open_secure_element_notification_callback(void *
secureElementHandle = psRemoteDevList[1].hTargetDev;
/* Set type name */
- SecureElementTech = get_technology_type(psRemoteDevList[1].psRemoteDevInfo->RemDevType,
+ jintArray techTree = nfc_jni_get_technology_tree(e, psRemoteDevList[1].psRemoteDevInfo->RemDevType,
psRemoteDevList[1].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak);
+ // TODO: Should use the "connected" technology, for now use the first
+ if (e->GetArrayLength(techTree) > 0) {
+ jint* technologies = e->GetIntArrayElements(techTree, 0);
+ SecureElementTech = technologies[0];
+ LOGD("Store Secure Element Info\n");
+ SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
+
+ LOGD("Discovered secure element: tech=%d", SecureElementTech);
+ }
+ else {
+ LOGE("Discovered secure element, but could not resolve tech");
+ status = NFCSTATUS_FAILED;
+ }
- LOGD("Store Secure Element Info\n");
- SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
-
- LOGD("Discovered secure element: tech=%d", SecureElementTech);
}
else
{
@@ -141,13 +150,21 @@ static void com_android_nfc_jni_open_secure_element_notification_callback(void *
secureElementHandle = psRemoteDevList->hTargetDev;
/* Set type name */
- SecureElementTech = get_technology_type(psRemoteDevList->psRemoteDevInfo->RemDevType,
+ jintArray techTree = nfc_jni_get_technology_tree(e, psRemoteDevList->psRemoteDevInfo->RemDevType,
psRemoteDevList->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak);
-
- LOGD("Store Secure Element Info\n");
- SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
-
- LOGD("Discovered secure element: tech=%d", SecureElementTech);
+ // TODO: Should use the "connected" technology, for now use the first
+ if ((techTree != NULL) && e->GetArrayLength(techTree) > 0) {
+ jint* technologies = e->GetIntArrayElements(techTree, 0);
+ SecureElementTech = technologies[0];
+ LOGD("Store Secure Element Info\n");
+ SecureElementInfo = psRemoteDevList->psRemoteDevInfo;
+
+ LOGD("Discovered secure element: tech=%d", SecureElementTech);
+ }
+ else {
+ LOGE("Discovered secure element, but could not resolve tech");
+ status = NFCSTATUS_FAILED;
+ }
}
}
diff --git a/jni/com_android_nfc_NativeNfcTag.cpp b/jni/com_android_nfc_NativeNfcTag.cpp
index f4a54df..91242de 100644
--- a/jni/com_android_nfc_NativeNfcTag.cpp
+++ b/jni/com_android_nfc_NativeNfcTag.cpp
@@ -456,11 +456,12 @@ static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
phLibNfc_sTransceiveInfo_t transceive_info;
jbyteArray result = NULL;
int res;
- jstring type = nfc_jni_get_nfc_tag_type(e, o);
- const char* str = e->GetStringUTFChars(type, 0);
+ jintArray techtypes = nfc_jni_get_nfc_tag_type(e, o);
phLibNfc_Handle handle = nfc_jni_get_nfc_tag_handle(e, o);
NFCSTATUS status;
struct nfc_jni_callback_data cb_data;
+ int selectedTech = 0;
+ jint* technologies = NULL;
CONCURRENCY_LOCK();
@@ -470,36 +471,55 @@ static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
goto clean_and_return;
}
- TRACE("Tag %s\n", str);
+
+
+ if ((techtypes == NULL) || (e->GetArrayLength(techtypes) == 0)) {
+ goto clean_and_return;
+ }
+ // TODO: code to determine the selected technology
+ // For now, take the first
+ technologies = e->GetIntArrayElements(techtypes, 0);
+ selectedTech = technologies[0];
+
+ TRACE("Transceive thinks selected tag technology = %d\n", selectedTech);
buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
buflen = (uint32_t)e->GetArrayLength(data);
- /* Prepare transceive info structure */
- if((res = strcmp(str, "Mifare1K") == 0) || (res = strcmp(str, "Mifare4K") == 0) || (res = strcmp(str, "MifareUL") == 0))
- {
- offset = 2;
- transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
- transceive_info.addr = (uint8_t)buf[1];
- }
- else if((res = strcmp(str, "Felica") == 0))
- {
- transceive_info.cmd.FelCmd = phNfc_eFelica_Raw;
- transceive_info.addr = 0;
- }
- else if((res = strcmp(str, "Iso14443") == 0))
- {
- transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
- transceive_info.addr = 0;
+ switch (selectedTech) {
+ 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;
+ break;
+ case TARGET_TYPE_MIFARE_CLASSIC:
+ case TARGET_TYPE_MIFARE_UL:
+ case TARGET_TYPE_MIFARE_DESFIRE:
+ offset = 2;
+ transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
+ transceive_info.addr = (uint8_t)buf[1];
+ break;
+ case TARGET_TYPE_ISO14443_3A:
+ // TODO: just try MF command set??
+ break;
+ case TARGET_TYPE_ISO14443_3B:
+ // TODO: ???
+ break;
+ case TARGET_TYPE_ISO14443_4:
+ transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
+ transceive_info.addr = 0;
+ break;
+ case TARGET_TYPE_ISO15693:
+ transceive_info.cmd.Iso15693Cmd = phNfc_eIso15693_Cmd;
+ transceive_info.addr = 0;
+ break;
+ case TARGET_TYPE_UNKNOWN:
+ default:
+ break;
}
- else if((res = strcmp(str, "Jewel") == 0))
- {
- transceive_info.cmd.JewelCmd = phNfc_eJewel_Raw;
- transceive_info.addr = 0;
- }
-
- /* Free memory */
- e->ReleaseStringUTFChars(type, str);
transceive_info.sSendData.buffer = buf + offset;
transceive_info.sSendData.length = buflen - offset;
@@ -549,6 +569,9 @@ clean_and_return:
{
free(transceive_info.sRecvData.buffer);
}
+ if (technologies != NULL) {
+ e->ReleaseIntArrayElements(techtypes, technologies, JNI_ABORT);
+ }
e->ReleaseByteArrayElements(data,
(jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);