diff options
-rw-r--r-- | jni/com_android_nfc_NativeNfcManager.cpp | 85 | ||||
-rwxr-xr-x | src/com/android/nfc/NativeNfcManager.java | 12 | ||||
-rwxr-xr-x | src/com/android/nfc/NfcService.java | 55 |
3 files changed, 141 insertions, 11 deletions
diff --git a/jni/com_android_nfc_NativeNfcManager.cpp b/jni/com_android_nfc_NativeNfcManager.cpp index cba4691..b37b8d4 100644 --- a/jni/com_android_nfc_NativeNfcManager.cpp +++ b/jni/com_android_nfc_NativeNfcManager.cpp @@ -46,6 +46,10 @@ static jmethodID cached_NfcManager_notifyTargetDeselected; static jmethodID cached_NfcManager_notifySeFieldActivated; static jmethodID cached_NfcManager_notifySeFieldDeactivated; +static jmethodID cached_NfcManager_notifySeApduReceived; +static jmethodID cached_NfcManager_notifySeMifareAccess; +static jmethodID cached_NfcManager_notifySeEmvCardRemoval; + namespace android { phLibNfc_Handle storedHandle = 0; @@ -210,7 +214,7 @@ static int nfc_jni_download(struct nfc_jni_native_data *nat, uint8_t update) uint8_t OutputBuffer[1]; uint8_t InputBuffer[1]; struct timespec ts; - NFCSTATUS status; + NFCSTATUS status = NFCSTATUS_FAILED; phLibNfc_StackCapabilities_t caps; struct nfc_jni_callback_data cb_data; @@ -1176,9 +1180,11 @@ static void nfc_jni_transaction_callback(void *context, phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status) { JNIEnv *e; - jobject aid_array = NULL; + jobject tmp_array = NULL; + jobject mifare_block = NULL; struct nfc_jni_native_data *nat; phNfc_sData_t *aid; + phNfc_sData_t *mifare_command; struct nfc_jni_callback_data *pCallbackData; int i=0; @@ -1205,18 +1211,18 @@ static void nfc_jni_transaction_callback(void *context, { char aid_str[AID_MAXLEN * 2 + 1]; aid_str[0] = '\0'; - for (i = 0; i < (aid->length) && i < AID_MAXLEN; i++) { + for (i = 0; i < (int) (aid->length) && i < AID_MAXLEN; i++) { snprintf(&aid_str[i*2], 3, "%02x", aid->buffer[i]); } LOGD("> AID: %s", aid_str); - aid_array = e->NewByteArray(aid->length); - if(aid_array == NULL) + tmp_array = e->NewByteArray(aid->length); + if (tmp_array == NULL) { goto error; } - e->SetByteArrayRegion((jbyteArray)aid_array, 0, aid->length, (jbyte *)aid->buffer); + e->SetByteArrayRegion((jbyteArray)tmp_array, 0, aid->length, (jbyte *)aid->buffer); if(e->ExceptionCheck()) { goto error; @@ -1229,7 +1235,7 @@ static void nfc_jni_transaction_callback(void *context, TRACE("Notify Nfc Service"); /* Notify manager that a new event occurred on a SE */ - e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, aid_array); + e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, tmp_array); if(e->ExceptionCheck()) { goto error; @@ -1241,6 +1247,56 @@ static void nfc_jni_transaction_callback(void *context, } }break; + case phLibNfc_eSE_EvtApduReceived: + { + phNfc_sData_t *apdu = &(evt_info->UiccEvtInfo.aid); + TRACE("> SE EVT_APDU_RECEIVED"); + + if (apdu != NULL) { + TRACE(" APDU length=%d", apdu->length); + tmp_array = e->NewByteArray(apdu->length); + if (tmp_array == NULL) { + goto error; + } + e->SetByteArrayRegion((jbyteArray)tmp_array, 0, apdu->length, (jbyte *)apdu->buffer); + if (e->ExceptionCheck()) { + goto error; + } + } else { + TRACE(" APDU EMPTY"); + } + + TRACE("Notify Nfc Service"); + e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeApduReceived, tmp_array); + }break; + + case phLibNfc_eSE_EvtCardRemoval: + { + TRACE("> SE EVT_EMV_CARD_REMOVAL"); + TRACE("Notify Nfc Service"); + e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeEmvCardRemoval); + }break; + + case phLibNfc_eSE_EvtMifareAccess: + { + TRACE("> SE EVT_MIFARE_ACCESS"); + mifare_command = &(evt_info->UiccEvtInfo.aid); + TRACE("> MIFARE Block: %d",mifare_command->buffer[1]); + tmp_array = e->NewByteArray(2); + if (tmp_array == NULL) + { + goto error; + } + + e->SetByteArrayRegion((jbyteArray)tmp_array, 0, 2, (jbyte *)mifare_command->buffer); + if(e->ExceptionCheck()) + { + goto error; + } + TRACE("Notify Nfc Service"); + e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeMifareAccess, mifare_block); + }break; + case phLibNfc_eSE_EvtFieldOn: { TRACE("> SE EVT_FIELD_ON"); @@ -1276,9 +1332,9 @@ static void nfc_jni_transaction_callback(void *context, e->ExceptionClear(); clean_and_return: - if(aid_array != NULL) + if(tmp_array != NULL) { - e->DeleteLocalRef(aid_array); + e->DeleteLocalRef(tmp_array); } } @@ -1631,7 +1687,16 @@ static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject "notifySeFieldActivated", "()V"); cached_NfcManager_notifySeFieldDeactivated = e->GetMethodID(cls, - "notifySeFieldDeactivated", "()V"); + "notifySeFieldDeactivated", "()V"); + + cached_NfcManager_notifySeApduReceived= e->GetMethodID(cls, + "notifySeApduReceived", "([B)V"); + + cached_NfcManager_notifySeMifareAccess = e->GetMethodID(cls, + "notifySeMifareAccess", "([B)V"); + + cached_NfcManager_notifySeEmvCardRemoval = e->GetMethodID(cls, + "notifySeEmvCardRemoval", "()V"); if(nfc_jni_cache_object(e,"com/android/nfc/NativeNfcTag",&(nat->cached_NfcTag)) == -1) { diff --git a/src/com/android/nfc/NativeNfcManager.java b/src/com/android/nfc/NativeNfcManager.java index 3f0f532..10ff1ff 100755 --- a/src/com/android/nfc/NativeNfcManager.java +++ b/src/com/android/nfc/NativeNfcManager.java @@ -146,4 +146,16 @@ public class NativeNfcManager { private void notifySeFieldDeactivated() { mNfcService.sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null); } + + private void notifySeApduReceived(byte[] apdu) { + mNfcService.sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu); + } + + private void notifySeEmvCardRemoval() { + mNfcService.sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null); + } + + private void notifySeMifareAccess(byte[] block) { + mNfcService.sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block); + } } diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index 6c536d5..4cd2d04 100755 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -221,6 +221,9 @@ public class NfcService extends Application { static final int MSG_MOCK_NDEF = 7; static final int MSG_SE_FIELD_ACTIVATED = 8; static final int MSG_SE_FIELD_DEACTIVATED = 9; + static final int MSG_SE_APDU_RECEIVED = 10; + static final int MSG_SE_EMV_CARD_REMOVAL = 11; + static final int MSG_SE_MIFARE_ACCESS = 12; // Copied from com.android.nfc_extras to avoid library dependency // Must keep in sync with com.android.nfc_extras @@ -234,6 +237,19 @@ public class NfcService extends Application { "com.android.nfc_extras.action.AID_SELECTED"; public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID"; + public static final String ACTION_APDU_RECEIVED = + "com.android.nfc_extras.action.APDU_RECEIVED"; + public static final String EXTRA_APDU_BYTES = + "com.android.nfc_extras.extra.APDU_BYTES"; + + public static final String ACTION_EMV_CARD_REMOVAL = + "com.android.nfc_extras.action.EMV_CARD_REMOVAL"; + + public static final String ACTION_MIFARE_ACCESS_DETECTED = + "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED"; + public static final String EXTRA_MIFARE_BLOCK = + "com.android.nfc_extras.extra.MIFARE_BLOCK"; + // Locked on mNfcAdapter PendingIntent mDispatchOverrideIntent; IntentFilter[] mDispatchOverrideFilters; @@ -2457,10 +2473,47 @@ public class NfcService extends Application { Intent aidIntent = new Intent(); aidIntent.setAction(ACTION_AID_SELECTED); aidIntent.putExtra(EXTRA_AID, aid); - if (DBG) Log.d(TAG, "Broadcasting ACTION_AID_SELECTED"); + if (DBG) Log.d(TAG, "Broadcasting " + ACTION_AID_SELECTED); mContext.sendBroadcast(aidIntent, NFCEE_ADMIN_PERM); break; + case MSG_SE_EMV_CARD_REMOVAL: + if (DBG) Log.d(TAG, "Card Removal message"); + /* Send broadcast */ + Intent cardRemovalIntent = new Intent(); + cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL); + if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL); + mContext.sendBroadcast(cardRemovalIntent, NFCEE_ADMIN_PERM); + break; + + case MSG_SE_APDU_RECEIVED: + if (DBG) Log.d(TAG, "APDU Received message"); + byte[] apduBytes = (byte[]) msg.obj; + /* Send broadcast */ + Intent apduReceivedIntent = new Intent(); + apduReceivedIntent.setAction(ACTION_APDU_RECEIVED); + if (apduBytes != null && apduBytes.length > 0) { + apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes); + } + if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED); + mContext.sendBroadcast(apduReceivedIntent, NFCEE_ADMIN_PERM); + break; + + case MSG_SE_MIFARE_ACCESS: + if (DBG) Log.d(TAG, "MIFARE access message"); + /* Send broadcast */ + byte[] mifareCmd = (byte[]) msg.obj; + Intent mifareAccessIntent = new Intent(); + mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED); + if (mifareCmd != null && mifareCmd.length > 1) { + int mifareBlock = mifareCmd[1] & 0xff; + if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock); + mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock); + } + if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED); + mContext.sendBroadcast(mifareAccessIntent, NFCEE_ADMIN_PERM); + break; + case MSG_LLCP_LINK_ACTIVATION: NativeP2pDevice device = (NativeP2pDevice) msg.obj; |