INT32 nativeNfcLlcp_ConnLessReceiveMessage(UINT8* msg, UINT32 *length)
 {
        NXPLOG_API_D ("%s: enter\n", __FUNCTION__);
        if(msg == NULL || length == NULL){
            NXPLOG_API_E ("%s: Invalid buffer or length", __FUNCTION__);
            return NFA_STATUS_FAILED;
        }

        NXPLOG_API_D("nfaLlcpServerCallBack: remote sap ID 0x%04x\n ", bDestSap);
        if( (bServerReadState == FALSE) && (bClientReadState == FALSE) )
        {
            sNfaLlcpConnLessReadEvent.wait();
        }

        if(NFA_STATUS_OK != NFA_P2pReadUI ((size_t)sLlcpConnLessHandle,
                     LLCP_MAX_DATA_SIZE,
                     &bDestSap,
                     &dwLlcpReadLength,
                     &bLlcpReadData[0],
                     &blMoreDataRemaining))
        {
            NXPLOG_API_D ("%s: send response failed.", __FUNCTION__);
            return NFA_STATUS_FAILED;
        }
        else
        {
            memcpy(msg,bLlcpReadData, dwLlcpReadLength);
            *length = dwLlcpReadLength;
            NXPLOG_API_D ("%s: exit\n", __FUNCTION__);
            bServerReadState = FALSE;
            bClientReadState = FALSE;
            return NFA_STATUS_OK;
        }

 }
