diff options
-rw-r--r-- | jni/com_android_nfc.cpp | 96 | ||||
-rw-r--r-- | jni/com_android_nfc.h | 3 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeNfcManager.cpp | 9 | ||||
-rwxr-xr-x | jni/com_android_nfc_NativeNfcSecureElement.cpp | 41 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeNfcTag.cpp | 77 |
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); |