summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xnci/jni/NativeNfcManager.cpp70
-rwxr-xr-xnci/jni/NativeNfcTag.cpp101
-rwxr-xr-xnci/jni/NfcTag.cpp85
-rwxr-xr-xnci/jni/NfcTag.h49
-rw-r--r--nci/jni/Pn544Interop.cpp153
-rw-r--r--nci/jni/Pn544Interop.h64
-rwxr-xr-xnci/jni/SecureElement.cpp34
-rwxr-xr-xnci/jni/SecureElement.h3
8 files changed, 501 insertions, 58 deletions
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp
index c3e76fa..5fd3025 100755
--- a/nci/jni/NativeNfcManager.cpp
+++ b/nci/jni/NativeNfcManager.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "PowerSwitch.h"
#include "JavaClassConstants.h"
+#include "Pn544Interop.h"
extern "C"
{
@@ -85,6 +86,7 @@ namespace android
const char* gNativeNfcManagerClassName = "com/android/nfc/dhimpl/NativeNfcManager";
const char* gNativeNfcSecureElementClassName = "com/android/nfc/dhimpl/NativeNfcSecureElement";
void doStartupConfig ();
+ void startStopPolling (bool isStartPolling);
}
@@ -284,6 +286,7 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat
case NFA_ACTIVATED_EVT: // NFC link/protocol activated
ALOGD("%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d", __FUNCTION__, gIsSelectingRfInterface);
+ NfcTag::getInstance().setActivationState ();
if (gIsSelectingRfInterface)
{
nativeNfcTag_doConnectStatus(true);
@@ -294,13 +297,14 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat
if (isPeerToPeer(eventData->activated))
{
ALOGD("%s: NFA_ACTIVATED_EVT; is p2p", __FUNCTION__);
- break;
}
- NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
+ else if (pn544InteropIsBusy() == false)
+ NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
break;
case NFA_DEACTIVATED_EVT: // NFC link/protocol deactivated
ALOGD("%s: NFA_DEACTIVATED_EVT Type: %u, gIsTagDeactivating: %d", __FUNCTION__, eventData->deactivated.type,gIsTagDeactivating);
+ NfcTag::getInstance().setDeactivationState (eventData->deactivated);
if (gIsTagDeactivating || gIsSelectingRfInterface)
{
if (gIsTagDeactivating)
@@ -333,6 +337,7 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat
status,
eventData->ndef_detect.protocol, eventData->ndef_detect.max_size,
eventData->ndef_detect.cur_size, eventData->ndef_detect.flags);
+ NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
nativeNfcTag_doCheckNdefResult(status,
eventData->ndef_detect.max_size, eventData->ndef_detect.cur_size,
eventData->ndef_detect.flags);
@@ -720,7 +725,8 @@ static jboolean nfcManager_doInitialize (JNIEnv* e, jobject o)
}
TheEnd:
- PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
+ if (sIsNfaEnabled)
+ PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
ALOGD ("%s: exit", __FUNCTION__);
return sIsNfaEnabled ? JNI_TRUE : JNI_FALSE;
}
@@ -767,7 +773,7 @@ static void nfcManager_enableDiscovery (JNIEnv* e, jobject o)
{
ALOGD ("%s: wait for enable event", __FUNCTION__);
sDiscoveryEnabled = true;
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_START_EVT
+ sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
ALOGD ("%s: got enabled event", __FUNCTION__);
}
else
@@ -810,6 +816,7 @@ void nfcManager_disableDiscovery (JNIEnv* e, jobject o)
tNFA_STATUS status = NFA_STATUS_OK;
ALOGD ("%s: enter;", __FUNCTION__);
+ pn544InteropAbortNow ();
if (sDiscoveryEnabled == false)
{
ALOGD ("%s: already disabled", __FUNCTION__);
@@ -826,7 +833,7 @@ void nfcManager_disableDiscovery (JNIEnv* e, jobject o)
if (status == NFA_STATUS_OK)
{
sDiscoveryEnabled = false;
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_STOP_EVT
+ sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
}
else
ALOGE ("%s: Failed to disable polling; error=0x%X", __FUNCTION__, status);
@@ -994,7 +1001,7 @@ static jboolean nfcManager_doDeinitialize (JNIEnv* e, jobject o)
ALOGD ("%s: enter", __FUNCTION__);
sIsDisabling = true;
-
+ pn544InteropAbortNow ();
SecureElement::getInstance().finalize ();
if (sIsNfaEnabled)
@@ -1676,5 +1683,56 @@ bool nfcManager_isNfcActive()
}
+/*******************************************************************************
+**
+** Function: startStopPolling
+**
+** Description: Start or stop polling.
+** isStartPolling: true to start polling; false to stop polling.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void startStopPolling (bool isStartPolling)
+{
+ ALOGD ("%s: enter; isStart=%u", __FUNCTION__, isStartPolling);
+ tNFA_STATUS stat = NFA_STATUS_FAILED;
+
+ startRfDiscovery (false);
+ if (isStartPolling)
+ {
+ tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
+ unsigned long num = 0;
+ if (GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num)))
+ tech_mask = num;
+
+ SyncEventGuard guard (sNfaEnableDisablePollingEvent);
+ ALOGD ("%s: enable polling", __FUNCTION__);
+ stat = NFA_EnablePolling (tech_mask);
+ if (stat == NFA_STATUS_OK)
+ {
+ ALOGD ("%s: wait for enable event", __FUNCTION__);
+ sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
+ }
+ else
+ ALOGE ("%s: fail enable polling; error=0x%X", __FUNCTION__, stat);
+ }
+ else
+ {
+ SyncEventGuard guard (sNfaEnableDisablePollingEvent);
+ ALOGD ("%s: disable polling", __FUNCTION__);
+ stat = NFA_DisablePolling ();
+ if (stat == NFA_STATUS_OK)
+ {
+ sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
+ }
+ else
+ ALOGE ("%s: fail disable polling; error=0x%X", __FUNCTION__, stat);
+ }
+ startRfDiscovery (true);
+ ALOGD ("%s: exit", __FUNCTION__);
+}
+
+
} /* namespace android */
diff --git a/nci/jni/NativeNfcTag.cpp b/nci/jni/NativeNfcTag.cpp
index e7352c5..8c0426b 100755
--- a/nci/jni/NativeNfcTag.cpp
+++ b/nci/jni/NativeNfcTag.cpp
@@ -25,6 +25,7 @@
#include "Mutex.h"
#include "IntervalTimer.h"
#include "JavaClassConstants.h"
+#include "Pn544Interop.h"
extern "C"
{
@@ -488,18 +489,28 @@ static jint nativeNfcTag_doConnect (JNIEnv *e, jobject o, jint targetHandle)
int i = targetHandle;
struct nfc_jni_native_data *nat = getNative (0, 0);
NfcTag& natTag = NfcTag::getInstance ();
- sNeedToSwitchRf = false;
+ int retCode = NFCSTATUS_SUCCESS;
+ sNeedToSwitchRf = false;
if (i >= NfcTag::MAX_NUM_TECHNOLOGY)
{
ALOGE ("%s: Handle not found", __FUNCTION__);
- return NFCSTATUS_FAILED;
+ retCode = NFCSTATUS_FAILED;
+ goto TheEnd;
+ }
+
+ if (natTag.getActivationState() != NfcTag::Active)
+ {
+ ALOGE ("%s: tag already deactivated", __FUNCTION__);
+ retCode = NFCSTATUS_FAILED;
+ goto TheEnd;
}
if (natTag.mTechLibNfcTypes[i] != NFC_PROTOCOL_ISO_DEP)
{
ALOGD ("%s() Nfc type = %d, do nothing for non ISO_DEP", __FUNCTION__, natTag.mTechLibNfcTypes[i]);
- return NFCSTATUS_SUCCESS;
+ retCode = NFCSTATUS_SUCCESS;
+ goto TheEnd;
}
if (natTag.mTechList[i] == TARGET_TYPE_ISO14443_3A || natTag.mTechList[i] == TARGET_TYPE_ISO14443_3B)
@@ -514,7 +525,9 @@ static jint nativeNfcTag_doConnect (JNIEnv *e, jobject o, jint targetHandle)
return (switchRfInterface (NFA_INTERFACE_ISO_DEP) ? NFCSTATUS_SUCCESS : NFCSTATUS_FAILED);
}
- return NFCSTATUS_SUCCESS;
+TheEnd:
+ ALOGD ("%s: exit 0x%X", __FUNCTION__, retCode);
+ return retCode;
}
/*******************************************************************************
@@ -530,22 +543,30 @@ static jint nativeNfcTag_doConnect (JNIEnv *e, jobject o, jint targetHandle)
*******************************************************************************/
static int reSelect (tNFA_INTF_TYPE rfInterface)
{
- ALOGD ("%s: rf intf = %d", __FUNCTION__, rfInterface);
+ ALOGD ("%s: enter; rf intf = %d", __FUNCTION__, rfInterface);
NfcTag& natTag = NfcTag::getInstance ();
- ALOGD ("%s: NFA_Deactivate()", __FUNCTION__);
tNFA_STATUS status;
int rVal = 1;
do
{
+ //if tag has shutdown, abort this method
+ if (NfcTag::getInstance ().isNdefDetectionTimedOut())
+ {
+ ALOGD ("%s: ndef detection timeout; break", __FUNCTION__);
+ rVal = STATUS_CODE_TARGET_LOST;
+ break;
+ }
+
{
SyncEventGuard g (sReconnectEvent);
gIsTagDeactivating = true;
sGotDeactivate = false;
- if (NFA_STATUS_OK != (status = NFA_Deactivate (TRUE)))
+ ALOGD ("%s: deactivate to sleep", __FUNCTION__);
+ if (NFA_STATUS_OK != (status = NFA_Deactivate (TRUE))) //deactivate to sleep state
{
- ALOGE ("%s: NFA_Deactivate failed, status = %d", __FUNCTION__, status);
+ ALOGE ("%s: deactivate failed, status = %d", __FUNCTION__, status);
break;
}
@@ -555,8 +576,9 @@ static int reSelect (tNFA_INTF_TYPE rfInterface)
}
}
- if (! NfcTag::getInstance ().isActivated ())
+ if (NfcTag::getInstance ().getActivationState () != NfcTag::Sleep)
{
+ ALOGD ("%s: tag is not in sleep", __FUNCTION__);
rVal = STATUS_CODE_TARGET_LOST;
break;
}
@@ -567,7 +589,7 @@ static int reSelect (tNFA_INTF_TYPE rfInterface)
SyncEventGuard g2 (sReconnectEvent);
sConnectWaitingForComplete = JNI_TRUE;
- ALOGD ("%s: NFA_Select()", __FUNCTION__);
+ ALOGD ("%s: select interface %u", __FUNCTION__, rfInterface);
gIsSelectingRfInterface = true;
if (NFA_STATUS_OK != (status = NFA_Select (natTag.mTechHandles[0], natTag.mTechLibNfcTypes[0], rfInterface)))
{
@@ -578,15 +600,15 @@ static int reSelect (tNFA_INTF_TYPE rfInterface)
sConnectOk = false;
if (sReconnectEvent.wait (1000) == false) //if timeout occured
{
- ALOGE ("%s: wait response timeout", __FUNCTION__);
+ ALOGE ("%s: timeout waiting for select", __FUNCTION__);
break;
}
}
- ALOGD("%s: done waiting on NFA_Select() sConnectOk=%d", __FUNCTION__, sConnectOk);
- if (! NfcTag::getInstance ().isActivated ())
+ ALOGD("%s: select completed; sConnectOk=%d", __FUNCTION__, sConnectOk);
+ if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
{
- ALOGD("%s: Tag no longer active", __FUNCTION__);
+ ALOGD("%s: tag is not active", __FUNCTION__);
rVal = STATUS_CODE_TARGET_LOST;
break;
}
@@ -596,6 +618,7 @@ static int reSelect (tNFA_INTF_TYPE rfInterface)
sConnectWaitingForComplete = JNI_FALSE;
gIsTagDeactivating = false;
gIsSelectingRfInterface = false;
+ ALOGD ("%s: exit; status=%d", __FUNCTION__, rVal);
return rVal;
}
@@ -650,22 +673,26 @@ static bool switchRfInterface (tNFA_INTF_TYPE rfInterface)
*******************************************************************************/
static jint nativeNfcTag_doReconnect (JNIEnv *e, jobject o)
{
- ALOGD ("%s", __FUNCTION__);
-
- tNFA_INTF_TYPE intf = NFA_INTERFACE_FRAME;
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retCode = NFCSTATUS_SUCCESS;
NfcTag& natTag = NfcTag::getInstance ();
+ if (natTag.getActivationState() != NfcTag::Active)
+ {
+ ALOGE ("%s: tag already deactivated", __FUNCTION__);
+ retCode = NFCSTATUS_FAILED;
+ goto TheEnd;
+ }
+
// this is only supported for type 2 or 4 (ISO_DEP) tags
if (natTag.mTechLibNfcTypes[0] == NFA_PROTOCOL_ISO_DEP)
- intf = NFA_INTERFACE_ISO_DEP;
+ retCode = reSelect(NFA_INTERFACE_ISO_DEP);
else if (natTag.mTechLibNfcTypes[0] == NFA_PROTOCOL_T2T)
- intf = NFA_INTERFACE_FRAME;
- else
- {
- return 0; // success
- }
+ retCode = reSelect(NFA_INTERFACE_FRAME);
- return reSelect(intf);
+TheEnd:
+ ALOGD ("%s: exit 0x%X", __FUNCTION__, retCode);
+ return retCode;
}
@@ -707,9 +734,9 @@ static jboolean nativeNfcTag_doDisconnect (JNIEnv *e, jobject o)
gGeneralTransceiveTimeout = DEFAULT_GENERAL_TRANS_TIMEOUT;
- if (NfcTag::getInstance ().isActivated () == false)
+ if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
{
- ALOGD ("%s: tag already deactivated", __FUNCTION__);
+ ALOGE ("%s: tag already deactivated", __FUNCTION__);
goto TheEnd;
}
@@ -783,7 +810,7 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da
uint32_t bufLen = 0;
jint *targetLost = NULL;
- if (! NfcTag::getInstance ().isActivated ())
+ if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
{
if (statusTargetLost)
{
@@ -844,7 +871,7 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv *e, jobject o, jbyteArray da
break;
}
- if (! NfcTag::getInstance ().isActivated ())
+ if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
{
ALOGE ("%s: already deactivated", __FUNCTION__);
if (targetLost)
@@ -1036,7 +1063,7 @@ void nativeNfcTag_doCheckNdefResult (tNFA_STATUS status, uint32_t maxSize, uint3
** o: Java object.
** ndefInfo: NDEF info.
**
-** Returns: Status code.
+** Returns: Status code; 0 is success.
**
*******************************************************************************/
static jint nativeNfcTag_doCheckNdef (JNIEnv *e, jobject o, jintArray ndefInfo)
@@ -1053,9 +1080,9 @@ static jint nativeNfcTag_doCheckNdef (JNIEnv *e, jobject o, jintArray ndefInfo)
return JNI_FALSE;
}
- if (NfcTag::getInstance ().isActivated () == false)
+ if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
{
- ALOGE ("%s: tag not present", __FUNCTION__);
+ ALOGE ("%s: tag already deactivated", __FUNCTION__);
goto TheEnd;
}
@@ -1065,7 +1092,7 @@ static jint nativeNfcTag_doCheckNdef (JNIEnv *e, jobject o, jintArray ndefInfo)
if (status != NFA_STATUS_OK)
{
- ALOGE ("%s: NFA_RwDetectNDef failed, status = %d", __FUNCTION__, status);
+ ALOGE ("%s: NFA_RwDetectNDef failed, status = 0x%X", __FUNCTION__, status);
goto TheEnd;
}
@@ -1106,9 +1133,15 @@ static jint nativeNfcTag_doCheckNdef (JNIEnv *e, jobject o, jintArray ndefInfo)
e->ReleaseIntArrayElements (ndefInfo, ndef, 0);
status = NFA_STATUS_FAILED;
}
+ else if (sCheckNdefStatus == NFA_STATUS_TIMEOUT)
+ {
+ pn544InteropStopPolling ();
+ status = sCheckNdefStatus;
+ }
else
{
ALOGD ("%s: unknown status 0x%X", __FUNCTION__, sCheckNdefStatus);
+ status = sCheckNdefStatus;
}
TheEnd:
@@ -1118,7 +1151,7 @@ TheEnd:
ALOGE ("%s: Failed to destroy check NDEF semaphore (errno=0x%08x)", __FUNCTION__, errno);
}
sCheckNdefWaitingForComplete = JNI_FALSE;
- ALOGD ("%s: exit; status=%u", __FUNCTION__, status);
+ ALOGD ("%s: exit; status=0x%X", __FUNCTION__, status);
return status;
}
@@ -1183,7 +1216,7 @@ static jboolean nativeNfcTag_doPresenceCheck (JNIEnv *e, jobject o)
return JNI_FALSE;
}
- if (NfcTag::getInstance ().isActivated () == false)
+ if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
{
ALOGD ("%s: tag already deactivated", __FUNCTION__);
return JNI_FALSE;
diff --git a/nci/jni/NfcTag.cpp b/nci/jni/NfcTag.cpp
index e996fdd..b94355f 100755
--- a/nci/jni/NfcTag.cpp
+++ b/nci/jni/NfcTag.cpp
@@ -37,17 +37,18 @@ extern "C"
*******************************************************************************/
NfcTag::NfcTag ()
: mNativeData (NULL),
- mIsActivated (false),
+ mActivationState (Idle),
mProtocol(NFC_PROTOCOL_UNKNOWN),
mNumTechList (0),
mtT1tMaxMessageSize (0),
- mReadCompletedStatus (NFA_STATUS_OK)
+ mReadCompletedStatus (NFA_STATUS_OK),
+ mLastKovioUidLen (0),
+ mNdefDetectionTimedOut (false)
{
memset (mTechList, 0, sizeof(mTechList));
memset (mTechHandles, 0, sizeof(mTechHandles));
memset (mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
memset (mTechParams, 0, sizeof(mTechParams));
- mLastKovioUidLen = 0;
memset(mLastKovioUid, 0, NFC_KOVIO_MAX_LEN);
}
@@ -81,7 +82,7 @@ NfcTag& NfcTag::getInstance ()
void NfcTag::initialize (nfc_jni_native_data* native)
{
mNativeData = native;
- mIsActivated = false;
+ mActivationState = Idle;
mProtocol = NFC_PROTOCOL_UNKNOWN;
mNumTechList = 0;
mtT1tMaxMessageSize = 0;
@@ -108,16 +109,55 @@ void NfcTag::abort ()
/*******************************************************************************
**
-** Function: isActivated
+** Function: getActivationState
**
-** Description: Is tag activated?
+** Description: What is the current state: Idle, Sleep, or Activated.
**
-** Returns: True if tag is activated.
+** Returns: Idle, Sleep, or Activated.
**
*******************************************************************************/
-bool NfcTag::isActivated ()
+NfcTag::ActivationState NfcTag::getActivationState ()
{
- return mIsActivated;
+ return mActivationState;
+}
+
+
+/*******************************************************************************
+**
+** Function: setDeactivationState
+**
+** Description: Set the current state: Idle or Sleep.
+** deactivated: state of deactivation.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcTag::setDeactivationState (tNFA_DEACTIVATED& deactivated)
+{
+ static const char fn [] = "NfcTag::setDeactivationState";
+ mActivationState = Idle;
+ mNdefDetectionTimedOut = false;
+ if (deactivated.type == NFA_DEACTIVATE_TYPE_SLEEP)
+ mActivationState = Sleep;
+ ALOGD ("%s: state=%u", fn, mActivationState);
+}
+
+
+/*******************************************************************************
+**
+** Function: setActivationState
+**
+** Description: Set the current state to Active.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcTag::setActivationState ()
+{
+ static const char fn [] = "NfcTag::setActivationState";
+ mNdefDetectionTimedOut = false;
+ mActivationState = Active;
+ ALOGD ("%s: state=%u", fn, mActivationState);
}
@@ -1204,6 +1244,21 @@ bool NfcTag::isT2tNackResponse (const UINT8* response, UINT32 responseLen)
/*******************************************************************************
**
+** Function: isNdefDetectionTimedOut
+**
+** Description: Whether NDEF-detection algorithm timed out.
+**
+** Returns: True if NDEF-detection algorithm timed out.
+**
+*******************************************************************************/
+bool NfcTag::isNdefDetectionTimedOut ()
+{
+ return mNdefDetectionTimedOut;
+}
+
+
+/*******************************************************************************
+**
** Function: connectionEventHandler
**
** Description: Handle connection-related events.
@@ -1215,6 +1270,8 @@ bool NfcTag::isT2tNackResponse (const UINT8* response, UINT32 responseLen)
*******************************************************************************/
void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data)
{
+ static const char fn [] = "NfcTag::connectionEventHandler";
+
switch (event)
{
case NFA_DISC_RESULT_EVT:
@@ -1236,7 +1293,6 @@ void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data)
tNFA_ACTIVATED& activated = data->activated;
if (IsSameKovio(activated))
break;
- mIsActivated = true;
mProtocol = activated.activate_ntf.protocol;
calculateT1tMaxMessageSize (activated);
discoverTechnologies (activated);
@@ -1245,7 +1301,6 @@ void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data)
break;
case NFA_DEACTIVATED_EVT:
- mIsActivated = false;
mProtocol = NFC_PROTOCOL_UNKNOWN;
resetTechnologies ();
break;
@@ -1257,6 +1312,14 @@ void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data)
mReadCompleteEvent.notifyOne ();
}
break;
+
+ case NFA_NDEF_DETECT_EVT:
+ {
+ tNFA_NDEF_DETECT& ndef_detect = data->ndef_detect;
+ mNdefDetectionTimedOut = ndef_detect.status == NFA_STATUS_TIMEOUT;
+ if (mNdefDetectionTimedOut)
+ ALOGE ("%s: NDEF detection timed out", fn);
+ }
}
}
diff --git a/nci/jni/NfcTag.h b/nci/jni/NfcTag.h
index 76a6bb7..7fa56ee 100755
--- a/nci/jni/NfcTag.h
+++ b/nci/jni/NfcTag.h
@@ -30,6 +30,7 @@ extern "C"
class NfcTag
{
public:
+ enum ActivationState {Idle, Sleep, Active};
static const int MAX_NUM_TECHNOLOGY = 10; //max number of technologies supported by one or more tags
int mTechList [MAX_NUM_TECHNOLOGY]; //array of NFC technologies according to NFC service
int mTechHandles [MAX_NUM_TECHNOLOGY]; //array of tag handles according to NFC service
@@ -100,18 +101,42 @@ public:
/*******************************************************************************
**
- ** Function: isActivated
+ ** Function: getActivationState
**
- ** Description: Is tag activated?
+ ** Description: What is the current state: Idle, Sleep, or Activated.
**
- ** Returns: True if tag is activated.
+ ** Returns: Idle, Sleep, or Activated.
**
*******************************************************************************/
- bool isActivated ();
+ ActivationState getActivationState ();
/*******************************************************************************
**
+ ** Function: setDeactivationState
+ **
+ ** Description: Set the current state: Idle or Sleep.
+ ** deactivated: state of deactivation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void setDeactivationState (tNFA_DEACTIVATED& deactivated);
+
+
+ /*******************************************************************************
+ **
+ ** Function: setActivationState
+ **
+ ** Description: Set the current state to Active.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void setActivationState ();
+
+ /*******************************************************************************
+ **
** Function: getProtocol
**
** Description: Get the protocol of the current tag.
@@ -197,15 +222,27 @@ public:
*******************************************************************************/
bool isT2tNackResponse (const UINT8* response, UINT32 responseLen);
+ /*******************************************************************************
+ **
+ ** Function: isNdefDetectionTimedOut
+ **
+ ** Description: Whether NDEF-detection algorithm has timed out.
+ **
+ ** Returns: True if NDEF-detection algorithm timed out.
+ **
+ *******************************************************************************/
+ bool isNdefDetectionTimedOut ();
+
private:
nfc_jni_native_data* mNativeData;
- bool mIsActivated;
+ ActivationState mActivationState;
tNFC_PROTOCOL mProtocol;
int mtT1tMaxMessageSize; //T1T max NDEF message size
tNFA_STATUS mReadCompletedStatus;
+ int mLastKovioUidLen; // len of uid of last Kovio tag activated
+ bool mNdefDetectionTimedOut; // whether NDEF detection algorithm timed out
tNFC_RF_TECH_PARAMS mTechParams [MAX_NUM_TECHNOLOGY]; //array of technology parameters
SyncEvent mReadCompleteEvent;
- int mLastKovioUidLen; // len of uid of last Kovio tag activated
struct timespec mLastKovioTime; // time of last Kovio tag activation
UINT8 mLastKovioUid[NFC_KOVIO_MAX_LEN]; // uid of last Kovio tag activated
diff --git a/nci/jni/Pn544Interop.cpp b/nci/jni/Pn544Interop.cpp
new file mode 100644
index 0000000..be92c75
--- /dev/null
+++ b/nci/jni/Pn544Interop.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*****************************************************************************
+**
+** Name: Pn544Interop.cpp
+**
+** Description: Implement operations that provide compatibility with NXP
+** PN544 controller. Specifically facilitate peer-to-peer
+** operations with PN544 controller.
+**
+*****************************************************************************/
+#include "OverrideLog.h"
+#include "Pn544Interop.h"
+#include "IntervalTimer.h"
+#include "Mutex.h"
+#include "NfcTag.h"
+namespace android
+{
+ extern void startStopPolling (bool isStartPolling);
+}
+
+
+/*****************************************************************************
+**
+** private variables and functions
+**
+*****************************************************************************/
+
+
+static const int gIntervalTime = 1000; //millisecond between the check to restore polling
+static IntervalTimer gTimer;
+static Mutex gMutex;
+static void pn544InteropStartPolling (union sigval); //callback function for interval timer
+static bool gIsBusy = false; //is timer busy?
+static bool gAbortNow = false; //stop timer during next callback
+
+
+/*******************************************************************************
+**
+** Function: pn544InteropStopPolling
+**
+** Description: Stop polling to let NXP PN544 controller poll.
+** PN544 should activate in P2P mode.
+**
+** Returns: None
+**
+*******************************************************************************/
+void pn544InteropStopPolling ()
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ gMutex.lock ();
+ gTimer.kill ();
+ android::startStopPolling (false);
+ gIsBusy = true;
+ gAbortNow = false;
+ gTimer.set (gIntervalTime, pn544InteropStartPolling); //after some time, start polling again
+ gMutex.unlock ();
+ ALOGD ("%s: exit", __FUNCTION__);
+}
+
+
+/*******************************************************************************
+**
+** Function: pn544InteropStartPolling
+**
+** Description: Start polling when activation state is idle.
+** sigval: Unused.
+**
+** Returns: None
+**
+*******************************************************************************/
+void pn544InteropStartPolling (union sigval)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ gMutex.lock ();
+ NfcTag::ActivationState state = NfcTag::getInstance ().getActivationState ();
+
+ if (gAbortNow)
+ {
+ ALOGD ("%s: abort now", __FUNCTION__);
+ gIsBusy = false;
+ goto TheEnd;
+ }
+
+ if (state == NfcTag::Idle)
+ {
+ ALOGD ("%s: start polling", __FUNCTION__);
+ android::startStopPolling (true);
+ gIsBusy = false;
+ }
+ else
+ {
+ ALOGD ("%s: try again later", __FUNCTION__);
+ gTimer.set (gIntervalTime, pn544InteropStartPolling); //after some time, start polling again
+ }
+
+TheEnd:
+ gMutex.unlock ();
+ ALOGD ("%s: exit", __FUNCTION__);
+}
+
+
+/*******************************************************************************
+**
+** Function: pn544InteropIsBusy
+**
+** Description: Is the code performing operations?
+**
+** Returns: True if the code is busy.
+**
+*******************************************************************************/
+bool pn544InteropIsBusy ()
+{
+ bool isBusy = false;
+ gMutex.lock ();
+ isBusy = gIsBusy;
+ gMutex.unlock ();
+ ALOGD ("%s: %u", __FUNCTION__, isBusy);
+ return isBusy;
+}
+
+
+/*******************************************************************************
+**
+** Function: pn544InteropAbortNow
+**
+** Description: Request to abort all operations.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void pn544InteropAbortNow ()
+{
+ ALOGD ("%s", __FUNCTION__);
+ gMutex.lock ();
+ gAbortNow = true;
+ gMutex.unlock ();
+}
+
diff --git a/nci/jni/Pn544Interop.h b/nci/jni/Pn544Interop.h
new file mode 100644
index 0000000..c9a2df6
--- /dev/null
+++ b/nci/jni/Pn544Interop.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*****************************************************************************
+**
+** Name: Pn544Interop.h
+**
+** Description: Implement operations that provide compatibility with NXP
+** PN544 controller. Specifically facilitate peer-to-peer
+** operations with PN544 controller.
+**
+*****************************************************************************/
+#pragma once
+#include "NfcJniUtil.h"
+
+
+/*******************************************************************************
+**
+** Function: pn544InteropStopPolling
+**
+** Description: Stop polling to let NXP PN544 controller poll.
+** PN544 should activate in P2P mode.
+**
+** Returns: None
+**
+*******************************************************************************/
+void pn544InteropStopPolling ();
+
+
+/*******************************************************************************
+**
+** Function: pn544InteropIsBusy
+**
+** Description: Is the code performing operations?
+**
+** Returns: True if the code is busy.
+**
+*******************************************************************************/
+bool pn544InteropIsBusy ();
+
+
+/*******************************************************************************
+**
+** Function: pn544InteropAbortNow
+**
+** Description: Request to abort all operations.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void pn544InteropAbortNow ();
diff --git a/nci/jni/SecureElement.cpp b/nci/jni/SecureElement.cpp
index b67ee66..2f94047 100755
--- a/nci/jni/SecureElement.cpp
+++ b/nci/jni/SecureElement.cpp
@@ -70,7 +70,9 @@ SecureElement::SecureElement ()
mCommandStatus (NFA_STATUS_OK),
mIsPiping (false),
mCurrentRouteSelection (NoRoute),
- mActualResponseSize(0)
+ mActualResponseSize(0),
+ mUseOberthurWarmReset (false),
+ mOberthurWarmResetCommand (3)
{
memset (&mEeInfo, 0, sizeof(mEeInfo));
memset (&mUiccInfo, 0, sizeof(mUiccInfo));
@@ -153,6 +155,12 @@ bool SecureElement::initialize (nfc_jni_native_data* native)
mActiveSeOverride = num;
ALOGD ("%s: Active SE override: %d", fn, mActiveSeOverride);
+ if (GetNumValue("OBERTHUR_WARM_RESET_COMMAND", &num, sizeof(num)))
+ {
+ mUseOberthurWarmReset = true;
+ mOberthurWarmResetCommand = (UINT8) num;
+ }
+
mActiveEeHandle = NFA_HANDLE_INVALID;
mNfaHciHandle = NFA_HANDLE_INVALID;
@@ -777,6 +785,21 @@ bool SecureElement::disconnectEE (jint seID)
ALOGD("%s: seID=0x%X; handle=0x%04x", fn, seID, eeHandle);
+ if (mUseOberthurWarmReset)
+ {
+ //send warm-reset command to Oberthur secure element which deselects the applet;
+ //this is an Oberthur-specific command;
+ ALOGD("%s: try warm-reset on pipe id 0x%X; cmd=0x%X", fn, mNewPipeId, mOberthurWarmResetCommand);
+ SyncEventGuard guard (mRegistryEvent);
+ nfaStat = NFA_HciSetRegistry (mNfaHciHandle, mNewPipeId,
+ 1, 1, &mOberthurWarmResetCommand);
+ if (nfaStat == NFA_STATUS_OK)
+ {
+ mRegistryEvent.wait ();
+ ALOGD("%s: completed warm-reset on pipe 0x%X", fn, mNewPipeId);
+ }
+ }
+
if (mNewSourceGate)
{
SyncEventGuard guard (mDeallocateGateEvent);
@@ -1718,6 +1741,15 @@ void SecureElement::nfaHciCallback (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* event
}
break;
+ case NFA_HCI_SET_REG_RSP_EVT: //received response to write registry command
+ {
+ tNFA_HCI_REGISTRY& registry = eventData->registry;
+ ALOGD ("%s: NFA_HCI_SET_REG_RSP_EVT; status=0x%X; pipe=0x%X", fn, registry.status, registry.pipe);
+ SyncEventGuard guard (sSecElem.mRegistryEvent);
+ sSecElem.mRegistryEvent.notifyOne ();
+ break;
+ }
+
default:
ALOGE ("%s: unknown event code=0x%X ????", fn, event);
break;
diff --git a/nci/jni/SecureElement.h b/nci/jni/SecureElement.h
index b887513..6a5cebd 100755
--- a/nci/jni/SecureElement.h
+++ b/nci/jni/SecureElement.h
@@ -372,6 +372,8 @@ private:
bool mIsPiping; //is a pipe connected to the controller?
RouteSelection mCurrentRouteSelection;
int mActualResponseSize; //number of bytes in the response received from secure element
+ bool mUseOberthurWarmReset; //whether to use warm-reset command
+ UINT8 mOberthurWarmResetCommand; //warm-reset command byte
tNFA_EE_INFO mEeInfo [MAX_NUM_EE]; //actual size stored in mActualNumEe
tNFA_EE_DISCOVER_REQ mUiccInfo;
tNFA_HCI_GET_GATE_PIPE_LIST mHciCfg;
@@ -389,6 +391,7 @@ private:
SyncEvent mAidAddRemoveEvent;
SyncEvent mTransceiveEvent;
SyncEvent mVerInfoEvent;
+ SyncEvent mRegistryEvent;
UINT8 mVerInfo [3];
UINT8 mResponseData [MAX_RESPONSE_SIZE];
RouteDataSet mRouteDataSet; //routing data