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; }
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; }
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; }
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; }
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; }
/******************************************************************************* ** ** 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; }