/*******************************************************************************
**
** Function:        nativeNfcTag_doRead
**
** Description:     Read the NDEF message on the tag.
**                  e: JVM environment.
**                  o: Java object.
**
** Returns:         NDEF message.
**
*******************************************************************************/
static jbyteArray nativeNfcTag_doRead (JNIEnv* e, jobject)
{
    ALOGD ("%s: enter", __FUNCTION__);
    tNFA_STATUS status = NFA_STATUS_FAILED;
    jbyteArray buf = NULL;

    sReadDataLen = 0;
    if (sReadData != NULL)
    {
        free (sReadData);
        sReadData = NULL;
    }

    if (sCheckNdefCurrentSize > 0)
    {
        {
            SyncEventGuard g (sReadEvent);
            sIsReadingNdefMessage = true;
            status = NFA_RwReadNDef ();
            sReadEvent.wait (); //wait for NFA_READ_CPLT_EVT
        }
        sIsReadingNdefMessage = false;

        if (sReadDataLen > 0) //if stack actually read data from the tag
        {
            ALOGD ("%s: read %u bytes", __FUNCTION__, sReadDataLen);
            buf = e->NewByteArray (sReadDataLen);
            e->SetByteArrayRegion (buf, 0, sReadDataLen, (jbyte*) sReadData);
        }
    }
    else
    {
        ALOGD ("%s: create empty buffer", __FUNCTION__);
        sReadDataLen = 0;
        sReadData = (uint8_t*) malloc (1);
        buf = e->NewByteArray (sReadDataLen);
        e->SetByteArrayRegion (buf, 0, sReadDataLen, (jbyte*) sReadData);
    }

    if (sReadData)
    {
        free (sReadData);
        sReadData = NULL;
    }
    sReadDataLen = 0;

    ALOGD ("%s: exit", __FUNCTION__);
    return buf;
}
INT32 nativeNfcLlcp_ConnLessRegisterClientCallback(nfcllcpConnlessClientCallback_t *clientCallback)
{
    tNFA_STATUS status = NFA_STATUS_FAILED;
    pthread_t llcpCleintRespThread;
    int ret = 1;
    NXPLOG_API_D ("%s:", __FUNCTION__);

    gSyncMutex.lock();
    if (!nativeNfcManager_isNfcActive())
    {
        NXPLOG_API_E ("%s: Nfc not initialized.", __FUNCTION__);
        gSyncMutex.unlock();
        return NFA_STATUS_FAILED;
    }

    sRfEnabled = isDiscoveryStarted();
    if (sRfEnabled)
    {
        /* Stop RF Discovery if we were polling */
        startRfDiscovery (FALSE);
    }

    {
        SyncEventGuard g (sNfaLlcpClientRegEvent);
        bClientReadState = FALSE;
        if(NFA_STATUS_OK != (status = NFA_P2pRegisterClient(NFA_P2P_LLINK_TYPE, nfaLlcpClientCallback)))
        {
            NXPLOG_API_E ("%s: fail to register client callback for LLCP", __FUNCTION__);
            if (sRfEnabled)
            {
                /*  Rollback to default */
                startRfDiscovery (TRUE);
                gSyncMutex.unlock();
                return status;
            }

        }
        sNfaLlcpClientRegEvent.wait();
    }

    sClientCallback = clientCallback;
    status = NFA_STATUS_OK;

    gSyncMutex.unlock();
    return status;
}
Exemplo n.º 4
0
static void *snepServerThread(void *arg)
{
    (void)arg;
    SyncEventGuard guard (sNfaSnepServerPutRspEvent);

    NXPLOG_API_D ("%s: enter\n", __FUNCTION__);
    while(sSnepServerState == SNEP_SERVER_STARTED)
    {
        sNfaSnepServerPutRspEvent.wait();
        if (sSnepServerConnectionHandle == 0)
            break;
        if(NFA_STATUS_OK != NFA_SnepPutResponse(sSnepServerConnectionHandle, sNfaSnepRespCode))
        {
            NXPLOG_API_D ("%s: send response failed.", __FUNCTION__);
        }
    }
    NXPLOG_API_D ("%s: exit\n", __FUNCTION__);
    pthread_exit(NULL);
    return NULL;
}
Exemplo n.º 5
0
INT32 nativeNfcSnep_registerClientCallback(nfcSnepClientCallback_t *clientCallback)
{
    tNFA_STATUS status = NFA_STATUS_FAILED;
    NXPLOG_API_D ("%s:", __FUNCTION__);
    gSyncMutex.lock();
    if (!nativeNfcManager_isNfcActive())
    {
        NXPLOG_API_E ("%s: Nfc not initialized.", __FUNCTION__);
        gSyncMutex.unlock();
        return NFA_STATUS_FAILED;
    }
    sRfEnabled = isDiscoveryStarted();
    if (sRfEnabled)
    {
        // Stop RF Discovery if we were polling
        startRfDiscovery (FALSE);
    }
    {
        SyncEventGuard g (sNfaSnepClientRegEvent);
        if(NFA_STATUS_OK != (status = NFA_SnepRegisterClient(nfaSnepClientCallback)))
        {
            NXPLOG_API_E ("%s: fail to register client callback for SNEP", __FUNCTION__);
            goto clean_and_return;
        }
        sNfaSnepClientRegEvent.wait();
    }
    sClientCallback = clientCallback;
    status = NFA_STATUS_OK;
clean_and_return:
    if (sRfEnabled)
    {
        // Stop RF Discovery if we were polling
        startRfDiscovery (TRUE);
    }
    gSyncMutex.unlock();
    return status;
}
Exemplo n.º 6
0
INT32 nativeNfcSnep_putMessage(UINT8* msg, UINT32 length)
{
    tNFA_STATUS status = NFA_STATUS_FAILED;
    NXPLOG_API_D ("%s: data length = %d", __FUNCTION__, length);

    if (!sSnepClientHandle)
    {
        NXPLOG_API_E ("%s: no connection", __FUNCTION__);
        return NFA_STATUS_FAILED;
    }
    if (!msg || length == 0)
    {
        NXPLOG_API_E ("%s: wrong param", __FUNCTION__);
        return NFA_STATUS_FAILED;
    }
    if(NFA_STATUS_OK != NDEF_MsgValidate(msg, length, FALSE))
    {
        NXPLOG_API_E ("%s: not NDEF message", __FUNCTION__);
        return NFA_STATUS_FAILED;
    }
    gSyncMutex.lock();
    if (!nativeNfcManager_isNfcActive())
    {
        NXPLOG_API_E ("%s: Nfc not initialized.", __FUNCTION__);
        status = NFA_STATUS_FAILED;
        goto clean_and_return;
    }
    if (sSnepClientHandle){
        SyncEventGuard guard (sNfaSnepClientConnEvent);
        if(NFA_STATUS_OK != NFA_SnepConnect(sSnepClientHandle, SNEP_SERVER_NAME))
        {
            status = NFA_STATUS_FAILED;
            goto clean_and_return;
        }
        sNfaSnepClientConnEvent.wait();
    }

    /* Send Put Request */
    if (sSnepClientConnectionHandle != 0)
    {
        SyncEventGuard guard (sNfaSnepClientPutMsgEvent);
        if(NFA_STATUS_OK != NFA_SnepPut (sSnepClientConnectionHandle, length, msg))
        {
            status = NFA_STATUS_FAILED;
            goto clean_and_return;
        }
        sNfaSnepClientPutMsgEvent.wait();
        if (sSnepClientPutState != NFA_STATUS_OK)
        {
            status = NFA_STATUS_FAILED;
        }
        else
        {
            status = NFA_STATUS_OK;
            sSnepClientPutState = NFA_STATUS_FAILED;
        }
    }
    /* Disconnect from Snep Server */
    if (sSnepClientConnectionHandle != 0)
    {
        SyncEventGuard guard (sNfaSnepClientDisconnEvent);
        if(NFA_STATUS_OK != NFA_SnepDisconnect (sSnepClientConnectionHandle, 0x01))
        {
            status = NFA_STATUS_FAILED;
            goto clean_and_return;
        }
        sNfaSnepClientDisconnEvent.wait();
    }
clean_and_return:
    NXPLOG_API_D ("%s: return = %d", __FUNCTION__, status);
    gSyncMutex.unlock();
    return status;
}
Exemplo n.º 7
0
INT32 nativeNfcSnep_startServer(nfcSnepServerCallback_t *serverCallback)
{
    tNFA_STATUS status = NFA_STATUS_OK;
    int ret;
    pthread_t snepRespThread;

    NXPLOG_API_D ("%s:", __FUNCTION__);
    if (serverCallback == NULL)
    {
        NXPLOG_API_E ("%s: callback is NULL!", __FUNCTION__);
        return NFA_STATUS_FAILED;
    }

    gSyncMutex.lock();
    if (!nativeNfcManager_isNfcActive())
    {
        NXPLOG_API_E ("%s: Nfc not initialized.", __FUNCTION__);
        gSyncMutex.unlock();
        return NFA_STATUS_FAILED;
    }

    if (sSnepServerState == SNEP_SERVER_STARTED && serverCallback == sServerCallback)
    {
        NXPLOG_API_D ("%s: alread started!", __FUNCTION__);
        gSyncMutex.unlock();
        return NFA_STATUS_OK;
    }
    if (sSnepServerState != SNEP_SERVER_IDLE)
    {
        NXPLOG_API_E ("%s: Server is started or busy. State = 0x%X", __FUNCTION__, sSnepServerState);
        gSyncMutex.unlock();
        return NFA_STATUS_FAILED;
    }

    sServerCallback = serverCallback;
    sSnepServerState = SNEP_SERVER_STARTING;

    sRfEnabled = isDiscoveryStarted();
    if (sRfEnabled)
    {
        // Stop RF Discovery if we were polling
        startRfDiscovery (FALSE);
    }
    {
        SyncEventGuard guard (sNfaSnepServerRegEvent);
        if(NFA_STATUS_OK != NFA_SnepRegisterServer(0x04, SNEP_SERVER_NAME, nfaSnepServerCallback))
        {
            status = NFA_STATUS_FAILED;
            sSnepServerState = SNEP_SERVER_IDLE;
            sServerCallback = NULL;
            goto clean_and_return;
        }
        sNfaSnepServerRegEvent.wait();
    }
    ret = pthread_create(&snepRespThread, NULL, snepServerThread, NULL);
    if(ret != 0)
    {
        NXPLOG_API_E("Unable to create snep server thread");
        sSnepServerState = SNEP_SERVER_IDLE;
        NFA_SnepDeregister(sSnepServerHandle);
        sServerCallback = NULL;
        status = NFA_STATUS_FAILED;
        goto clean_and_return;
    }

    sSnepServerState = SNEP_SERVER_STARTED;
clean_and_return:
    if (sRfEnabled)
    {
        startRfDiscovery (TRUE);
    }
    gSyncMutex.unlock();
    return status;
}
INT32 nativeNfcLlcp_ConnLessStartServer(nfcllcpConnlessServerCallback_t *serverCallback)
 {
    tNFA_STATUS status = NFA_STATUS_OK;
    int ret;
    pthread_t llcpRespThread;
    bServerReadState = FALSE;
    NXPLOG_API_D ("%s:", __FUNCTION__);
    if (serverCallback == NULL)
    {
        NXPLOG_API_E ("%s: callback is NULL!", __FUNCTION__);
        return NFA_STATUS_FAILED;
    }
    gSyncMutex.lock();
    if (!nativeNfcManager_isNfcActive())
    {
        NXPLOG_API_E ("%s: Nfc not initialized.", __FUNCTION__);
        gSyncMutex.unlock();
        return NFA_STATUS_FAILED;
    }
    if (sLlcpServerState == LLCP_SERVER_STARTED && serverCallback == sServerCallback)
    {
        NXPLOG_API_D ("%s: alread started!", __FUNCTION__);
        gSyncMutex.unlock();
        return NFA_STATUS_OK;
    }
    if (sLlcpServerState != LLCP_SERVER_IDLE)
    {
        NXPLOG_API_E ("%s: Server is started or busy. State = 0x%X", __FUNCTION__, sLlcpServerState);
        gSyncMutex.unlock();
        return NFA_STATUS_FAILED;
    }
    sServerCallback = serverCallback;
    sLlcpServerState = LLCP_SERVER_STARTING;
    sRfEnabled = isDiscoveryStarted();
    if (sRfEnabled)
    {
        /* Stop RF Discovery if we were polling */
        startRfDiscovery (FALSE);
    }
    SyncEventGuard guard (sNfaLlcpServerRegEvent);
    if(NFA_STATUS_OK != NFA_P2pRegisterServer ( LLCP_CL_SAP_ID_DEFAULT,
                                    NFA_P2P_LLINK_TYPE,
                                    (char *)LLCP_SERVER_NAME,
                                    nfaLlcpServerCallBack))
    {
        status = NFA_STATUS_FAILED;
        sLlcpServerState = LLCP_SERVER_IDLE;
        sServerCallback = NULL;
        if (sRfEnabled)
        {
            /*  Rollback to default */
            startRfDiscovery (TRUE);
            gSyncMutex.unlock();
            return status;
        }
    }
    sNfaLlcpServerRegEvent.wait();

    gSyncMutex.unlock();
    return status;


 }
