keep history
diff --git a/jni/com_android_nfc_NativeNfcManager.cpp b/jni/com_android_nfc_NativeNfcManager.cpp
index cba4691..e724524 100644
--- a/jni/com_android_nfc_NativeNfcManager.cpp
+++ b/jni/com_android_nfc_NativeNfcManager.cpp
@@ -26,13 +26,16 @@
#define ERROR_BUFFER_TOO_SMALL -12
#define ERROR_INSUFFICIENT_RESOURCES -9
-#define EEDATA_SETTINGS_NUMBER 28
+#define EEDATA_SETTINGS_NUMBER 29
static phLibNfc_sConfig_t gDrvCfg;
void *gHWRef;
static phNfc_sData_t gInputParam;
static phNfc_sData_t gOutputParam;
+uint8_t device_connected_flag;
+static bool driverConfigured = FALSE;
+
static phLibNfc_Handle hLlcpHandle;
static NFCSTATUS lastErrorStatus = NFCSTATUS_FAILED;
static phLibNfc_Llcp_eLinkStatus_t g_eLinkStatus = phFriNfc_LlcpMac_eLinkDefault;
@@ -46,6 +49,10 @@
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;
@@ -102,6 +109,9 @@
// Set NFCT ATQA
,{0x00, 0x98, 0x7D, 0x02}
,{0x00, 0x98, 0x7E, 0x00}
+
+ // Enable CEA detection mechanism
+ ,{0x00, 0x9F, 0xC8, 0x01}
};
/* Internal functions declaration */
@@ -210,7 +220,7 @@
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;
@@ -277,13 +287,21 @@
goto clean_and_return;
}
- /* Download Status */
- if(cb_data.status != NFCSTATUS_SUCCESS)
+ /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
+ try to download an old-style firmware on top of a new-style
+ firmware. Hence, this is expected behavior, and not an
+ error condition. */
+ if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
{
status = cb_data.status;
goto clean_and_return;
}
+ if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
+ {
+ LOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
+ }
+
reinit:
TRACE("phLibNfc_HW_Reset()");
phLibNfc_HW_Reset();
@@ -323,13 +341,14 @@
}
else
{
- LOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, FW Update Info = %d",
+ LOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d",
caps.psDevCapabilities.hal_version,
caps.psDevCapabilities.fw_version,
caps.psDevCapabilities.hw_version,
caps.psDevCapabilities.model_id,
caps.psDevCapabilities.hci_version,
caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1],
+ caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2],
caps.psDevCapabilities.firmware_update_info);
}
@@ -341,20 +360,83 @@
return status;
}
+static int nfc_jni_configure_driver(struct nfc_jni_native_data *nat)
+{
+ char value[PROPERTY_VALUE_MAX];
+ int result = FALSE;
+ NFCSTATUS status;
+
+ /* ====== CONFIGURE DRIVER ======= */
+ /* Configure hardware link */
+ gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
+
+ property_get("ro.nfc.port", value, "unknown");
+ gDrvCfg.nLinkType = parseLinkType(value);
+
+ TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x, 0x%08x)", gDrvCfg.nClientId, gDrvCfg.nLinkType);
+ REENTRANCE_LOCK();
+ status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef);
+ REENTRANCE_UNLOCK();
+ if(status == NFCSTATUS_ALREADY_INITIALISED) {
+ LOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ }
+ else if(status != NFCSTATUS_SUCCESS)
+ {
+ LOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ goto clean_and_return;
+ }
+ TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+
+ if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread, nat) != 0)
+ {
+ LOGE("pthread_create failed");
+ goto clean_and_return;
+ }
+
+ driverConfigured = TRUE;
+
+clean_and_return:
+ return result;
+}
+
+static int nfc_jni_unconfigure_driver(struct nfc_jni_native_data *nat)
+{
+ int result = FALSE;
+ NFCSTATUS status;
+
+ /* Unconfigure driver */
+ TRACE("phLibNfc_Mgt_UnConfigureDriver()");
+ REENTRANCE_LOCK();
+ status = phLibNfc_Mgt_UnConfigureDriver(gHWRef);
+ REENTRANCE_UNLOCK();
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ LOGE("phLibNfc_Mgt_UnConfigureDriver() returned error 0x%04x[%s] -- this should never happen", status, nfc_jni_get_status_name( status));
+ }
+ else
+ {
+ LOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ result = TRUE;
+ }
+
+ driverConfigured = FALSE;
+
+ return result;
+}
+
/* Initialization function */
static int nfc_jni_initialize(struct nfc_jni_native_data *nat) {
struct timespec ts;
uint8_t resp[16];
NFCSTATUS status;
phLibNfc_StackCapabilities_t caps;
- char value[PROPERTY_VALUE_MAX];
- int result = FALSE;
phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index = 0, SmartMX_detected = 0;
phLibNfc_Llcp_sLinkParameters_t LlcpConfigInfo;
struct nfc_jni_callback_data cb_data;
uint8_t firmware_status;
uint8_t update = TRUE;
+ int result = JNI_FALSE;
LOGD("Start Initialization\n");
@@ -364,36 +446,16 @@
goto clean_and_return;
}
+ /* Reset device connected handle */
+ device_connected_flag = 0;
+
/* Reset stored handle */
storedHandle = 0;
- /* Configure hardware link */
- gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
-
- property_get("ro.nfc.port", value, "unknown");
- gDrvCfg.nLinkType = parseLinkType(value);
-
- /* ====== CONFIGURE DRIVER ======= */
-
- TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x, 0x%08x)", gDrvCfg.nClientId, gDrvCfg.nLinkType);
- REENTRANCE_LOCK();
- status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef);
- REENTRANCE_UNLOCK();
- if(status == NFCSTATUS_ALREADY_INITIALISED) {
- LOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- }
- else if(status != NFCSTATUS_SUCCESS)
+ /* Initialize Driver */
+ if(!driverConfigured)
{
- LOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- goto clean_and_return;
- }
- TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
-
- if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread,
- nat) != 0)
- {
- LOGE("pthread_create failed");
- goto clean_and_return;
+ nfc_jni_configure_driver(nat);
}
/* ====== INITIALIZE ======= */
@@ -460,6 +522,7 @@
break;
}
LOGW("Firmware update FAILED");
+ update = FALSE;
}
if(i>=3)
{
@@ -655,6 +718,9 @@
/* Reset the PN544 ISO XCHG / sw watchdog timeouts */
nfc_jni_reset_timeout_values();
+ /* Reset device connected flag */
+ device_connected_flag = 0;
+
/* Restart Polling loop */
TRACE("****** Start NFC Discovery ******");
REENTRANCE_LOCK();
@@ -839,12 +905,15 @@
sLinkParams.miu,
sLinkParams.option,
sLinkParams.wks);
+ device_connected_flag = 1;
}
}
else if(eLinkStatus == phFriNfc_LlcpMac_eLinkDeactivated)
{
LOGI("LLCP Link deactivated");
free(pContextData);
+ /* Reset device connected flag */
+ device_connected_flag = 0;
/* Reset incoming socket list */
while (!LIST_EMPTY(&pMonitor->incoming_socket_head))
@@ -982,7 +1051,10 @@
{
LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status);
TRACE("Discovered %d tags", uNofRemoteDev);
-
+
+ /* Reset device connected flag */
+ device_connected_flag = 1;
+
if((psRemoteDevList->psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
|| (psRemoteDevList->psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Target))
{
@@ -1176,9 +1248,11 @@
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 +1279,18 @@
{
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 +1303,7 @@
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 +1315,56 @@
}
}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 +1400,9 @@
e->ExceptionClear();
clean_and_return:
- if(aid_array != NULL)
+ if(tmp_array != NULL)
{
- e->DeleteLocalRef(aid_array);
+ e->DeleteLocalRef(tmp_array);
}
}
@@ -1354,6 +1478,9 @@
/* Reset the PN544 ISO XCHG / sw watchdog timeouts */
nfc_jni_reset_timeout_values();
+ /* Reset device connected flag */
+ device_connected_flag = 0;
+
#if 0
nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
@@ -1454,7 +1581,7 @@
}
discovery_cfg.PollDevInfo.PollEnabled = 0;
- discovery_cfg.Duration = 0xffffffff;
+ discovery_cfg.Duration = 300000; /* in ms */
/*discovery_cfg.NfcIP_Mode = phNfc_eInvalidP2PMode;*/
discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode;
discovery_cfg.NfcIP_Tgt_Disable = TRUE;
@@ -1631,7 +1758,16 @@
"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)
{
@@ -1644,11 +1780,11 @@
LOGD("Native Structure initialization failed");
return FALSE;
}
-
- TRACE("****** Init Native Structure OK ******");
+ TRACE("****** Init Native Structure OK ******");
return TRUE;
+
}
-
+
/* Init/Deinit method */
static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
{
@@ -1687,17 +1823,20 @@
{
struct timespec ts;
NFCSTATUS status;
+ int result = JNI_FALSE;
struct nfc_jni_native_data *nat;
int bStackReset = FALSE;
struct nfc_jni_callback_data cb_data;
+ CONCURRENCY_LOCK();
+
/* Retrieve native structure address */
- nat = nfc_jni_get_nat(e, o);
+ nat = nfc_jni_get_nat(e, o);
/* Clear previous configuration */
memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
-
+
/* Create the local semaphore */
if (nfc_cb_data_init(&cb_data, NULL))
{
@@ -1747,22 +1886,12 @@
emergency_recovery(nat);
}
- /* Unconfigure driver */
- TRACE("phLibNfc_Mgt_UnConfigureDriver()");
- REENTRANCE_LOCK();
- status = phLibNfc_Mgt_UnConfigureDriver(gHWRef);
- REENTRANCE_UNLOCK();
- if(status != NFCSTATUS_SUCCESS)
- {
- LOGE("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- }
- else
- {
- LOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
- }
+ result = nfc_jni_unconfigure_driver(nat);
TRACE("NFC Deinitialized");
+ CONCURRENCY_UNLOCK();
+
return TRUE;
}
@@ -2384,14 +2513,123 @@
emergency_recovery(NULL);
}
+static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
+{
+ char* firmware_version;
+ jboolean result = FALSE;
+ int load_result;
+ int unconfigure_status;
+ bool drive_state = FALSE;
+ uint8_t OutputBuffer[1];
+ uint8_t InputBuffer[1];
+ struct timespec ts;
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ struct nfc_jni_callback_data cb_data;
+ struct nfc_jni_native_data *nat = NULL;
+ char value[PROPERTY_VALUE_MAX];
+
+ /* Create the local semaphore */
+ if (!nfc_cb_data_init(&cb_data, NULL))
+ {
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ /* Retrieve native structure address */
+ nat = nfc_jni_get_nat(e, o);
+
+ CONCURRENCY_LOCK();
+
+ /* Initialize Driver */
+ if(!driverConfigured)
+ {
+ result = nfc_jni_configure_driver(nat);
+ drive_state = TRUE;
+ }
+
+ TRACE("com_android_nfc_NfcManager_doDownload()");
+
+ TRACE("Go in Download Mode");
+ phLibNfc_Download_Mode();
+
+ TRACE("Load new Firmware Image");
+ load_result = phLibNfc_Load_Firmware_Image();
+ if(load_result != 0)
+ {
+ TRACE("Load new Firmware Image - status = %d",load_result);
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ // Download
+ gInputParam.buffer = InputBuffer;
+ gInputParam.length = 0x01;
+ gOutputParam.buffer = OutputBuffer;
+ gOutputParam.length = 0x01;
+
+ LOGD("Download new Firmware");
+ REENTRANCE_LOCK();
+ status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
+ REENTRANCE_UNLOCK();
+ if(status != NFCSTATUS_PENDING)
+ {
+ LOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ result = FALSE;
+ goto clean_and_return;
+ }
+ TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+
+ /* Wait for callback response */
+ if(sem_wait(&cb_data.sem))
+ {
+ LOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
+ try to download an old-style firmware on top of a new-style
+ firmware. Hence, this is expected behavior, and not an
+ error condition. */
+ if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
+ {
+ TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
+ result = FALSE;
+ goto clean_and_return;
+ }
+
+ if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
+ {
+ LOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
+ }
+
+ /*Download is successful*/
+ result = TRUE;
+
+clean_and_return:
+ TRACE("phLibNfc_HW_Reset()");
+ phLibNfc_HW_Reset();
+ /* Deinitialize Driver */
+ if(drive_state)
+ {
+ result = nfc_jni_unconfigure_driver(nat);
+ }
+ CONCURRENCY_UNLOCK();
+ nfc_cb_data_deinit(&cb_data);
+ return result;
+}
+
/*
* JNI registration.
*/
static JNINativeMethod gMethods[] =
{
+ {"doDownload", "()Z",
+ (void *)com_android_nfc_NfcManager_doDownload},
+
{"initializeNativeStructure", "()Z",
(void *)com_android_nfc_NfcManager_init_native_struc},
-
+
{"initialize", "()Z",
(void *)com_android_nfc_NfcManager_initialize},
diff --git a/jni/com_android_nfc_NativeNfcSecureElement.cpp b/jni/com_android_nfc_NativeNfcSecureElement.cpp
index f309122..f4a402b 100755
--- a/jni/com_android_nfc_NativeNfcSecureElement.cpp
+++ b/jni/com_android_nfc_NativeNfcSecureElement.cpp
@@ -24,6 +24,7 @@
static int secureElementHandle;
extern void *gHWRef;
static int SecureElementTech;
+extern uint8_t device_connected_flag;
namespace android {
@@ -204,6 +205,13 @@
TRACE("Open Secure Element");
+ /* Check if NFC device is already connected to a tag or P2P peer */
+ if (device_connected_flag == 1)
+ {
+ LOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag");
+ goto clean_and_return;
+ }
+
/* Test if External RF field is detected */
InParam.buffer = ExternalRFDetected;
InParam.length = 3;
@@ -215,6 +223,7 @@
if(ret!=NFCSTATUS_PENDING)
{
LOGE("IOCTL status error");
+ goto clean_and_return;
}
/* Wait for callback response */
diff --git a/jni/com_android_nfc_NativeNfcTag.cpp b/jni/com_android_nfc_NativeNfcTag.cpp
index 566b28e..e724309 100644
--- a/jni/com_android_nfc_NativeNfcTag.cpp
+++ b/jni/com_android_nfc_NativeNfcTag.cpp
@@ -25,7 +25,7 @@
uint8_t *nfc_jni_ndef_buf = NULL;
uint32_t nfc_jni_ndef_buf_len = 0;
-
+extern uint8_t device_connected_flag;
namespace android {
@@ -444,13 +444,12 @@
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 @@
/* 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 @@
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 @@
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 @@
/* 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 @@
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 @@
return com_android_nfc_NativeNfcTag_doConnect(e, o, handle);
}
else {
- return JNI_TRUE;
+ return NFCSTATUS_SUCCESS;
}
}
else {
- return JNI_FALSE;
+ return NFCSTATUS_REJECTED;
}
}
@@ -639,9 +642,12 @@
{
goto clean_and_return;
}
+
result = JNI_TRUE;
clean_and_return:
+ /* Reset device connected flag */
+ device_connected_flag = 0;
nfc_cb_data_deinit(&cb_data);
CONCURRENCY_UNLOCK();
return result;
@@ -937,11 +943,10 @@
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);
@@ -952,6 +957,7 @@
/* 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;
@@ -973,16 +979,18 @@
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) {
@@ -1005,7 +1013,7 @@
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)
@@ -1051,6 +1059,7 @@
clean_and_return:
nfc_cb_data_deinit(&cb_data);
+
CONCURRENCY_UNLOCK();
return result;
@@ -1217,19 +1226,19 @@
*/
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/jni/com_android_nfc_NativeP2pDevice.cpp b/jni/com_android_nfc_NativeP2pDevice.cpp
index fd9af3e..ed85620 100644
--- a/jni/com_android_nfc_NativeP2pDevice.cpp
+++ b/jni/com_android_nfc_NativeP2pDevice.cpp
@@ -20,6 +20,8 @@
#include "com_android_nfc.h"
+extern uint8_t device_connected_flag;
+
namespace android {
extern void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat);
@@ -252,9 +254,12 @@
{
goto clean_and_return;
}
+
result = JNI_TRUE;
clean_and_return:
+ /* Reset device connected flag */
+ device_connected_flag = 0;
nfc_cb_data_deinit(&cb_data);
CONCURRENCY_UNLOCK();
return result;
diff --git a/src/com/android/nfc/NativeNfcManager.java b/src/com/android/nfc/NativeNfcManager.java
index 3f0f532..5938613 100755
--- a/src/com/android/nfc/NativeNfcManager.java
+++ b/src/com/android/nfc/NativeNfcManager.java
@@ -104,6 +104,8 @@
doSetIsoDepTimeout(timeout);
}
+ public native boolean doDownload();
+
/**
* Notifies Ndef Message (TODO: rename into notifyTargetDiscovered)
*/
@@ -146,4 +148,16 @@
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/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 @@
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 @@
}
}
- 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 @@
// 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 @@
// 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 @@
if (mWatchdog != null) {
mWatchdog.doResume();
}
- return isSuccess;
+ mLastStatusCode = status;
+ return status;
}
public synchronized void startPresenceChecking() {
@@ -219,28 +221,28 @@
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 @@
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 @@
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 283d72d..51cbfa4 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -70,7 +70,7 @@
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -79,6 +79,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -89,6 +90,7 @@
private static final String MY_TAG_FILE_NAME = "mytag";
private static final String SE_RESET_SCRIPT_FILE_NAME = "/system/etc/se-reset-script";
+ private static final String NFC_CONTROLLER_FIRMWARE_FILE_NAME = "/system/lib/libpn544_fw.so";
static {
System.loadLibrary("nfc_jni");
@@ -189,6 +191,9 @@
private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip";
private static final boolean DISCOVERY_NFCIP_DEFAULT = true;
+ private static final String PREF_FIRMWARE_MODTIME = "firmware_modtime";
+ private static final long FIRMWARE_MODTIME_DEFAULT = -1;
+
/** NFC Reader Discovery mode for enableDiscovery() */
private static final int DISCOVERY_MODE_READER = 0;
@@ -221,6 +226,11 @@
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;
+
+ 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
@@ -234,6 +244,19 @@
"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;
@@ -256,7 +279,7 @@
private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
private boolean mScreenOn;
- private String mSePackageName;
+ private HashSet<String> mSePackages = new HashSet<String>();
// fields below are final after onCreate()
Context mContext;
@@ -307,6 +330,7 @@
NfcAdapter.ACTION_TECH_DISCOVERED, NfcAdapter.ACTION_TECH_DISCOVERED);
mSecureElement = new NativeNfcSecureElement();
+ mEeRoutingState = ROUTE_OFF;
mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
mPrefsEditor = mPrefs.edit();
@@ -336,9 +360,14 @@
Thread t = new Thread() {
@Override
public void run() {
+ Log.d(TAG,"checking on firmware download");
boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT);
if (nfc_on) {
+ Log.d(TAG,"NFC is on. Doing normal stuff");
_enable(false, true);
+ } else {
+ Log.d(TAG,"NFC is off. Checking firmware version");
+ _maybeUpdateFirmware();
}
resetSeOnFirstBoot();
}
@@ -1288,7 +1317,7 @@
// 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;
@@ -1309,7 +1338,7 @@
/* 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;
@@ -1375,20 +1404,19 @@
@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
@@ -1821,6 +1849,12 @@
} catch (RemoteException e) {
mOpenEe.binderDied();
}
+
+ // Add the calling package to the list of packages that have accessed
+ // the secure element.
+ for (String packageName : getPackageManager().getPackagesForUid(getCallingUid())) {
+ mSePackages.add(packageName);
+ }
}
}
@@ -1884,17 +1918,8 @@
}
@Override
- public void registerTearDownApdus(String packageName, ApduList apdu) throws RemoteException {
+ public void authenticate(byte[] token) throws RemoteException {
NfcService.enforceNfceeAdminPerm(mContext);
- Log.w(TAG, "NOP");
- //TODO: Remove this API
- }
-
- @Override
- public void unregisterTearDownApdus(String packageName) throws RemoteException {
- NfcService.enforceNfceeAdminPerm(mContext);
- Log.w(TAG, "NOP");
- //TODO: Remove this API
}
};
@@ -1982,6 +2007,48 @@
return isSuccess;
}
+ // Check that the NFC controller firmware is up to date. This
+ // ensures that firmware updates are applied in a timely fashion,
+ // and makes it much less likely that the user will have to wait
+ // for a firmware download when they enable NFC in the settings
+ // app. Firmware download can take some time, so this should be
+ // run in a separate thread.
+ private void _maybeUpdateFirmware() {
+ // check the timestamp of the firmware file
+ File firmwareFile;
+ int nbRetry = 0;
+ try {
+ firmwareFile = new File(NFC_CONTROLLER_FIRMWARE_FILE_NAME);
+ } catch(NullPointerException npe) {
+ Log.e(TAG,"path to firmware file was null");
+ return;
+ }
+
+ long modtime = firmwareFile.lastModified();
+
+ long prev_fw_modtime = mPrefs.getLong(PREF_FIRMWARE_MODTIME, FIRMWARE_MODTIME_DEFAULT);
+ Log.d(TAG,"prev modtime: " + prev_fw_modtime);
+ Log.d(TAG,"new modtime: " + modtime);
+ if (prev_fw_modtime == modtime) {
+ return;
+ }
+
+ // FW download.
+ while(nbRetry < 5) {
+ Log.d(TAG,"Perform Download");
+ if(mManager.doDownload()) {
+ Log.d(TAG,"Download Success");
+ // Now that we've finished updating the firmware, save the new modtime.
+ mPrefsEditor.putLong(PREF_FIRMWARE_MODTIME, modtime);
+ mPrefsEditor.apply();
+ break;
+ } else {
+ Log.d(TAG,"Download Failed");
+ nbRetry++;
+ }
+ }
+ }
+
private class WatchDogThread extends Thread {
boolean mWatchDogCanceled = false;
@Override
@@ -2346,15 +2413,19 @@
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()) {
@@ -2369,7 +2440,8 @@
} // 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;
@@ -2403,10 +2475,17 @@
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];
@@ -2447,13 +2526,14 @@
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;
@@ -2464,10 +2544,47 @@
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;
@@ -2972,8 +3089,9 @@
String packageName = data.getSchemeSpecificPart();
synchronized (NfcService.this) {
- if (packageName.equals(mSePackageName)) {
+ if (mSePackages.contains(packageName)) {
executeSeReset();
+ mSePackages.remove(packageName);
}
}
}