Exemplo n.º 9
0
/*******************************************************************************
**
** Function:        setLevel
**
** Description:     Set the controller's power level.
**                  level: power level.
**
** Returns:         True if ok.
**
*******************************************************************************/
bool PowerSwitch::setLevel (PowerLevel newLevel)
{
    static const char fn [] = "PowerSwitch::setLevel";
    bool retval = false;

    mMutex.lock ();

    ALOGD ("%s: level=%s (%u)", fn, powerLevelToString(newLevel), newLevel);
    if (mCurrLevel == newLevel)
    {
        retval = true;
        goto TheEnd;
    }

    if (mCurrLevel == UNKNOWN_LEVEL)
    {
        ALOGE ("%s: unknown power level", fn);
        goto TheEnd;
    }

    if ( (mCurrLevel == LOW_POWER && newLevel == FULL_POWER) ||
         (mCurrLevel == FULL_POWER && newLevel == LOW_POWER) )
    {
        mMutex.unlock ();
        SyncEventGuard g (gDeactivatedEvent);
        if (gActivated)
        {
            ALOGD("%s: wait for deactivation", fn);
            gDeactivatedEvent.wait ();
        }
        mMutex.lock ();
    }

    switch (newLevel)
    {
    case FULL_POWER:
        if (mCurrDeviceMgtPowerState == NFA_DM_PWR_MODE_OFF_SLEEP)
            retval = setPowerOffSleepState (false);
        break;

    case LOW_POWER:
    case POWER_OFF:
        if (isPowerOffSleepFeatureEnabled())
            retval = setPowerOffSleepState (true);
        else if (mDesiredScreenOffPowerState == 1) //.conf file desires full-power
        {
            mCurrLevel = FULL_POWER;
            retval = true;
        }
        break;

    default:
        ALOGE ("%s: not handled", fn);
        break;
    }

    ALOGD("%s: actual power level=%s", fn, powerLevelToString(mCurrLevel));

TheEnd:
    mMutex.unlock ();
    return retval;
}
/*******************************************************************************
**
** Function:        nativeNfcTag_doTransceive
**
** Description:     Send raw data to the tag; receive tag's response.
**                  e: JVM environment.
**                  o: Java object.
**                  raw: Not used.
**                  statusTargetLost: Whether tag responds or times out.
**
** Returns:         Response from tag.
**
*******************************************************************************/
static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject, jbyteArray data, jboolean raw, jintArray statusTargetLost)
{
    int timeout = NfcTag::getInstance ().getTransceiveTimeout (sCurrentConnectedTargetType);
    ALOGD ("%s: enter; raw=%u; timeout = %d", __FUNCTION__, raw, timeout);
    bool waitOk = false;
    bool isNack = false;
    jint *targetLost = NULL;

    if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
    {
        if (statusTargetLost)
        {
            targetLost = e->GetIntArrayElements (statusTargetLost, 0);
            if (targetLost)
                *targetLost = 1; //causes NFC service to throw TagLostException
            e->ReleaseIntArrayElements (statusTargetLost, targetLost, 0);
        }
        ALOGD ("%s: tag not active", __FUNCTION__);
        return NULL;
    }

    NfcTag& natTag = NfcTag::getInstance ();

    // get input buffer and length from java call
    ScopedByteArrayRO bytes(e, data);
    uint8_t* buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); // TODO: API bug; NFA_SendRawFrame should take const*!
    size_t bufLen = bytes.size();

    if (statusTargetLost)
    {
        targetLost = e->GetIntArrayElements (statusTargetLost, 0);
        if (targetLost)
            *targetLost = 0; //success, tag is still present
    }

    sSwitchBackTimer.kill ();
    ScopedLocalRef<jbyteArray> result(e, NULL);
    do
    {
        {
            SyncEventGuard g (sTransceiveEvent);
            sTransceiveRfTimeout = false;
            sWaitingForTransceive = true;
            sRxDataStatus = NFA_STATUS_OK;
            sRxDataBuffer.clear ();
            tNFA_STATUS status = NFA_SendRawFrame (buf, bufLen,
                    NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY);
            if (status != NFA_STATUS_OK)
            {
                ALOGE ("%s: fail send; error=%d", __FUNCTION__, status);
                break;
            }
            waitOk = sTransceiveEvent.wait (timeout);
        }

        if (waitOk == false || sTransceiveRfTimeout) //if timeout occurred
        {
            ALOGE ("%s: wait response timeout", __FUNCTION__);
            if (targetLost)
                *targetLost = 1; //causes NFC service to throw TagLostException
            break;
        }

        if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
        {
            ALOGE ("%s: already deactivated", __FUNCTION__);
            if (targetLost)
                *targetLost = 1; //causes NFC service to throw TagLostException
            break;
        }

        ALOGD ("%s: response %d bytes", __FUNCTION__, sRxDataBuffer.size());

        if ((natTag.getProtocol () == NFA_PROTOCOL_T2T) &&
            natTag.isT2tNackResponse (sRxDataBuffer.data(), sRxDataBuffer.size()))
        {
            isNack = true;
        }

        if (sRxDataBuffer.size() > 0)
        {
            if (isNack)
            {
                //Some Mifare Ultralight C tags enter the HALT state after it
                //responds with a NACK.  Need to perform a "reconnect" operation
                //to wake it.
                ALOGD ("%s: try reconnect", __FUNCTION__);
                nativeNfcTag_doReconnect (NULL, NULL);
                ALOGD ("%s: reconnect finish", __FUNCTION__);
            }
            else
            {
                // marshall data to java for return
                result.reset(e->NewByteArray(sRxDataBuffer.size()));
                if (result.get() != NULL)
                {
                    e->SetByteArrayRegion(result.get(), 0, sRxDataBuffer.size(), (const jbyte *) sRxDataBuffer.data());
                }
                else
                    ALOGE ("%s: Failed to allocate java byte array", __FUNCTION__);
            } // else a nack is treated as a transceive failure to the upper layers

            sRxDataBuffer.clear();
        }
    } while (0);

    sWaitingForTransceive = false;
    if (targetLost)
        e->ReleaseIntArrayElements (statusTargetLost, targetLost, 0);

    ALOGD ("%s: exit", __FUNCTION__);
    return result.release();
}
/*******************************************************************************
**
** Function:        reSelect
**
** Description:     Deactivates the tag and re-selects it with the specified
**                  rf interface.
**
** Returns:         status code, 0 on success, 1 on failure,
**                  146 (defined in service) on tag lost
**
*******************************************************************************/
static int reSelect (tNFA_INTF_TYPE rfInterface, bool fSwitchIfNeeded)
{
    ALOGD ("%s: enter; rf intf = %d, current intf = %d", __FUNCTION__, rfInterface, sCurrentRfInterface);

    sRfInterfaceMutex.lock ();

    if (fSwitchIfNeeded && (rfInterface == sCurrentRfInterface))
    {
        // already in the requested interface
        sRfInterfaceMutex.unlock ();
        return 0;   // success
    }

    NfcTag& natTag = NfcTag::getInstance ();

    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;
            ALOGD ("%s: deactivate to sleep", __FUNCTION__);
            if (NFA_STATUS_OK != (status = NFA_Deactivate (TRUE))) //deactivate to sleep state
            {
                ALOGE ("%s: deactivate failed, status = %d", __FUNCTION__, status);
                break;
            }

            if (sReconnectEvent.wait (1000) == false) //if timeout occurred
            {
                ALOGE ("%s: timeout waiting for deactivate", __FUNCTION__);
            }
        }

        if (!sGotDeactivate)
        {
            rVal = STATUS_CODE_TARGET_LOST;
            break;
        }

        if (NfcTag::getInstance ().getActivationState () != NfcTag::Sleep)
        {
            ALOGE ("%s: tag is not in sleep", __FUNCTION__);
            rVal = STATUS_CODE_TARGET_LOST;
            break;
        }

        gIsTagDeactivating = false;

        {
            SyncEventGuard g2 (sReconnectEvent);

            sConnectWaitingForComplete = JNI_TRUE;
            ALOGD ("%s: select interface %u", __FUNCTION__, rfInterface);
            gIsSelectingRfInterface = true;
            if (NFA_STATUS_OK != (status = NFA_Select (natTag.mTechHandles[0], natTag.mTechLibNfcTypes[0], rfInterface)))
            {
                ALOGE ("%s: NFA_Select failed, status = %d", __FUNCTION__, status);
                break;
            }

            sConnectOk = false;
            if (sReconnectEvent.wait (1000) == false) //if timeout occured
            {
                ALOGE ("%s: timeout waiting for select", __FUNCTION__);
                break;
            }
        }

        ALOGD("%s: select completed; sConnectOk=%d", __FUNCTION__, sConnectOk);
        if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
        {
            ALOGE("%s: tag is not active", __FUNCTION__);
            rVal = STATUS_CODE_TARGET_LOST;
            break;
        }
        if (sConnectOk)
        {
            rVal = 0;   // success
            sCurrentRfInterface = rfInterface;
        }
        else
        {
            rVal = 1;
        }
    } while (0);

    sConnectWaitingForComplete = JNI_FALSE;
    gIsTagDeactivating = false;
    gIsSelectingRfInterface = false;
    sRfInterfaceMutex.unlock ();
    ALOGD ("%s: exit; status=%d", __FUNCTION__, rVal);
    return rVal;
}
/*******************************************************************************
**
** Function:        nativeNfcTag_doPresenceCheck
**
** Description:     Check if the tag is in the RF field.
**                  e: JVM environment.
**                  o: Java object.
**
** Returns:         True if tag is in RF field.
**
*******************************************************************************/
static jboolean nativeNfcTag_doPresenceCheck (JNIEnv*, jobject)
{
    ALOGD ("%s", __FUNCTION__);
    tNFA_STATUS status = NFA_STATUS_OK;
    jboolean isPresent = JNI_FALSE;

    // Special case for Kovio.  The deactivation would have already occurred
    // but was ignored so that normal tag opertions could complete.  Now we
    // want to process as if the deactivate just happened.
    if (NfcTag::getInstance ().mTechList [0] == TARGET_TYPE_KOVIO_BARCODE)
    {
        ALOGD ("%s: Kovio, force deactivate handling", __FUNCTION__);
        tNFA_DEACTIVATED deactivated = {NFA_DEACTIVATE_TYPE_IDLE};
        {
            SyncEventGuard g (gDeactivatedEvent);
            gActivated = false; //guard this variable from multi-threaded access
            gDeactivatedEvent.notifyOne ();
        }

        NfcTag::getInstance().setDeactivationState (deactivated);
        nativeNfcTag_resetPresenceCheck();
        NfcTag::getInstance().connectionEventHandler (NFA_DEACTIVATED_EVT, NULL);
        nativeNfcTag_abortWaits();
        NfcTag::getInstance().abort ();

        return JNI_FALSE;
    }

    if (nfcManager_isNfcActive() == false)
    {
        ALOGD ("%s: NFC is no longer active.", __FUNCTION__);
        return JNI_FALSE;
    }

    if (!sRfInterfaceMutex.tryLock())
    {
        ALOGD ("%s: tag is being reSelected assume it is present", __FUNCTION__);
        return JNI_TRUE;
    }

    sRfInterfaceMutex.unlock();

    if (NfcTag::getInstance ().isActivated () == false)
    {
        ALOGD ("%s: tag already deactivated", __FUNCTION__);
        return JNI_FALSE;
    }

    {
        SyncEventGuard guard (sPresenceCheckEvent);
        status = NFA_RwPresenceCheck (NfcTag::getInstance().getPresenceCheckAlgorithm());
        if (status == NFA_STATUS_OK)
        {
            sPresenceCheckEvent.wait ();
            isPresent = sIsTagPresent ? JNI_TRUE : JNI_FALSE;
        }
    }

    if (isPresent == JNI_FALSE)
        ALOGD ("%s: tag absent", __FUNCTION__);
    return isPresent;
}