diff options
author | Jizhou Liao <Jizhou.Liao@nxp.com> | 2015-08-31 07:24:05 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-08-31 07:24:05 +0000 |
commit | 39f4cd0a6b18c777a45776975e0401af0ad677da (patch) | |
tree | d2d19650df2d4a4a988ae622a4d335bc89228a97 | |
parent | aea1b9246ac749aba111785b49a12799a29abc35 (diff) | |
parent | 8c9730a81c73870882b4eb33aba95455b51131fb (diff) | |
download | android_packages_apps_Nfc-39f4cd0a6b18c777a45776975e0401af0ad677da.tar.gz android_packages_apps_Nfc-39f4cd0a6b18c777a45776975e0401af0ad677da.tar.bz2 android_packages_apps_Nfc-39f4cd0a6b18c777a45776975e0401af0ad677da.zip |
am 8c9730a8: am 8605731e: Support Mifare Classic tag.
* commit '8c9730a81c73870882b4eb33aba95455b51131fb':
Support Mifare Classic tag.
28 files changed, 15050 insertions, 44 deletions
diff --git a/nci/jni/Android.mk b/nci/jni/Android.mk index ed4d3c4e..4f395069 100644 --- a/nci/jni/Android.mk +++ b/nci/jni/Android.mk @@ -4,6 +4,8 @@ NFC := $(VOB_COMPONENTS)/nfc LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +include $(call all-makefiles-under,$(LOCAL_PATH)) + LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk @@ -20,7 +22,7 @@ $(patsubst ./%,%, \ ) endef -LOCAL_SRC_FILES:= $(call all-cpp-files-under, .) +LOCAL_SRC_FILES = $(call all-cpp-files-under, .) $(call all-c-files-under, .) LOCAL_C_INCLUDES += \ external/libxml2/include \ diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp index fbf3cd2f..bf9be831 100755 --- a/nci/jni/NativeNfcManager.cpp +++ b/nci/jni/NativeNfcManager.cpp @@ -39,6 +39,7 @@ extern "C" #include "nfa_ee_api.h" #include "nfc_brcm_defs.h" #include "ce_api.h" + #include "phNxpExtns.h" } extern const UINT8 nfca_version_string []; @@ -59,6 +60,7 @@ namespace android extern void nativeNfcTag_formatStatus (bool is_ok); extern void nativeNfcTag_resetPresenceCheck (); extern void nativeNfcTag_doReadCompleted (tNFA_STATUS status); + extern void nativeNfcTag_setRfInterface (tNFA_INTF_TYPE rfInterface); extern void nativeNfcTag_abortWaits (); extern void nativeLlcpConnectionlessSocket_abortWait (); extern void nativeNfcTag_registerNdefTypeHandler (); @@ -297,6 +299,16 @@ 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, sIsDisabling=%d", __FUNCTION__, gIsSelectingRfInterface, sIsDisabling); + if((eventData->activated.activate_ntf.protocol != NFA_PROTOCOL_NFC_DEP) && (!isListenMode (eventData->activated))) + { + nativeNfcTag_setRfInterface ((tNFA_INTF_TYPE) eventData->activated.activate_ntf.intf_param.type); + } + if (EXTNS_GetConnectFlag () == TRUE) + { + NfcTag::getInstance().setActivationState (); + nativeNfcTag_doConnectStatus (true); + break; + } NfcTag::getInstance().setActive(true); if (sIsDisabling || !sIsNfaEnabled) break; @@ -362,8 +374,13 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat } else if (gIsTagDeactivating) { - NfcTag::getInstance().setActive(false); - nativeNfcTag_doDeactivateStatus(0); + NfcTag::getInstance ().setActive (false); + nativeNfcTag_doDeactivateStatus (0); + } + else if (EXTNS_GetDeactivateFlag () == TRUE) + { + NfcTag::getInstance().setActive (false); + nativeNfcTag_doDeactivateStatus (0); } // If RF is activated for what we think is a Secure Element transaction @@ -706,6 +723,7 @@ void nfaDeviceManagementCallback (UINT8 dmEvent, tNFA_DM_CBACK_DATA* eventData) if (!sIsDisabling && sIsNfaEnabled) { + EXTNS_Close (); NFA_Disable(FALSE); sIsDisabling = true; } @@ -861,6 +879,7 @@ static jboolean nfcManager_doInitialize (JNIEnv* e, jobject o) NFA_P2pSetTraceLevel (num); sNfaEnableEvent.wait(); //wait for NFA command to finish } + EXTNS_Init (nfaDeviceManagementCallback, nfaConnectionCallback); } if (stat == NFA_STATUS_OK) @@ -905,7 +924,10 @@ static jboolean nfcManager_doInitialize (JNIEnv* e, jobject o) ALOGE ("%s: fail nfa enable; error=0x%X", __FUNCTION__, stat); if (sIsNfaEnabled) + { + EXTNS_Close (); stat = NFA_Disable (FALSE /* ungraceful */); + } theInstance.Finalize(); } @@ -1218,6 +1240,7 @@ static jboolean nfcManager_doDeinitialize (JNIEnv*, jobject) ALOGD ("%s: enter", __FUNCTION__); sIsDisabling = true; + pn544InteropAbortNow (); RoutingManager::getInstance().onNfccShutdown(); PowerSwitch::getInstance ().initialize (PowerSwitch::UNKNOWN_LEVEL); @@ -1225,6 +1248,7 @@ static jboolean nfcManager_doDeinitialize (JNIEnv*, jobject) if (sIsNfaEnabled) { SyncEventGuard guard (sNfaDisableEvent); + EXTNS_Close (); tNFA_STATUS stat = NFA_Disable (TRUE /* graceful */); if (stat == NFA_STATUS_OK) { diff --git a/nci/jni/NativeNfcTag.cpp b/nci/jni/NativeNfcTag.cpp index 7b51d93a..a25c3d7c 100755 --- a/nci/jni/NativeNfcTag.cpp +++ b/nci/jni/NativeNfcTag.cpp @@ -36,8 +36,10 @@ extern "C" { #include "nfa_api.h" #include "nfa_rw_api.h" + #include "nfc_brcm_defs.h" #include "ndef_utils.h" #include "rw_api.h" + #include "phNxpExtns.h" } namespace android { @@ -115,7 +117,7 @@ static bool sIsTagPresent = true; static tNFA_STATUS sMakeReadonlyStatus = NFA_STATUS_FAILED; static jboolean sMakeReadonlyWaitingForComplete = JNI_FALSE; static int sCurrentConnectedTargetType = TARGET_TYPE_UNKNOWN; - +static int sCurrentConnectedTargetProtocol = NFC_PROTOCOL_UNKNOWN; static int reSelect (tNFA_INTF_TYPE rfInterface, bool fSwitchIfNeeded); static bool switchRfInterface(tNFA_INTF_TYPE rfInterface); @@ -155,6 +157,7 @@ void nativeNfcTag_abortWaits () sem_post (&sMakeReadonlySem); sCurrentRfInterface = NFA_INTERFACE_ISO_DEP; sCurrentConnectedTargetType = TARGET_TYPE_UNKNOWN; + sCurrentConnectedTargetProtocol = NFC_PROTOCOL_UNKNOWN; } /******************************************************************************* @@ -189,6 +192,21 @@ void nativeNfcTag_doReadCompleted (tNFA_STATUS status) /******************************************************************************* ** +** Function: nativeNfcTag_setRfInterface +** +** Description: Set rf interface. +** +** Returns: void +** +*******************************************************************************/ +void nativeNfcTag_setRfInterface (tNFA_INTF_TYPE rfInterface) +{ + sCurrentRfInterface = rfInterface; +} + + +/******************************************************************************* +** ** Function: ndefHandlerCallback ** ** Description: Receive NDEF-message related events from stack. @@ -257,7 +275,14 @@ static jbyteArray nativeNfcTag_doRead (JNIEnv* e, jobject) { SyncEventGuard g (sReadEvent); sIsReadingNdefMessage = true; - status = NFA_RwReadNDef (); + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + status = EXTNS_MfcReadNDef (); + } + else + { + status = NFA_RwReadNDef (); + } sReadEvent.wait (); //wait for NFA_READ_CPLT_EVT } sIsReadingNdefMessage = false; @@ -372,7 +397,37 @@ static jboolean nativeNfcTag_doWrite (JNIEnv* e, jobject, jbyteArray buf) ALOGD ("%s: try format", __FUNCTION__); sem_init (&sFormatSem, 0, 0); sFormatOk = false; - status = NFA_RwFormatTag (); + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + static uint8_t mfc_key1[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + static uint8_t mfc_key2[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7}; + + status = EXTNS_MfcFormatTag (mfc_key1, sizeof(mfc_key1)); + if (status != NFA_STATUS_OK) + { + ALOGE ("%s: can't format mifare classic tag", __FUNCTION__); + sem_destroy (&sFormatSem); + goto TheEnd; + } + + if (sFormatOk == false) //if format operation failed + { + sem_wait (&sFormatSem); + sem_destroy (&sFormatSem); + sem_init (&sFormatSem, 0, 0); + status = EXTNS_MfcFormatTag (mfc_key2, sizeof(mfc_key2)); + if (status != NFA_STATUS_OK) + { + ALOGE ("%s: can't format mifare classic tag", __FUNCTION__); + sem_destroy (&sFormatSem); + goto TheEnd; + } + } + } + else + { + status = NFA_RwFormatTag (); + } sem_wait (&sFormatSem); sem_destroy (&sFormatSem); if (sFormatOk == false) //if format operation failed @@ -387,12 +442,26 @@ static jboolean nativeNfcTag_doWrite (JNIEnv* e, jobject, jbyteArray buf) NDEF_MsgInit (buffer, maxBufferSize, &curDataSize); status = NDEF_MsgAddRec (buffer, maxBufferSize, &curDataSize, NDEF_TNF_EMPTY, NULL, 0, NULL, 0, NULL, 0); ALOGD ("%s: create empty ndef msg; status=%u; size=%lu", __FUNCTION__, status, curDataSize); - status = NFA_RwWriteNDef (buffer, curDataSize); + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + status = EXTNS_MfcWriteNDef (buffer, curDataSize); + } + else + { + status = NFA_RwWriteNDef (buffer, curDataSize); + } } else { ALOGD ("%s: NFA_RwWriteNDef", __FUNCTION__); - status = NFA_RwWriteNDef (p_data, bytes.size()); + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + status = EXTNS_MfcWriteNDef (p_data, bytes.size()); + } + else + { + status = NFA_RwWriteNDef (p_data, bytes.size()); + } } if (status != NFA_STATUS_OK) @@ -435,6 +504,13 @@ TheEnd: *******************************************************************************/ void nativeNfcTag_doConnectStatus (jboolean isConnectOk) { + if (EXTNS_GetConnectFlag () == TRUE) + { + EXTNS_MfcActivated (); + EXTNS_SetConnectFlag (FALSE); + return; + } + if (sConnectWaitingForComplete != JNI_FALSE) { sConnectWaitingForComplete = JNI_FALSE; @@ -456,6 +532,13 @@ void nativeNfcTag_doConnectStatus (jboolean isConnectOk) *******************************************************************************/ void nativeNfcTag_doDeactivateStatus (int status) { + if (EXTNS_GetDeactivateFlag () == TRUE) + { + EXTNS_MfcDisconnect (); + EXTNS_SetDeactivateFlag (FALSE); + return; + } + sGotDeactivate = (status == 0); SyncEventGuard g (sReconnectEvent); @@ -497,16 +580,18 @@ static jint nativeNfcTag_doConnect (JNIEnv*, jobject, jint targetHandle) } sCurrentConnectedTargetType = natTag.mTechList[i]; - if (natTag.mTechLibNfcTypes[i] != NFC_PROTOCOL_ISO_DEP) + sCurrentConnectedTargetProtocol = natTag.mTechLibNfcTypes[i]; + + if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP) { - ALOGD ("%s() Nfc type = %d, do nothing for non ISO_DEP", __FUNCTION__, natTag.mTechLibNfcTypes[i]); + ALOGD ("%s() Nfc type = %d, do nothing for non ISO_DEP", __FUNCTION__, sCurrentConnectedTargetProtocol); retCode = NFCSTATUS_SUCCESS; goto TheEnd; } - if (natTag.mTechList[i] == TARGET_TYPE_ISO14443_3A || natTag.mTechList[i] == TARGET_TYPE_ISO14443_3B) + if (sCurrentConnectedTargetType == TARGET_TYPE_ISO14443_3A || sCurrentConnectedTargetType == TARGET_TYPE_ISO14443_3B) { - ALOGD ("%s: switching to tech: %d need to switch rf intf to frame", __FUNCTION__, natTag.mTechList[i]); + ALOGD ("%s: switching to tech: %d need to switch rf intf to frame", __FUNCTION__, sCurrentConnectedTargetType); retCode = switchRfInterface(NFA_INTERFACE_FRAME) ? NFA_STATUS_OK : NFA_STATUS_FAILED; } else @@ -519,6 +604,7 @@ TheEnd: return retCode; } + /******************************************************************************* ** ** Function: reSelect @@ -650,7 +736,7 @@ static bool switchRfInterface (tNFA_INTF_TYPE rfInterface) { NfcTag& natTag = NfcTag::getInstance (); - if (natTag.mTechLibNfcTypes[0] != NFC_PROTOCOL_ISO_DEP) + if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP) { ALOGD ("%s: protocol: %d not ISO_DEP, do nothing", __FUNCTION__, natTag.mTechLibNfcTypes[0]); return true; @@ -687,17 +773,19 @@ static jint nativeNfcTag_doReconnect (JNIEnv*, jobject) } // special case for Kovio - if (NfcTag::getInstance ().mTechList [0] == TARGET_TYPE_KOVIO_BARCODE) + if (sCurrentConnectedTargetProtocol == TARGET_TYPE_KOVIO_BARCODE) { ALOGD ("%s: fake out reconnect for Kovio", __FUNCTION__); goto TheEnd; } // this is only supported for type 2 or 4 (ISO_DEP) tags - if (natTag.mTechLibNfcTypes[0] == NFA_PROTOCOL_ISO_DEP) - retCode = reSelect(NFA_INTERFACE_ISO_DEP, false); - else if (natTag.mTechLibNfcTypes[0] == NFA_PROTOCOL_T2T) - retCode = reSelect(NFA_INTERFACE_FRAME, false); + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_ISO_DEP) + retCode = reSelect (NFA_INTERFACE_ISO_DEP, false); + else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_T2T) + retCode = reSelect (NFA_INTERFACE_FRAME, false); + else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + retCode = reSelect (NFA_INTERFACE_MIFARE, false); TheEnd: ALOGD ("%s: exit 0x%X", __FUNCTION__, retCode); @@ -774,6 +862,16 @@ void nativeNfcTag_doTransceiveStatus (tNFA_STATUS status, uint8_t* buf, uint32_t { SyncEventGuard g (sTransceiveEvent); ALOGD ("%s: data len=%d", __FUNCTION__, bufLen); + + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + if (EXTNS_GetCallBackFlag () == FALSE) + { + EXTNS_MfcCallBack (buf, bufLen); + return; + } + } + if (!sWaitingForTransceive) { ALOGE ("%s: drop data", __FUNCTION__); @@ -814,13 +912,15 @@ void nativeNfcTag_notifyRfTimeout () ** Returns: Response from tag. ** *******************************************************************************/ -static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject, jbyteArray data, jboolean raw, jintArray statusTargetLost) +static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject o, 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; + tNFA_STATUS status; if (NfcTag::getInstance ().getActivationState () != NfcTag::Active) { @@ -859,8 +959,17 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject, jbyteArray data sWaitingForTransceive = true; sRxDataStatus = NFA_STATUS_OK; sRxDataBuffer.clear (); - tNFA_STATUS status = NFA_SendRawFrame (buf, bufLen, - NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY); + + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + status = EXTNS_MfcTransceive (buf, bufLen); + } + else + { + 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); @@ -904,6 +1013,28 @@ static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject, jbyteArray data nativeNfcTag_doReconnect (NULL, NULL); ALOGD ("%s: reconnect finish", __FUNCTION__); } + else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + uint32_t transDataLen = sRxDataBuffer.size (); + uint8_t *transData = (uint8_t *) sRxDataBuffer.data (); + if (EXTNS_CheckMfcResponse (&transData, &transDataLen) == NFCSTATUS_FAILED) + { + nativeNfcTag_doReconnect (e, o); + } + else + { + if (transDataLen != 0) + { + result.reset (e->NewByteArray (transDataLen)); + } + if (result.get () != NULL) + { + e->SetByteArrayRegion (result.get (), 0, transDataLen, (const jbyte *) transData); + } + else + ALOGE ("%s: Failed to allocate java byte array", __FUNCTION__); + } + } else { // marshall data to java for return @@ -949,26 +1080,30 @@ static jint nativeNfcTag_doGetNdefType (JNIEnv*, jobject, jint libnfcType, jint // For NFA, libnfcType is mapped to the protocol value received // in the NFA_ACTIVATED_EVT and NFA_DISC_RESULT_EVT event. - switch (libnfcType) { - case NFA_PROTOCOL_T1T: + if (NFA_PROTOCOL_T1T == libnfcType) + { ndefType = NDEF_TYPE1_TAG; - break; - case NFA_PROTOCOL_T2T: - ndefType = NDEF_TYPE2_TAG;; - break; - case NFA_PROTOCOL_T3T: + } + else if (NFA_PROTOCOL_T2T == libnfcType) + { + ndefType = NDEF_TYPE2_TAG; + } + else if (NFA_PROTOCOL_T3T == libnfcType) + { ndefType = NDEF_TYPE3_TAG; - break; - case NFA_PROTOCOL_ISO_DEP: + } + else if (NFA_PROTOCOL_ISO_DEP == libnfcType) + { ndefType = NDEF_TYPE4_TAG; - break; - case NFA_PROTOCOL_INVALID: - ndefType = NDEF_UNKNOWN_TYPE; - break; - default: - /* NFA_PROTOCOL_ISO15693 and others */ + } + else if (NFA_PROTOCOL_MIFARE == libnfcType) + { + ndefType = NDEF_MIFARE_CLASSIC_TAG; + } + else + { + /* NFA_PROTOCOL_ISO15693, NFA_PROTOCOL_INVALID and others */ ndefType = NDEF_UNKNOWN_TYPE; - break; } ALOGD ("%s: exit; ndef type=%d", __FUNCTION__, ndefType); return ndefType; @@ -1064,7 +1199,7 @@ void nativeNfcTag_doCheckNdefResult (tNFA_STATUS status, uint32_t maxSize, uint3 ** Returns: Status code; 0 is success. ** *******************************************************************************/ -static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject, jintArray ndefInfo) +static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject o, jintArray ndefInfo) { tNFA_STATUS status = NFA_STATUS_FAILED; jint* ndef = NULL; @@ -1072,7 +1207,7 @@ static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject, jintArray ndefInfo) ALOGD ("%s: enter", __FUNCTION__); // special case for Kovio - if (NfcTag::getInstance ().mTechList [0] == TARGET_TYPE_KOVIO_BARCODE) + if (sCurrentConnectedTargetProtocol == TARGET_TYPE_KOVIO_BARCODE) { ALOGD ("%s: Kovio tag, no NDEF", __FUNCTION__); ndef = e->GetIntArrayElements (ndefInfo, 0); @@ -1081,6 +1216,10 @@ static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject, jintArray ndefInfo) e->ReleaseIntArrayElements (ndefInfo, ndef, 0); return NFA_STATUS_FAILED; } + else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + nativeNfcTag_doReconnect (e, o); + } /* Create the write semaphore */ if (sem_init (&sCheckNdefSem, 0, 0) == -1) @@ -1097,7 +1236,15 @@ static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject, jintArray ndefInfo) ALOGD ("%s: try NFA_RwDetectNDef", __FUNCTION__); sCheckNdefWaitingForComplete = JNI_TRUE; - status = NFA_RwDetectNDef (); + + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + status = EXTNS_MfcCheckNDef (); + } + else + { + status = NFA_RwDetectNDef (); + } if (status != NFA_STATUS_OK) { @@ -1153,6 +1300,12 @@ static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject, jintArray ndefInfo) status = sCheckNdefStatus; } + /* Reconnect Mifare Classic Tag for furture use */ + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + nativeNfcTag_doReconnect (e, o); + } + TheEnd: /* Destroy semaphore */ if (sem_destroy (&sCheckNdefSem)) @@ -1218,7 +1371,7 @@ static jboolean nativeNfcTag_doPresenceCheck (JNIEnv*, jobject) // 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) + if (sCurrentConnectedTargetProtocol == TARGET_TYPE_KOVIO_BARCODE) { ALOGD ("%s: Kovio, force deactivate handling", __FUNCTION__); tNFA_DEACTIVATED deactivated = {NFA_DEACTIVATE_TYPE_IDLE}; @@ -1256,6 +1409,14 @@ static jboolean nativeNfcTag_doPresenceCheck (JNIEnv*, jobject) ALOGD ("%s: tag already deactivated", __FUNCTION__); return JNI_FALSE; } + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + status = EXTNS_MfcPresenceCheck (); + if (status == NFCSTATUS_SUCCESS) + { + return (NFCSTATUS_SUCCESS == EXTNS_GetPresenceCheckStatus ()) ? JNI_TRUE : JNI_FALSE; + } + } { SyncEventGuard guard (sPresenceCheckEvent); @@ -1294,7 +1455,8 @@ static jboolean nativeNfcTag_doIsNdefFormatable (JNIEnv* e, { jboolean isFormattable = JNI_FALSE; tNFC_PROTOCOL protocol = NfcTag::getInstance().getProtocol(); - if (NFA_PROTOCOL_T1T == protocol || NFA_PROTOCOL_ISO15693 == protocol) + if (NFA_PROTOCOL_T1T == protocol || NFA_PROTOCOL_ISO15693 == protocol + || NFA_PROTOCOL_MIFARE == protocol) { isFormattable = JNI_TRUE; } @@ -1376,6 +1538,53 @@ static jboolean nativeNfcTag_doIsIsoDepNdefFormatable (JNIEnv *e, jobject o, jby /******************************************************************************* ** +** Function: nativeNfcTag_makeMifareNdefFormat +** +** Description: Format a mifare classic tag so it can store NDEF message. +** e: JVM environment. +** o: Java object. +** key: Key to acces tag. +** keySize: size of Key. +** +** Returns: True if ok. +** +*******************************************************************************/ +static jboolean nativeNfcTag_makeMifareNdefFormat (JNIEnv *e, jobject o, uint8_t *key, uint32_t keySize) +{ + ALOGD ("%s: enter", __FUNCTION__); + tNFA_STATUS status = NFA_STATUS_OK; + + status = nativeNfcTag_doReconnect (e, o); + if (status != NFA_STATUS_OK) + { + ALOGD ("%s: reconnect error, status=%u", __FUNCTION__, status); + return JNI_FALSE; + } + + sem_init (&sFormatSem, 0, 0); + sFormatOk = false; + + status = EXTNS_MfcFormatTag (key, keySize); + + if (status == NFA_STATUS_OK) + { + ALOGD ("%s: wait for completion", __FUNCTION__); + sem_wait (&sFormatSem); + status = sFormatOk ? NFA_STATUS_OK : NFA_STATUS_FAILED; + } + else + { + ALOGE ("%s: error status=%u", __FUNCTION__, status); + } + + sem_destroy (&sFormatSem); + ALOGD ("%s: exit", __FUNCTION__); + return (status == NFA_STATUS_OK) ? JNI_TRUE : JNI_FALSE; +} + + +/******************************************************************************* +** ** Function: nativeNfcTag_doNdefFormat ** ** Description: Format a tag so it can store NDEF message. @@ -1398,6 +1607,20 @@ static jboolean nativeNfcTag_doNdefFormat (JNIEnv *e, jobject o, jbyteArray) return JNI_FALSE; } + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + static uint8_t mfc_key1[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + static uint8_t mfc_key2[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7}; + jboolean result; + + result = nativeNfcTag_makeMifareNdefFormat (e, o, mfc_key1, sizeof(mfc_key1)); + if (result == JNI_FALSE) + { + result = nativeNfcTag_makeMifareNdefFormat (e, o, mfc_key2, sizeof(mfc_key2)); + } + return result; + } + sem_init (&sFormatSem, 0, 0); sFormatOk = false; status = NFA_RwFormatTag (); @@ -1411,7 +1634,7 @@ static jboolean nativeNfcTag_doNdefFormat (JNIEnv *e, jobject o, jbyteArray) ALOGE ("%s: error status=%u", __FUNCTION__, status); sem_destroy (&sFormatSem); - if (NfcTag::getInstance ().mTechLibNfcTypes[0] == NFA_PROTOCOL_ISO_DEP) + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_ISO_DEP) { int retCode = NFCSTATUS_SUCCESS; retCode = nativeNfcTag_doReconnect (e, o); @@ -1446,6 +1669,66 @@ void nativeNfcTag_doMakeReadonlyResult (tNFA_STATUS status) /******************************************************************************* ** +** Function: nativeNfcTag_makeMifareReadonly +** +** Description: Make the mifare classic tag read-only. +** e: JVM environment. +** o: Java object. +** key: Key to access the tag. +** keySize: size of Key. +** +** Returns: True if ok. +** +*******************************************************************************/ +static jboolean nativeNfcTag_makeMifareReadonly (JNIEnv *e, jobject o, uint8_t *key, int32_t keySize) +{ + jboolean result = JNI_FALSE; + tNFA_STATUS status = NFA_STATUS_OK; + + sMakeReadonlyStatus = NFA_STATUS_FAILED; + + ALOGD ("%s", __FUNCTION__); + + /* Create the make_readonly semaphore */ + if (sem_init (&sMakeReadonlySem, 0, 0) == -1) + { + ALOGE ("%s: Make readonly semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno); + return JNI_FALSE; + } + + sMakeReadonlyWaitingForComplete = JNI_TRUE; + + status = nativeNfcTag_doReconnect (e, o); + if (status != NFA_STATUS_OK) + { + goto TheEnd; + } + + status = EXTNS_MfcSetReadOnly (key, keySize); + if (status != NFA_STATUS_OK) + { + goto TheEnd; + } + sem_wait (&sMakeReadonlySem); + + if (sMakeReadonlyStatus == NFA_STATUS_OK) + { + result = JNI_TRUE; + } + +TheEnd: + /* Destroy semaphore */ + if (sem_destroy (&sMakeReadonlySem)) + { + ALOGE ("%s: Failed to destroy read_only semaphore (errno=0x%08x)", __FUNCTION__, errno); + } + sMakeReadonlyWaitingForComplete = JNI_FALSE; + return result; +} + + +/******************************************************************************* +** ** Function: nativeNfcTag_doMakeReadonly ** ** Description: Make the tag read-only. @@ -1456,13 +1739,25 @@ void nativeNfcTag_doMakeReadonlyResult (tNFA_STATUS status) ** Returns: True if ok. ** *******************************************************************************/ -static jboolean nativeNfcTag_doMakeReadonly (JNIEnv*, jobject, jbyteArray) +static jboolean nativeNfcTag_doMakeReadonly (JNIEnv *e, jobject o, jbyteArray) { jboolean result = JNI_FALSE; tNFA_STATUS status; ALOGD ("%s", __FUNCTION__); + if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE) + { + static uint8_t mfc_key1[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + static uint8_t mfc_key2[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7}; + result = nativeNfcTag_makeMifareReadonly (e, o, mfc_key1, sizeof(mfc_key1)); + if (result == JNI_FALSE) + { + result = nativeNfcTag_makeMifareReadonly (e, o, mfc_key2, sizeof(mfc_key2)); + } + return result; + } + /* Create the make_readonly semaphore */ if (sem_init (&sMakeReadonlySem, 0, 0) == -1) { @@ -1529,6 +1824,7 @@ void nativeNfcTag_registerNdefTypeHandler () ALOGD ("%s", __FUNCTION__); sNdefTypeHandlerHandle = NFA_HANDLE_INVALID; NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_DEFAULT, (UINT8 *) "", 0, ndefHandlerCallback); + EXTNS_MfcRegisterNDefTypeHandler (ndefHandlerCallback); } diff --git a/nci/jni/NfcTag.cpp b/nci/jni/NfcTag.cpp index c5eadd33..c4e343bc 100755 --- a/nci/jni/NfcTag.cpp +++ b/nci/jni/NfcTag.cpp @@ -27,6 +27,8 @@ extern "C" { #include "rw_int.h" + #include "nfc_brcm_defs.h" + #include "phNxpExtns.h" } @@ -392,6 +394,18 @@ void NfcTag::discoverTechnologies (tNFA_ACTIVATED& activationData) ALOGD ("%s: Kovio", fn); mTechList [mNumTechList] = TARGET_TYPE_KOVIO_BARCODE; } + else if (NFC_PROTOCOL_MIFARE == rfDetail.protocol) + { + ALOGD ("%s: Mifare Classic", fn); + EXTNS_MfcInit (activationData); + mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API + mNumTechList++; + mTechHandles [mNumTechList] = rfDetail.rf_disc_id; + mTechLibNfcTypes [mNumTechList] = rfDetail.protocol; + //save the stack's data structure for interpretation later + memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param)); + mTechList [mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC; //is TagTechnology.MIFARE_CLASSIC by Java API + } else { ALOGE ("%s: unknown protocol ????", fn); @@ -501,6 +515,19 @@ void NfcTag::discoverTechnologies (tNFA_DISC_RESULT& discoveryData) //is TagTechnology.NFC_V by Java API mTechList [mNumTechList] = TARGET_TYPE_ISO15693; } + else if (NFC_PROTOCOL_MIFARE == discovery_ntf.protocol) + { + mTechList [mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC; + if (mNumTechList < (MAX_NUM_TECHNOLOGY-1)) + { + mNumTechList++; + mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id; + mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol; + mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; + //save the stack's data structure for interpretation later + memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param)); + } + } else { ALOGE ("%s: unknown protocol ????", fn); @@ -821,6 +848,13 @@ void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, t //really, there is no data actBytes.reset(e->NewByteArray(0)); } + else if (NFC_PROTOCOL_MIFARE == mTechLibNfcTypes[i]) + { + ALOGD ("%s: Mifare Classic; tech A", fn); + actBytes.reset (e->NewByteArray(1)); + e->SetByteArrayRegion (actBytes.get(), 0, 1, + (jbyte*) &mTechParams [i].param.pa.sel_rsp); + } else if (NFC_PROTOCOL_ISO_DEP == mTechLibNfcTypes[i]) { //t4t @@ -1125,6 +1159,10 @@ void NfcTag::selectFirstTag () { rf_intf = NFA_INTERFACE_ISO_DEP; } + else if (mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_MIFARE) + { + rf_intf = NFA_INTERFACE_MIFARE; + } else rf_intf = NFA_INTERFACE_FRAME; diff --git a/nci/jni/extns/Android.mk b/nci/jni/extns/Android.mk new file mode 100755 index 00000000..2363da07 --- /dev/null +++ b/nci/jni/extns/Android.mk @@ -0,0 +1,2 @@ +EXTNS_PATH := $(call my-dir) +include $(call all-makefiles-under,$(EXTNS_PATH)) diff --git a/nci/jni/extns/pn54x/Android.mk b/nci/jni/extns/pn54x/Android.mk new file mode 100755 index 00000000..c4845097 --- /dev/null +++ b/nci/jni/extns/pn54x/Android.mk @@ -0,0 +1,10 @@ +EXTN_PN54X_PATH:= $(call my-dir) + +LOCAL_C_INCLUDES += \ + $(EXTN_PN54X_PATH)/inc \ + $(EXTN_PN54X_PATH)/src/common \ + $(EXTN_PN54X_PATH)/src/log \ + $(EXTN_PN54X_PATH)/src/mifare \ + $(EXTN_PN54X_PATH)/src/utils + +LOCAL_CFLAGS += -DNXP_UICC_ENABLE diff --git a/nci/jni/extns/pn54x/inc/phNxpExtns.h b/nci/jni/extns/pn54x/inc/phNxpExtns.h new file mode 100755 index 00000000..62809d40 --- /dev/null +++ b/nci/jni/extns/pn54x/inc/phNxpExtns.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef _PHNXPEXTNS_H_ +#define _PHNXPEXTNS_H_ + +#include <nfa_api.h> +#include <sys/types.h> +#include <errno.h> +#include <phNfcStatus.h> +#ifdef __cplusplus +extern "C" { +#endif + +NFCSTATUS EXTNS_Init (tNFA_DM_CBACK *p_dm_cback, + tNFA_CONN_CBACK *p_conn_cback); +void EXTNS_Close (void); +NFCSTATUS EXTNS_MfcInit (tNFA_ACTIVATED activationData); +NFCSTATUS EXTNS_MfcCheckNDef (void); +NFCSTATUS EXTNS_MfcReadNDef (void); +NFCSTATUS EXTNS_MfcPresenceCheck (void); +NFCSTATUS EXTNS_MfcWriteNDef (uint8_t *pBuf, uint32_t len); +NFCSTATUS EXTNS_MfcFormatTag (uint8_t *key, uint8_t len); +NFCSTATUS EXTNS_MfcDisconnect (void); +NFCSTATUS EXTNS_MfcActivated (void); +NFCSTATUS EXTNS_MfcTransceive (uint8_t *p_data, uint32_t len); +NFCSTATUS EXTNS_MfcRegisterNDefTypeHandler (tNFA_NDEF_CBACK *ndefHandlerCallback); +NFCSTATUS EXTNS_MfcCallBack (uint8_t *buf, uint32_t buflen); +NFCSTATUS EXTNS_MfcSetReadOnly (uint8_t *key, uint8_t len); +void EXTNS_SetConnectFlag (bool_t flagval); +bool_t EXTNS_GetConnectFlag (void); +void EXTNS_SetDeactivateFlag (bool_t flagval); +bool_t EXTNS_GetDeactivateFlag (void); +void EXTNS_SetCallBackFlag (bool_t flagval); +bool_t EXTNS_GetCallBackFlag (void); +NFCSTATUS EXTNS_CheckMfcResponse (uint8_t** sTransceiveData, uint32_t *sTransceiveDataLen); +void MfcPresenceCheckResult (NFCSTATUS status); +void MfcResetPresenceCheckStatus (void); +NFCSTATUS EXTNS_GetPresenceCheckStatus (void); +#ifdef __cplusplus +} +#endif + +/* + * Events from JNI for NXP Extensions + */ +#define PH_NXPEXTNS_MIFARE_CHECK_NDEF 0x01 /* MIFARE Check Ndef */ +#define PH_NXPEXTNS_MIFARE_READ_NDEF 0x02 /* MIFARE Read Ndef */ +#define PH_NXPEXTNS_MIFARE_WRITE_NDEF 0x03 /* MIFARE Write Ndef */ +#define PH_NXPEXTNS_MIFARE_FORMAT_NDEF 0x04 /* MIFARE Format */ +#define PH_NXPEXTNS_DISCONNECT 0x05 /* Target Disconnect */ +#define PH_NXPEXTNS_ACTIVATED 0x06 /* Target Activated */ +#define PH_NXPEXTNS_MIFARE_TRANSCEIVE 0x07 /* MIFARE Raw Transceive */ +#define PH_NXPEXTNS_MIFARE_READ_ONLY 0x08 /* MIFARE Read Only */ +#define PH_NXPEXTNS_MIFARE_PRESENCE_CHECK 0x09 /* MIFARE Presence Check */ +#define PH_NXPEXTNS_RX_DATA 0xF1 /* Receive Data */ + +#endif /* _PHNXPEXTNS_H_ */ diff --git a/nci/jni/extns/pn54x/inc/phNxpExtns_Custom.h b/nci/jni/extns/pn54x/inc/phNxpExtns_Custom.h new file mode 100755 index 00000000..a9d10c8d --- /dev/null +++ b/nci/jni/extns/pn54x/inc/phNxpExtns_Custom.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef _PHNXPEXTNS_CUSTOM_H_ +#define _PHNXPEXTNS_CUSTOM_H_ + +#include <nfa_api.h> +#include <sys/types.h> +#include <errno.h> +#include <phNfcStatus.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * TLV structure + * For simple TLV, type[0] == 0x00 + * For extended TLV, type[0] == 0xA0 + */ +typedef struct { + uint8_t type[2]; + uint8_t len; + uint8_t *val; +} tlv_t; + +typedef enum { + passive_106 = 0x01, + passive_212 = 0x02, + passive_424 = 0x04, + active_106 = 0x10, + active_212 = 0x20, + active_424 = 0x40, +} p2p_speed_t; + +typedef enum { + NO_SE, + UICC, + eSE, +} SE_t; + +typedef enum { + ReaderMode = 0x01, + P2PMode = 0x02, + CEMode = 0x04, +} PollMode_t; + +/******************************************************************************* + ** + ** Function phNxpExtns_get_version + ** + ** Description Function to get the HW, FW and SW versions. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function will use phNxpNciHal_get_version from HAL. + *******************************************************************************/ + +NFCSTATUS phNxpExtns_get_version (uint32_t *hw_ver, uint32_t *fw_ver, uint32_t *sw_ver); + +/******************************************************************************* + ** + ** Function phNxpNciHal_read_tlv + ** + ** Description Function to read simple TLV and extended TLV. + ** Memory for TLV and fields are allocated and freed by calling + ** function. Input is type and len. Response is provied in *val. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function will use NFA_GetConfig for simple TLV. + ** For extended TLV, it will use NFA_SendRawFrame. + *******************************************************************************/ + +NFCSTATUS phNxpNciHal_read_tlv (tlv_t *tlv); + +/******************************************************************************* + ** + ** Function phNxpNciHal_write_tlv + ** + ** Description Function to write simple TLV and extended TLV. + ** Memory for TLV and fields are allocated and freed by calling + ** function. Input is type, len, *val. + ** + ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function will use NFA_SetConfig for simple TLV. + ** For extended TLV, it will use NFA_SendRawFrame. + *******************************************************************************/ + +NFCSTATUS phNxpNciHal_write_tlv (tlv_t *tlv); + +/******************************************************************************* + ** + ** Function phNxpExtns_select_poll_tech + ** + ** Description This function selects the polling technology for starting + ** polling loop. This function does not start polling loop. + ** It is just a setting for polling technology. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function is using NFA_EnablePolling function. + *******************************************************************************/ + +NFCSTATUS phNxpExtns_select_poll_tech (tNFA_TECHNOLOGY_MASK tech_mask); + +/******************************************************************************* + ** + ** Function phNxpExtns_select_ce_listen_tech + ** + ** Description This function set the listen tech for card emulation. + ** This function does not include routing. + ** This function does not start polling loop. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function is using NFA_CeConfigureUiccListenTech. + ** Not sure which handle to use, from UICC or eSE. + *******************************************************************************/ + +NFCSTATUS phNxpExtns_select_ce_listen_tech (tNFA_TECHNOLOGY_MASK tech_mask); + +/******************************************************************************* + ** + ** Function phNxpExtns_select_p2p_poll_speed + ** + ** Description This function will select the P2P polling speed. + ** phNxpExtns_select_poll_tech overwrite the settings of poll if + ** reader mode is enabled. + ** There is only one active poll phase but device can use one + ** active speed and can move to higher speed if target supports. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function will use NFA_EnablePolling and NFA_SetConfig + *******************************************************************************/ + +NFCSTATUS phNxpExtns_select_p2p_poll_speed (p2p_speed_t p2p_initiator_speed); + +/******************************************************************************* + ** + ** Function phNxpExtns_select_p2p_listen_speed + ** + ** Description This function will select the listen mode + ** This function does not include routing. + ** This function does not start polling loop. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function will use NFA_SetP2pListenTech and NFA_SetConfig + *******************************************************************************/ + +NFCSTATUS phNxpExtns_select_p2p_listen_speed (p2p_speed_t p2p_target_speed); + +/******************************************************************************* + ** + ** Function phNxpExtns_select_se + ** + ** Description This function will set the routing of the traffic to selected + ** SE. This function also does not start polling loop. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: + *******************************************************************************/ + +NFCSTATUS phNxpExtns_select_se (SE_t se); + +/******************************************************************************* + ** + ** Function phNxpExtns_set_poll_mode + ** + ** Description This function selects which mode to enable for polling loop. + ** This function do not start polling loop. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: + *******************************************************************************/ + +NFCSTATUS phNxpExtns_set_poll_mode (PollMode_t poll_mode); + +/******************************************************************************* + ** + ** Function phNxpExtns_start_poll + ** + ** Description This function starts polling loop based on the configuration + ** of the previous calls. If no configuration done through other + ** function call then it uses the default configuration from + ** configuration files. + ** This function internally stops the polling loop if it is + ** already running. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: Internally this function uses NFA_StartRfDiscovery. + *******************************************************************************/ + +NFCSTATUS phNxpExtns_start_poll (void); + +/******************************************************************************* + ** + ** Function phNxpExtns_stop_poll + ** + ** Description This function stops the polling loop if it is running. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE:Internally this function uses NFA_StopRfDiscovery. + *******************************************************************************/ + +NFCSTATUS phNxpExtns_stop_poll (void); + +/******************************************************************************* + ** + ** Function phNxpExtns_enable_Felica_CLT + ** + ** Description This function enables or disable Felica CLT feature. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: + *******************************************************************************/ + +NFCSTATUS phNxpExtns_enable_Felica_CLT (bool enable); + +/******************************************************************************* + ** + ** Function phNxpExtns_enable_Mifare_CLT + ** + ** Description This function enables or disable Mifare CLT feature. + ** + ** Returns NFCSTATUS_SUCCESS if operation successful, + ** otherwise NFCSTATUS_FAILED. + ** + ** NOTE: + *******************************************************************************/ + +NFCSTATUS phNxpExtns_enable_Mifare_CLT (bool enable); + +#endif /* _PHNXPEXTNS_CUSTOM_H_ */ diff --git a/nci/jni/extns/pn54x/src/common/phNciNfcTypes.h b/nci/jni/extns/pn54x/src/common/phNciNfcTypes.h new file mode 100755 index 00000000..fad68662 --- /dev/null +++ b/nci/jni/extns/pn54x/src/common/phNciNfcTypes.h @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * NCI Interface + */ + +#ifndef PHNCINFCTYPES_H +#define PHNCINFCTYPES_H + +/* + ################################################################################ + ***************************** Header File Inclusion **************************** + ################################################################################ + */ +#include <phNfcStatus.h> + +/* + ################################################################################ + ****************************** Macro Definitions ******************************* + ################################################################################ + */ +#define PH_NCINFCTYPES_MAX_UID_LENGTH (0x0AU) +/* Maximum length of ATR_RES (General Bytes) length expected */ +#define PH_NCINFCTYPES_MAX_ATR_LENGTH (0x30U) +#define PH_NCINFCTYPES_ATQA_LENGTH (0x02U) /* ATQA length */ +#define PH_NCINFCTYPES_MAX_HIST_BYTES (0x0FU) /* Max Historical bytes returned by Type A tag */ + +/* + * Enum definition contains supported RF Protocols + */ +typedef enum +{ + phNciNfc_e_RfProtocolsUnknownProtocol = 0x00, /* Protocol is not known */ + phNciNfc_e_RfProtocolsT1tProtocol = 0x01, /* Type 1 Tag protocol */ + phNciNfc_e_RfProtocolsT2tProtocol = 0x02, /* Type 2 Tag protocol */ + phNciNfc_e_RfProtocolsT3tProtocol = 0x03, /* Type 3 Tag protocol */ + phNciNfc_e_RfProtocolsIsoDepProtocol = 0x04, /* ISO DEP protocol */ + phNciNfc_e_RfProtocolsNfcDepProtocol = 0x05, /* NFC DEP protocol */ + phNciNfc_e_RfProtocols15693Protocol = 0x06, /* 15693 protocol */ + phNciNfc_e_RfProtocolsMifCProtocol = 0x80, /* Mifare Classic protocol */ + phNciNfc_e_RfProtocolsHidProtocol = 0x81, /* Hid protocol */ + phNciNfc_e_RfProtocolsEpcGen2Protocol = 0x82, /* EpcGen2 protocol */ + phNciNfc_e_RfProtocolsKovioProtocol = 0x83 /* Kovio protocol */ +} phNciNfc_RfProtocols_t; + +/* + * Supported RF Interfaces + */ +typedef enum +{ + phNciNfc_e_RfInterfacesNfceeDirect_RF = 0x00, /* Nfcee Direct RF Interface */ + phNciNfc_e_RfInterfacesFrame_RF = 0x01, /* Frame RF Interface */ + phNciNfc_e_RfInterfacesISODEP_RF = 0x02, /* ISO DEP RF Interface */ + phNciNfc_e_RfInterfacesNFCDEP_RF = 0x03, /* NFC DEP RF Interface */ + phNciNfc_e_RfInterfacesTagCmd_RF = 0x80, /* Tag-Cmd RF Interface (Nxp prop) */ + phNciNfc_e_RfInterfacesHID_RF = 0x81 /* Hid RF Interface (Nxp prop) */ +} phNciNfc_RfInterfaces_t; + +/* + * Enum definition contains RF technology modes supported. + * This information is a part of RF_DISCOVER_NTF or RF_INTF_ACTIVATED_NTF. + */ +typedef enum +{ + phNciNfc_NFCA_Poll = 0x00, /* Nfc A Technology in Poll Mode */ + phNciNfc_NFCB_Poll = 0x01, /* Nfc B Technology in Poll Mode */ + phNciNfc_NFCF_Poll = 0x02, /* Nfc F Technology in Poll Mode */ + phNciNfc_NFCA_Active_Poll = 0x03, /* Nfc A Technology in Active Poll Mode */ + phNciNfc_NFCF_Active_Poll = 0x05, /* Nfc F Technology in Active Poll Mode */ + phNciNfc_NFCISO15693_Poll = 0x06, /* Nfc ISO15693 Technology in Poll Mode */ + phNciNfc_NxpProp_NFCHID_Poll = 0x70, /* Nfc Hid Technology in Poll Mode */ + phNciNfc_NxpProp_NFCEPFGEN2_Poll = 0x71, /* Nfc EpcGen2 Technology in Poll Mode */ + phNciNfc_NxpProp_NFCKOVIO_Poll = 0x72, /* Nfc Kovio Technology in Poll Mode */ + phNciNfc_NFCA_Listen = 0x80,/* Nfc A Technology in Listen Mode */ + phNciNfc_NFCB_Listen = 0x81,/* Nfc B Technology in Listen Mode */ + phNciNfc_NFCF_Listen = 0x82,/* Nfc F Technology in Listen Mode */ + phNciNfc_NFCA_Active_Listen = 0x83,/* Nfc A Technology in Active Listen Mode */ + phNciNfc_NFCF_Active_Listen = 0x85, /* Nfc F Technology in Active Listen Mode */ + phNciNfc_NFCISO15693_Active_Listen = 0x86 /* Nfc ISO15693 Technology in Listen Mode */ +} phNciNfc_RfTechMode_t; + +/* + * This is used to identify the exact device type + */ +typedef enum +{ + phNciNfc_eUnknown_DevType = 0x00U, + + /* Generic PICC Type */ + phNciNfc_ePICC_DevType, + /* Specific PICC Devices */ + /* This PICC type explains that the card is compliant to the + * ISO 14443-1 and 2A specification. This type can be used for the + * cards that is supporting these specifications + */ + phNciNfc_eISO14443_A_PICC, + /* This PICC type explains that the card is compliant to the + * ISO 14443-4A specification + */ + phNciNfc_eISO14443_4A_PICC, + /* This PICC type explains that the card is compliant to the + * ISO 14443-3A specification + */ + phNciNfc_eISO14443_3A_PICC, + /* This PICC type explains that the card is Mifare UL/1k/4k and + * also it is compliant to ISO 14443-3A. There can also be other + * ISO 14443-3A cards, so the phNciNfc_eISO14443_3A_PICC is also used for + * PICC detection + */ + phNciNfc_eMifareUL_PICC, + phNciNfc_eMifare1k_PICC, + phNciNfc_eMifare4k_PICC, + phNciNfc_eMifareMini_PICC, + /* This PICC type explains that the card is compliant to the + * ISO 14443-1, 2 and 3B specification + */ + phNciNfc_eISO14443_B_PICC, + /* This PICC type explains that the card is compliant to the + * ISO 14443-4B specification + */ + phNciNfc_eISO14443_4B_PICC, + /* This PICC type explains that the card is B-Prime type */ + phNciNfc_eISO14443_BPrime_PICC, + phNciNfc_eFelica_PICC, + phNciNfc_eJewel_PICC, + /* This PICC type explains that the card is ISO15693 type */ + phNciNfc_eISO15693_PICC, + /* This PICC type explains that the card is EpcGen2 type */ + phNciNfc_eEpcGen_PICC, + + /* NFC-IP1 Device Types */ + phNciNfc_eNfcIP1_Target, + phNciNfc_eNfcIP1_Initiator, + + /* Other Sources */ + phNciNfc_eInvalid_DevType + +}phNciNfc_RFDevType_t; + +/* + * RATS Response Params structure + */ +typedef struct phNciNfc_RATSResp { + uint8_t bFormatByte; /* Format Byte */ + uint8_t bIByteTA; /* Interface Byte TA(1) */ + uint8_t bIByteTB; /* Interface Byte TB(1) */ + uint8_t bIByteTC; /* Interface Byte TC(1) */ + uint8_t bHistByte[PH_NCINFCTYPES_MAX_HIST_BYTES]; /* Historical Bytes - Max size 15 */ +} phNciNfc_RATSResp_t; + +/* + * The Reader A structure includes the available information + * related to the discovered ISO14443A remote device. This information + * is updated for every device discovery. + */ +typedef struct phNciNfc_Iso14443AInfo +{ + uint8_t Uid[PH_NCINFCTYPES_MAX_UID_LENGTH]; /* UID information of the TYPE A + Tag Discovered NFCID1 - + Considering max size of NFCID1*/ + uint8_t UidLength; /* UID information length, shall not be greater + than PHNCINFC_MAX_UID_LENGTH i.e., 10 */ + uint8_t AppData[PH_NCINFCTYPES_MAX_ATR_LENGTH]; /* Application data information of the + tag discovered (= Historical bytes for + type A) */ + uint8_t AppDataLength; /* Application data length */ + uint8_t Sak; /* SAK information of the TYPE ATag Discovered + Mapped to SEL_RES Response*/ + uint8_t AtqA[PH_NCINFCTYPES_ATQA_LENGTH]; /* ATQA information of the TYPE A + Tag Discovered */ + uint8_t MaxDataRate; /* Maximum data rate supported by the TYPE A + Tag Discovered */ + uint8_t Fwi_Sfgt; /* Frame waiting time and start up frame guard + time as defined in ISO/IEC 14443-4[7] for type A */ + uint8_t bSensResResp[2]; /* SENS_RES Response */ + uint8_t bSelResRespLen; /* SEL_RES Response Length */ + uint8_t bRatsRespLen; /* Length of RATS Response */ + phNciNfc_RATSResp_t tRatsResp; /* RATS Response Info */ +} phNciNfc_Iso14443AInfo_t; + +/* + * The Remote Device Information Union includes the available Remote Device Information + * structures. Following the device detected, the corresponding data structure is used. + */ +typedef union phNciNfc_RemoteDevInfo +{ + phNciNfc_Iso14443AInfo_t Iso14443A_Info;/* Type A tag Info */ +} phNciNfc_RemoteDevInfo_t; + +/* Contains Details of Discovered Target */ +typedef struct phNciNfc_RemoteDevInformation +{ + uint8_t SessionOpened; /* Flag indicating the validity of the handle of the remote device. */ + phNciNfc_RFDevType_t RemDevType; /* Remote device type which says that remote + is Reader A or Reader B or NFCIP or Felica or + Reader B Prime or Jewel*/ + uint8_t bRfDiscId; /* ID of the Tag */ + phNciNfc_RfInterfaces_t eRfIf; /* RF Interface */ + phNciNfc_RfProtocols_t eRFProtocol; /* RF protocol of the target */ + phNciNfc_RfTechMode_t eRFTechMode; /* RF Technology mode of the discovered/activated target */ + uint8_t bMaxPayLoadSize; /* Max data payload size*/ + uint8_t bInitialCredit; /* Initial credit*/ + uint8_t bTechSpecificParamLen; /* Technology Specific parameter length, for Debugging purpose only*/ + phNciNfc_RfTechMode_t eDataXchgRFTechMode; /* Data Exchange RF Technology mode of the activated target */ + uint8_t bTransBitRate; /* Transmit Bit Rate */ + uint8_t bRecvBitRate; /* Receive Bit Rate */ + phNciNfc_RemoteDevInfo_t tRemoteDevInfo; /* Structure object to #phNciNfc_RemoteDevInfo_t*/ +} phNciNfc_RemoteDevInformation_t, *pphNciNfc_RemoteDevInformation_t;/* Pointer to Remote Dev Info*/ + +/* + * Structure contains buffer where payload of the received data packet + * shall be stored and length of the payload stored in the buffer. + */ +typedef struct phNciNfc_Data +{ + uint8_t *pBuff; /* Buffer to store received data packet's payload */ + uint16_t wLen; /* Length of the payload */ +} phNciNfc_Data_t, *pphNciNfc_Data_t; + + +/* + * Type 2 tag command list supported by NCI stack + * It includes command lists applicable to Mifare family cards also + */ +typedef enum phNciNfc_T2TCmdList +{ + phNciNfc_eT2TRaw = 0x00, /* Performs Raw communication over T2T Tag*/ + phNciNfc_eT2TWriteN, /* Write Multiple blocks to T2T tag*/ + phNciNfc_eT2TreadN, /* Read Multiple blocks to T2T tag*/ + phNciNfc_eT2TSectorSel, /* Sector Select for MifareStd Cards*/ + phNciNfc_eT2TAuth, /* Sector Select for MifareStd Cards*/ + phNciNfc_eT2TProxCheck,/* Proxy Check command for MF+*/ + phNciNfc_eT2TInvalidCmd /* Invalid Command*/ +} phNciNfc_T2TCmdList_t; /* Type2 Tag and Mifare specicific command list*/ + +/* All command list for tag operation supported by NCI stack */ +typedef union phNciNfc_TagCmdList +{ + phNciNfc_T2TCmdList_t T2TCmd; /* T2T Specific command*/ +} phNciNfc_TagCmdList_t; /* Tag specific command */ + +/* Transceive info */ +typedef struct phNciNfc_TransceiveInfo +{ + phNciNfc_TagCmdList_t uCmd; /* Technology Specific commands */ + uint8_t bAddr; /* Start address to perform operation,Valid for T1T T2T T3T and some Propriatery tags */ + uint8_t bNumBlock;/* Number of blocks */ + uint16_t wTimeout; /* Timeout value to be used during transceive */ + phNciNfc_Data_t tSendData;/* Buffer information for sending data */ + phNciNfc_Data_t tRecvData;/* Buffer information for receiving data */ + /* Details for Felica To be Added if Check and Update supported */ +} phNciNfc_TransceiveInfo_t, *pphNciNfc_TransceiveInfo_t; /* pointer to struct #phNciNfc_TransceiveInfo_t */ + +#endif /* end of #ifndef PHNCINFCTYPES_H */ diff --git a/nci/jni/extns/pn54x/src/common/phNfcCompId.h b/nci/jni/extns/pn54x/src/common/phNfcCompId.h new file mode 100755 index 00000000..e41f1c68 --- /dev/null +++ b/nci/jni/extns/pn54x/src/common/phNfcCompId.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * NFC Component ID Values - Used for Function Return Codes + */ + +#ifndef PHNFCCOMPID_H +#define PHNFCCOMPID_H + +/* + * Component IDs + * + * IDs for all NFC components. Combined with the Status Code they build the value (status) + * returned by each function. + * + * ID Number Spaces: + * - 01..1F: HAL + * - 20..3F: NFC-MW (Local Device) + * - 40..5F: NFC-MW (Remote Device) + * . + * + * The value CID_NFC_NONE does not exist for Component IDs. Do not use this value except + * for NFCSTATUS_SUCCESS. The enumeration function uses CID_NFC_NONE + * to mark unassigned "References". + */ +#define CID_NFC_NONE 0x00 /* Unassigned or doesn't apply (see #NFCSTATUS_SUCCESS) */ +#define CID_NFC_TML 0x01 /* Transport Mapping Layer */ +#define CID_NFC_LLC 0x07 /* Logical Link Control Layer */ +#define CID_NFC_NCI 0x08 /* NFC Controller(NFCC) Interface Layer */ +#define CID_NFC_DNLD 0x09 /* Firmware Download Management Layer */ +#define CID_NFC_HAL 0x10 /* Hardware Abstraction Layer */ +#define CID_NFC_OSAL CID_NFC_NONE /* Operating System Abstraction Layer*/ +#define CID_FRI_NFC_OVR_HAL 0x20 /* NFC-Device, HAL-based */ +#define CID_FRI_NFC_NDEF_RECORD 0x22 /* NDEF Record Tools Library. */ +#define CID_FRI_NFC_NDEF_MAP 0x23 /* NDEF Mapping. */ +#define CID_FRI_NFC_NDEF_REGISTRY 0x24 /* NDEF_REGISTRY. */ +#define CID_FRI_NFC_AUTO_DEV_DIS 0x25 /* Automatic Device Discovery. */ +#define CID_FRI_NFC_NDEF_SMTCRDFMT 0x26 /* Smart Card Formatting */ +#define CID_NFC_LIB 0x30 /* NFC Library Layer*/ +#define CID_MAX_VALUE 0xF0 /* The maximum CID value that is defined. */ +#define CID_FRI_NFC_LLCP 0x40 /* Logical Link Control Protocol */ +#define CID_FRI_NFC_LLCP_TRANSPORT 0x50 +#define CID_FRI_NFC_LLCP_MAC 0x60 + +#endif /* PHNFCCOMPID_H */ diff --git a/nci/jni/extns/pn54x/src/common/phNfcStatus.h b/nci/jni/extns/pn54x/src/common/phNfcStatus.h new file mode 100755 index 00000000..ccd955f8 --- /dev/null +++ b/nci/jni/extns/pn54x/src/common/phNfcStatus.h @@ -0,0 +1,367 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * NFC Status Values - Function Return Codes + */ + +#ifndef PHNFCSTATUS_H +#define PHNFCSTATUS_H + +#include <phNfcTypes.h> + +/* Internally required by PHNFCSTVAL. */ +#define PHNFCSTSHL8 (8U) +/* Required by PHNFCSTVAL. */ +#define PHNFCSTBLOWER ((NFCSTATUS)(0x00FFU)) + +/* + * NFC Status Composition Macro + * + * This is the macro which must be used to compose status values. + * + * phNfcCompID Component ID, as defined in phNfcCompId.h . + * phNfcStatus Status values, as defined in phNfcStatus.h . + * + * The macro is not required for the NFCSTATUS_SUCCESS value. + * This is the only return value to be used directly. + * For all other values it shall be used in assignment and conditional statements, e.g.: + * NFCSTATUS status = PHNFCSTVAL(phNfcCompID, phNfcStatus); ... + * if (status == PHNFCSTVAL(phNfcCompID, phNfcStatus)) ... + */ +#define PHNFCSTVAL(phNfcCompID, phNfcStatus) \ + ( ((phNfcStatus) == (NFCSTATUS_SUCCESS)) ? (NFCSTATUS_SUCCESS) : \ + ( (((NFCSTATUS)(phNfcStatus)) & (PHNFCSTBLOWER)) | \ + (((uint16_t)(phNfcCompID)) << (PHNFCSTSHL8)) ) ) + +/* + * PHNFCSTATUS + * Get grp_retval from Status Code + */ +#define PHNFCSTATUS(phNfcStatus) ((phNfcStatus) & 0x00FFU) +#define PHNFCCID(phNfcStatus) (((phNfcStatus) & 0xFF00U)>>8) + +/* + * Status Codes + * + * Generic Status codes for the NFC components. Combined with the Component ID + * they build the value (status) returned by each function. + * Example: + * grp_comp_id "Component ID" - e.g. 0x10, plus + * status code as listed in this file - e.g. 0x03 + * result in a status value of 0x0003. + */ + +/* + * The function indicates successful completion + */ +#define NFCSTATUS_SUCCESS (0x0000) + +/* + * The function indicates successful completion + */ +#define NFCSTATUS_OK (NFCSTATUS_SUCCESS) + +/* + * At least one parameter could not be properly interpreted + */ +#define NFCSTATUS_INVALID_PARAMETER (0x0001) + +/* + * The buffer provided by the caller is too small + */ +#define NFCSTATUS_BUFFER_TOO_SMALL (0x0003) + +/* + * Device specifier/handle value is invalid for the operation + */ +#define NFCSTATUS_INVALID_DEVICE (0x0006) + +/* + * The function executed successfully but could have returned + * more information than space provided by the caller + */ +#define NFCSTATUS_MORE_INFORMATION (0x0008) + +/* + * No response from the remote device received: Time-out + */ +#define NFCSTATUS_RF_TIMEOUT (0x0009) + +/* + * RF Error during data transaction with the remote device + */ +#define NFCSTATUS_RF_ERROR (0x000A) + +/* + * Not enough resources Memory, Timer etc(e.g. allocation failed.) + */ +#define NFCSTATUS_INSUFFICIENT_RESOURCES (0x000C) + +/* + * A non-blocking function returns this immediately to indicate + * that an internal operation is in progress + */ +#define NFCSTATUS_PENDING (0x000D) + +/* + * A board communication error occurred + * (e.g. Configuration went wrong) + */ +#define NFCSTATUS_BOARD_COMMUNICATION_ERROR (0x000F) + +/* + * Invalid State of the particular state machine + */ +#define NFCSTATUS_INVALID_STATE (0x0011) + + +/* + * This Layer is Not initialized, hence initialization required. + */ +#define NFCSTATUS_NOT_INITIALISED (0x0031) + + +/* + * The Layer is already initialized, hence initialization repeated. + */ +#define NFCSTATUS_ALREADY_INITIALISED (0x0032) + + +/* + * Feature not supported + */ +#define NFCSTATUS_FEATURE_NOT_SUPPORTED (0x0033) + +/* The Unregistration command has failed because the user wants to unregister on + * an element for which he was not registered + */ +#define NFCSTATUS_NOT_REGISTERED (0x0034) + + +/* The Registration command has failed because the user wants to register on + * an element for which he is already registered + */ +#define NFCSTATUS_ALREADY_REGISTERED (0x0035) + +/* Single Tag with Multiple + Protocol support detected */ +#define NFCSTATUS_MULTIPLE_PROTOCOLS (0x0036) + +/* + * Feature not supported + */ +#define NFCSTATUS_MULTIPLE_TAGS (0x0037) + +/* + * A DESELECT event has occurred + */ +#define NFCSTATUS_DESELECTED (0x0038) + +/* + * A RELEASE event has occurred + */ +#define NFCSTATUS_RELEASED (0x0039) + +/* + * The operation is currently not possible or not allowed + */ +#define NFCSTATUS_NOT_ALLOWED (0x003A) + +/* + * The system is busy with the previous operation. + */ +#define NFCSTATUS_BUSY (0x006F) + + +/* NDEF Mapping error codes */ + +/* The remote device (type) is not valid for this request. */ +#define NFCSTATUS_INVALID_REMOTE_DEVICE (0x001D) + +/* Read operation failed */ +#define NFCSTATUS_READ_FAILED (0x0014) + +/* + * Write operation failed + */ +#define NFCSTATUS_WRITE_FAILED (0x0015) + +/* Non Ndef Compliant */ +#define NFCSTATUS_NO_NDEF_SUPPORT (0x0016) + +/* Could not proceed further with the write operation: reached card EOF*/ +#define NFCSTATUS_EOF_NDEF_CONTAINER_REACHED (0x001A) + +/* Incorrect number of bytes received from the card*/ +#define NFCSTATUS_INVALID_RECEIVE_LENGTH (0x001B) + +/* The data format/composition is not understood/correct. */ +#define NFCSTATUS_INVALID_FORMAT (0x001C) + + +/* There is not sufficient storage available. */ +#define NFCSTATUS_INSUFFICIENT_STORAGE (0x001F) + +/* The Ndef Format procedure has failed. */ +#define NFCSTATUS_FORMAT_ERROR (0x0023) + +/* The NCI Cedit error */ +#define NFCSTATUS_CREDIT_TIMEOUT (0x0024) + +/* + * Response Time out for the control message(NFCC not responded) + */ +#define NFCSTATUS_RESPONSE_TIMEOUT (0x0025) + +/* + * Device is already connected + */ +#define NFCSTATUS_ALREADY_CONNECTED (0x0026) + +/* + * Device is already connected + */ +#define NFCSTATUS_ANOTHER_DEVICE_CONNECTED (0x0027) + +/* + * Single Target Detected and Activated + */ +#define NFCSTATUS_SINGLE_TAG_ACTIVATED (0x0028) + +/* + * Single Target Detected + */ +#define NFCSTATUS_SINGLE_TAG_DISCOVERED (0x0029) + +/* + * Secure element Detected and Activated + */ +#define NFCSTATUS_SECURE_ELEMENT_ACTIVATED (0x0028) + +/* + * Unknown error Status Codes + */ +#define NFCSTATUS_UNKNOWN_ERROR (0x00FE) + +/* + * Status code for failure + */ +#define NFCSTATUS_FAILED (0x00FF) + +/* + * The function/command has been aborted + */ +#define NFCSTATUS_CMD_ABORTED (0x0002) + +/* + * No target found after poll + */ +#define NFCSTATUS_NO_TARGET_FOUND (0x000A) + +/* Attempt to disconnect a not connected remote device. */ +#define NFCSTATUS_NO_DEVICE_CONNECTED (0x000B) + +/* External RF field detected. */ +#define NFCSTATUS_EXTERNAL_RF_DETECTED (0x000E) + +/* Message is not allowed by the state machine + * (e.g. configuration went wrong) + */ +#define NFCSTATUS_MSG_NOT_ALLOWED_BY_FSM (0x0010) + +/* + * No access has been granted + */ +#define NFCSTATUS_ACCESS_DENIED (0x001E) + +/* No registry node matches the specified input data. */ +#define NFCSTATUS_NODE_NOT_FOUND (0x0017) + +/* The current module is busy ; one might retry later */ +#define NFCSTATUS_SMX_BAD_STATE (0x00F0) + + +/* The Abort mechanism has failed for unexpected reason: user can try again*/ +#define NFCSTATUS_ABORT_FAILED (0x00F2) + + +/* The Registration command has failed because the user wants to register as target + * on a operating mode not supported + */ +#define NFCSTATUS_REG_OPMODE_NOT_SUPPORTED (0x00F5) + +/* + * Shutdown in progress, cannot handle the request at this time. + */ +#define NFCSTATUS_SHUTDOWN (0x0091) + +/* + * Target is no more in RF field + */ +#define NFCSTATUS_TARGET_LOST (0x0092) + +/* + * Request is rejected + */ +#define NFCSTATUS_REJECTED (0x0093) + +/* + * Target is not connected + */ +#define NFCSTATUS_TARGET_NOT_CONNECTED (0x0094) + +/* + * Invalid handle for the operation + */ +#define NFCSTATUS_INVALID_HANDLE (0x0095) + +/* + * Process aborted + */ +#define NFCSTATUS_ABORTED (0x0096) + +/* + * Requested command is not supported + */ +#define NFCSTATUS_COMMAND_NOT_SUPPORTED (0x0097) + +/* + * Tag is not NDEF compliant + */ +#define NFCSTATUS_NON_NDEF_COMPLIANT (0x0098) + +/* + * Not enough memory available to complete the requested operation + */ +#define NFCSTATUS_NOT_ENOUGH_MEMORY (0x001F) + +/* + * Indicates incoming connection + */ +#define NFCSTATUS_INCOMING_CONNECTION (0x0045) + +/* + * Indicates Connection was successful + */ +#define NFCSTATUS_CONNECTION_SUCCESS (0x0046) + +/* + * Indicates Connection failed + */ +#define NFCSTATUS_CONNECTION_FAILED (0x0047) + +#endif /* PHNFCSTATUS_H */ diff --git a/nci/jni/extns/pn54x/src/common/phNfcTypes.h b/nci/jni/extns/pn54x/src/common/phNfcTypes.h new file mode 100755 index 00000000..08a17f9e --- /dev/null +++ b/nci/jni/extns/pn54x/src/common/phNfcTypes.h @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef PHNFCTYPES_H +#define PHNFCTYPES_H + +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#ifndef TRUE +#define TRUE (0x01) /* Logical True Value */ +#endif +#ifndef FALSE +#define FALSE (0x00) /* Logical False Value */ +#endif +typedef uint8_t utf8_t; /* UTF8 Character String */ +typedef uint8_t bool_t; /* boolean data type */ +typedef uint16_t NFCSTATUS; /* Return values */ +#define STATIC static + +#define PHNFC_MAX_UID_LENGTH 0x0AU /* Maximum UID length expected */ +#define PHNFC_MAX_ATR_LENGTH 0x30U /* Maximum ATR_RES (General Bytes) length expected */ +#define PHNFC_NFCID_LENGTH 0x0AU /* Maximum length of NFCID 1.3*/ +#define PHNFC_ATQA_LENGTH 0x02U /* ATQA length */ + +/* + * NFC Data structure + */ +typedef struct phNfc_sData +{ + uint8_t *buffer; /* Buffer to store data */ + uint32_t length; /* Buffer length */ +} phNfc_sData_t; + +/* + * Possible Hardware Configuration exposed to upper layer. + * Typically this should be port name (Ex:"COM1","COM2") to which PN547 is connected. + */ +typedef enum +{ + ENUM_LINK_TYPE_COM1, + ENUM_LINK_TYPE_COM2, + ENUM_LINK_TYPE_COM3, + ENUM_LINK_TYPE_COM4, + ENUM_LINK_TYPE_COM5, + ENUM_LINK_TYPE_COM6, + ENUM_LINK_TYPE_COM7, + ENUM_LINK_TYPE_COM8, + ENUM_LINK_TYPE_I2C, + ENUM_LINK_TYPE_SPI, + ENUM_LINK_TYPE_USB, + ENUM_LINK_TYPE_TCP, + ENUM_LINK_TYPE_NB +} phLibNfc_eConfigLinkType; + +/* + * Deferred message. This message type will be posted to the client application thread + * to notify that a deferred call must be invoked. + */ +#define PH_LIBNFC_DEFERREDCALL_MSG (0x311) + +/* + * Deferred call declaration. + * This type of API is called from ClientApplication ( main thread) to notify + * specific callback. + */ +typedef void (*pphLibNfc_DeferredCallback_t) (void*); + +/* + * Deferred parameter declaration. + * This type of data is passed as parameter from ClientApplication (main thread) to the + * callback. + */ +typedef void *pphLibNfc_DeferredParameter_t; + +/* + * Possible Hardware Configuration exposed to upper layer. + * Typically this should be at least the communication link (Ex:"COM1","COM2") + * the controller is connected to. + */ +typedef struct phLibNfc_sConfig +{ + uint8_t *pLogFile; /* Log File Name*/ + /* Hardware communication link to the controller */ + phLibNfc_eConfigLinkType nLinkType; + /* The client ID (thread ID or message queue ID) */ + unsigned int nClientId; +} phLibNfc_sConfig_t, *pphLibNfc_sConfig_t; + +/* + * NFC Message structure contains message specific details like + * message type, message specific data block details, etc. + */ +typedef struct phLibNfc_Message +{ + uint32_t eMsgType; /* Type of the message to be posted*/ + void * pMsgData; /* Pointer to message specific data block in case any*/ + uint32_t Size; /* Size of the datablock*/ +} phLibNfc_Message_t, *pphLibNfc_Message_t; + +/* + * Deferred message specific info declaration. + * This type of information is packed as message data when PH_LIBNFC_DEFERREDCALL_MSG + * type message is posted to message handler thread. + */ +typedef struct phLibNfc_DeferredCall +{ + pphLibNfc_DeferredCallback_t pCallback;/* pointer to Deferred callback */ + pphLibNfc_DeferredParameter_t pParameter;/* pointer to Deferred parameter */ +} phLibNfc_DeferredCall_t; + +/* + * Definitions for supported protocol + */ +typedef struct phNfc_sSupProtocol +{ + unsigned int MifareUL : 1; /* Protocol Mifare Ultra Light or any NFC Forum Type-2 tags */ + unsigned int MifareStd : 1; /* Protocol Mifare Standard. */ + unsigned int ISO14443_4A : 1; /* Protocol ISO14443-4 Type A. */ + unsigned int ISO14443_4B : 1; /* Protocol ISO14443-4 Type B. */ + unsigned int ISO15693 : 1; /* Protocol ISO15693 HiTag. */ + unsigned int Felica : 1; /* Protocol Felica. */ + unsigned int NFC : 1; /* Protocol NFC. */ + unsigned int Jewel : 1; /* Protocol Innovision Jewel Tag. or Any T1T*/ + unsigned int Desfire : 1; /*TRUE indicates specified feature (mapping + or formatting)for DESFire tag supported else not supported.*/ + unsigned int Kovio : 1; /* Protocol Kovio Tag*/ + unsigned int HID : 1; /* Protocol HID(Picopass) Tag*/ + unsigned int Bprime : 1; /* Protocol BPrime Tag*/ + unsigned int EPCGEN2 : 1; /* Protocol EPCGEN2 Tag*/ +} phNfc_sSupProtocol_t; + +/* + * Enumerated MIFARE Commands + */ + +typedef enum phNfc_eMifareCmdList +{ + phNfc_eMifareRaw = 0x00U, /* This command performs raw transcations */ + phNfc_eMifareAuthentA = 0x60U, /* This command performs an authentication with KEY A for a sector. */ + phNfc_eMifareAuthentB = 0x61U, /* This command performs an authentication with KEY B for a sector. */ + phNfc_eMifareRead16 = 0x30U, /* Read 16 Bytes from a Mifare Standard block */ + phNfc_eMifareRead = 0x30U, /* Read Mifare Standard */ + phNfc_eMifareWrite16 = 0xA0U, /* Write 16 Bytes to a Mifare Standard block */ + phNfc_eMifareWrite4 = 0xA2U, /* Write 4 bytes. */ + phNfc_eMifareInc = 0xC1U, /* Increment */ + phNfc_eMifareDec = 0xC0U, /* Decrement */ + phNfc_eMifareTransfer = 0xB0U, /* Transfer */ + phNfc_eMifareRestore = 0xC2U, /* Restore. */ + phNfc_eMifareReadSector = 0x38U, /* Read Sector. */ + phNfc_eMifareWriteSector= 0xA8U, /* Write Sector. */ + /* Above commands could be used for preparing raw command but below one can not be */ + phNfc_eMifareReadN = 0x01, /* Proprietary Command */ + phNfc_eMifareWriteN = 0x02, /* Proprietary Command */ + phNfc_eMifareSectorSel = 0x03, /* Proprietary Command */ + phNfc_eMifareAuth = 0x04, /* Proprietary Command */ + phNfc_eMifareProxCheck = 0x05, /* Proprietary Command */ + phNfc_eMifareInvalidCmd = 0xFFU /* Invalid Command */ +} phNfc_eMifareCmdList_t; + +/* + * Information about ISO14443A + */ +typedef struct phNfc_sIso14443AInfo +{ + uint8_t Uid[PHNFC_MAX_UID_LENGTH]; /* UID information of the TYPE A + * Tag Discovered */ + uint8_t UidLength; /* UID information length */ + uint8_t AppData[PHNFC_MAX_ATR_LENGTH]; /* Application data information of the + 1 * tag discovered (= Historical bytes for + * type A) */ + uint8_t AppDataLength; /* Application data length */ + uint8_t Sak; /* SAK information of the TYPE A + * Tag Discovered */ + uint8_t AtqA[PHNFC_ATQA_LENGTH]; /* ATQA informationof the TYPE A + * Tag Discovered */ + uint8_t MaxDataRate; /* Maximum data rate supported + * by the tag Discovered */ + uint8_t Fwi_Sfgt; /* Frame waiting time and start up + * frame guard */ +} phNfc_sIso14443AInfo_t; + +/* Remote device information structure */ +typedef union phNfc_uRemoteDevInfo +{ + phNfc_sIso14443AInfo_t Iso14443A_Info;/* ISO1443A Remote device info */ +} phNfc_uRemoteDevInfo_t; + +/* +* +* The RF Device Type List is used to identify the type of +* remote device that is discovered and connected. +* +*/ + +typedef enum phNfc_eRFDevType +{ + phNfc_eUnknown_DevType = 0x00U, + phNfc_eISO14443_A_PCD, + phNfc_eISO14443_B_PCD, + phNfc_eISO14443_BPrime_PCD, + phNfc_eFelica_PCD, + phNfc_eJewel_PCD, + phNfc_eISO15693_PCD, + phNfc_eEpcGen2_PCD, + phNfc_ePCD_DevType, + phNfc_ePICC_DevType, + phNfc_eISO14443_A_PICC, + phNfc_eISO14443_4A_PICC, + phNfc_eISO14443_3A_PICC, + phNfc_eMifare_PICC, + phNfc_eISO14443_B_PICC, + phNfc_eISO14443_4B_PICC, + phNfc_eISO14443_BPrime_PICC, + phNfc_eFelica_PICC, + phNfc_eJewel_PICC, + phNfc_eISO15693_PICC, + phNfc_eEpcGen2_PICC, + phNfc_eNfcIP1_Target, + phNfc_eNfcIP1_Initiator, + phNfc_eInvalid_DevType +} phNfc_eRFDevType_t; + +/* + * The Remote Device Type List is used to identify the type of + * remote device that is discovered/connected + */ +typedef phNfc_eRFDevType_t phNfc_eRemDevType_t; +typedef phNfc_eRemDevType_t phHal_eRemDevType_t; + +/* + * Union for each available type of Commands. + */ + +typedef union phNfc_uCommand +{ + phNfc_eMifareCmdList_t MfCmd; /* Mifare command structure. */ +} phNfc_uCmdList_t; + +/* + * The Remote Device Information Structure holds information about one single Remote + * Device detected. + */ +typedef struct phNfc_sRemoteDevInformation +{ + uint8_t SessionOpened; /* Flag indicating the validity of + * the handle of the remote device. + * 1 = Device is not activer (Only discovered), 2 = Device is active and ready for use*/ + phNfc_eRemDevType_t RemDevType; /* Remote device type */ + phNfc_uRemoteDevInfo_t RemoteDevInfo; /* Union of available Remote Device */ +} phNfc_sRemoteDevInformation_t; + + +/* + * Transceive Information Data Structure for sending commands/response to the remote device + */ + +typedef struct phNfc_sTransceiveInfo +{ + phNfc_uCmdList_t cmd; /* Command for transceive */ + uint8_t addr; /* Start Block Number */ + uint8_t NumBlock; /* Number of Blocks to perform operation */ + /* For Felica only*/ + uint16_t *ServiceCodeList; /* 2 Byte service Code List */ + uint16_t *Blocklist; /* 2 Byte Block list */ + phNfc_sData_t sSendData; /* Send data */ + phNfc_sData_t sRecvData; /* Recv data */ + /* For EPC-GEN */ + uint32_t dwWordPtr; /* Word address for the memory write */ + uint8_t bWordPtrLen; /* Specifies the length of word pointer + 00: 8 bits + 01: 16 bits + 10: 24 bits + 11: 32 bits + */ + uint8_t bWordCount; /* Number of words to be read or written */ +} phNfc_sTransceiveInfo_t; + +#define UNUSED(X) (void)X; + +#endif /* PHNFCTYPES_H */ diff --git a/nci/jni/extns/pn54x/src/common/phNfcTypes_Mapping.h b/nci/jni/extns/pn54x/src/common/phNfcTypes_Mapping.h new file mode 100755 index 00000000..9a1a5252 --- /dev/null +++ b/nci/jni/extns/pn54x/src/common/phNfcTypes_Mapping.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef PHNFCTYPES_MAPPING_H_ +#define PHNFCTYPES_MAPPING_H_ + + +typedef phNfc_sData_t phHal_sData_t; +typedef phNfc_sSupProtocol_t phHal_sSupProtocol_t; +#define phHal_eMifareRaw phNfc_eMifareRaw +#define phHal_eMifareAuthentA phNfc_eMifareAuthentA +#define phHal_eMifareAuthentB phNfc_eMifareAuthentB +#define phHal_eMifareRead16 phNfc_eMifareRead16 +#define phHal_eMifareRead phNfc_eMifareRead +#define phHal_eMifareWrite16 phNfc_eMifareWrite16 +#define phHal_eMifareWrite4 phNfc_eMifareWrite4 +#define phHal_eMifareInc phNfc_eMifareInc +#define phHal_eMifareDec phNfc_eMifareDec +#define phHal_eMifareTransfer phNfc_eMifareTransfer +#define phHal_eMifareRestore phNfc_eMifareRestore +#define phHal_eMifareReadSector phNfc_eMifareReadSector +#define phHal_eMifareWriteSector phNfc_eMifareWriteSector +#define phHal_eMifareReadN phNfc_eMifareReadN +#define phHal_eMifareWriteN phNfc_eMifareWriteN +#define phHal_eMifareSectorSel phNfc_eMifareSectorSel +#define phHal_eMifareAuth phNfc_eMifareAuth +#define phHal_eMifareProxCheck phNfc_eMifareProxCheck +#define phHal_eMifareInvalidCmd phNfc_eMifareInvalidCmd + +typedef phNfc_eMifareCmdList_t phHal_eMifareCmdList_t; + +typedef phNfc_uCmdList_t phHal_uCmdList_t; +typedef phNfc_sRemoteDevInformation_t phHal_sRemoteDevInformation_t; +typedef phNfc_sRemoteDevInformation_t phLibNfc_sRemoteDevInformation_t; +#endif /* PHNFCTYPES_MAPPING_H_ */ diff --git a/nci/jni/extns/pn54x/src/log/phNxpLog.c b/nci/jni/extns/pn54x/src/log/phNxpLog.c new file mode 100755 index 00000000..fb3e8adf --- /dev/null +++ b/nci/jni/extns/pn54x/src/log/phNxpLog.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2015 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. + */ + +#include <string.h> +#if !defined (NXPLOG__H_INCLUDED) +# include "phNxpLog.h" +# include "phNxpConfig.h" +#endif +#include <cutils/properties.h> + +const char * NXPLOG_ITEM_EXTNS = "NxpExtns"; +const char * NXPLOG_ITEM_NCIHAL = "NxpHal"; +const char * NXPLOG_ITEM_NCIX = "NxpNciX"; +const char * NXPLOG_ITEM_NCIR = "NxpNciR"; +const char * NXPLOG_ITEM_FWDNLD = "NxpFwDnld"; +const char * NXPLOG_ITEM_TML = "NxpTml"; + +#ifdef NXP_HCI_REQ +const char * NXPLOG_ITEM_HCPX = "NxpHcpX"; +const char * NXPLOG_ITEM_HCPR = "NxpHcpR"; +#endif /*NXP_HCI_REQ*/ + +/* global log level structure */ +nci_log_level_t gLog_level; + + +/******************************************************************************* + * + * Function phNxpLog_SetGlobalLogLevel + * + * Description Sets the global log level for all modules. + * This value is set by Android property nfc.nxp_log_level_global. + * If value can be overridden by module log level. + * + * Returns The value of global log level + * + ******************************************************************************/ +static uint8_t phNxpLog_SetGlobalLogLevel (void) +{ + uint8_t level = NXPLOG_DEFAULT_LOGLEVEL; + unsigned long num = 0; + char valueStr [PROPERTY_VALUE_MAX] = {0}; + + int len = property_get (PROP_NAME_NXPLOG_GLOBAL_LOGLEVEL, valueStr, ""); + if (len > 0) + { + /* let Android property override .conf variable */ + sscanf (valueStr, "%lu", &num); + level = (unsigned char) num; + } + memset(&gLog_level, level, sizeof(nci_log_level_t)); + return level; +} + +/******************************************************************************* + * + * Function phNxpLog_SetHALLogLevel + * + * Description Sets the HAL layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetHALLogLevel (uint8_t level) +{ + unsigned long num = 0; + int len; + char valueStr [PROPERTY_VALUE_MAX] = {0}; + + if (GetNxpNumValue (NAME_NXPLOG_HAL_LOGLEVEL, &num, sizeof(num))) + { + gLog_level.hal_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;; + } + + len = property_get (PROP_NAME_NXPLOG_HAL_LOGLEVEL, valueStr, ""); + if (len > 0) + { + /* let Android property override .conf variable */ + sscanf (valueStr, "%lu", &num); + gLog_level.hal_log_level = (unsigned char) num; + } + + return; +} + +/******************************************************************************* + * + * Function phNxpLog_SetExtnsLogLevel + * + * Description Sets the Extensions layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetExtnsLogLevel (uint8_t level) +{ + unsigned long num = 0; + int len; + char valueStr [PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue (NAME_NXPLOG_EXTNS_LOGLEVEL, &num, sizeof(num))) + { + gLog_level.extns_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;; + } + + len = property_get (PROP_NAME_NXPLOG_EXTNS_LOGLEVEL, valueStr, ""); + if (len > 0) + { + /* let Android property override .conf variable */ + sscanf (valueStr, "%lu", &num); + gLog_level.extns_log_level = (unsigned char) num; + } + + return; +} + +/******************************************************************************* + * + * Function phNxpLog_SetTmlLogLevel + * + * Description Sets the TML layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetTmlLogLevel (uint8_t level) +{ + unsigned long num = 0; + int len; + char valueStr [PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue (NAME_NXPLOG_TML_LOGLEVEL, &num, sizeof(num))) + { + gLog_level.tml_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;; + } + + len = property_get (PROP_NAME_NXPLOG_TML_LOGLEVEL, valueStr, ""); + if (len > 0) + { + /* let Android property override .conf variable */ + sscanf (valueStr, "%lu", &num); + gLog_level.tml_log_level = (unsigned char) num; + } + + return; +} + +/******************************************************************************* + * + * Function phNxpLog_SetDnldLogLevel + * + * Description Sets the FW download layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetDnldLogLevel (uint8_t level) +{ + unsigned long num = 0; + int len; + char valueStr [PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue (NAME_NXPLOG_FWDNLD_LOGLEVEL, &num, sizeof(num))) + { + gLog_level.dnld_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;; + } + + len = property_get (PROP_NAME_NXPLOG_FWDNLD_LOGLEVEL, valueStr, ""); + if (len > 0) + { + /* let Android property override .conf variable */ + sscanf (valueStr, "%lu", &num); + gLog_level.dnld_log_level = (unsigned char) num; + } + + return; +} + +/******************************************************************************* + * + * Function phNxpLog_SetNciTxLogLevel + * + * Description Sets the NCI transaction layer log level. + * + * Returns void + * + ******************************************************************************/ +static void phNxpLog_SetNciTxLogLevel (uint8_t level) +{ + unsigned long num = 0; + int len; + char valueStr [PROPERTY_VALUE_MAX] = {0}; + if (GetNxpNumValue (NAME_NXPLOG_NCIX_LOGLEVEL, &num, sizeof(num))) + { + gLog_level.ncix_log_level = (level > (unsigned char) num) ? level : (unsigned char) num; + } + if (GetNxpNumValue (NAME_NXPLOG_NCIR_LOGLEVEL, &num, sizeof(num))) + { + gLog_level.ncir_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;; + } + + len = property_get (PROP_NAME_NXPLOG_NCI_LOGLEVEL, valueStr, ""); + if (len > 0) + { + /* let Android property override .conf variable */ + sscanf (valueStr, "%lu", &num); + gLog_level.ncix_log_level = (unsigned char) num; + gLog_level.ncir_log_level = (unsigned char) num; + } + + return; +} + +/****************************************************************************** + * Function phNxpLog_InitializeLogLevel + * + * Description Initialize and get log level of module from libnfc-nxp.conf or + * Android runtime properties. + * The Android property nfc.nxp_global_log_level is to + * define log level for all modules. Modules log level will override global level. + * The Android property will override the level + * in libnfc-nxp.conf + * + * Android property names: + * nfc.nxp_log_level_global * defines log level for all modules + * nfc.nxp_log_level_extns * extensions module log + * nfc.nxp_log_level_hal * Hal module log + * nfc.nxp_log_level_dnld * firmware download module log + * nfc.nxp_log_level_tml * TML module log + * nfc.nxp_log_level_nci * NCI transaction log + * + * Log Level values: + * NXPLOG_LOG_SILENT_LOGLEVEL 0 * No trace to show + * NXPLOG_LOG_ERROR_LOGLEVEL 1 * Show Error trace only + * NXPLOG_LOG_WARN_LOGLEVEL 2 * Show Warning trace and Error trace + * NXPLOG_LOG_DEBUG_LOGLEVEL 3 * Show all traces + * + * Returns void + * + ******************************************************************************/ +void phNxpLog_InitializeLogLevel(void) +{ + uint8_t level = phNxpLog_SetGlobalLogLevel (); + phNxpLog_SetHALLogLevel (level); + phNxpLog_SetExtnsLogLevel (level); + phNxpLog_SetTmlLogLevel (level); + phNxpLog_SetDnldLogLevel (level); + phNxpLog_SetNciTxLogLevel (level); + + ALOGD ("%s: global =%u, Fwdnld =%u, extns =%u, \ + hal =%u, tml =%u, ncir =%u, \ + ncix =%u", \ + __FUNCTION__, gLog_level.global_log_level, gLog_level.dnld_log_level, + gLog_level.extns_log_level, gLog_level.hal_log_level, gLog_level.tml_log_level, + gLog_level.ncir_log_level, gLog_level.ncix_log_level); + + return; +} diff --git a/nci/jni/extns/pn54x/src/log/phNxpLog.h b/nci/jni/extns/pn54x/src/log/phNxpLog.h new file mode 100755 index 00000000..af91d3d2 --- /dev/null +++ b/nci/jni/extns/pn54x/src/log/phNxpLog.h @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2015 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. + */ + +#if !defined (NXPLOG__H_INCLUDED) +#define NXPLOG__H_INCLUDED + +#include <cutils/log.h> + +typedef struct nci_log_level +{ + uint8_t global_log_level; + uint8_t extns_log_level; + uint8_t hal_log_level; + uint8_t dnld_log_level; + uint8_t tml_log_level; + uint8_t ncix_log_level; + uint8_t ncir_log_level; +} nci_log_level_t; + +/* global log level Ref */ +extern nci_log_level_t gLog_level; + +/* define log module included when compile */ +#define ENABLE_EXTNS_TRACES TRUE +#define ENABLE_HAL_TRACES TRUE +#define ENABLE_TML_TRACES TRUE +#define ENABLE_FWDNLD_TRACES TRUE +#define ENABLE_NCIX_TRACES TRUE +#define ENABLE_NCIR_TRACES TRUE + +#define ENABLE_HCPX_TRACES FALSE +#define ENABLE_HCPR_TRACES FALSE + +/* ####################### Set the log module name in .conf file ########################## */ +#define NAME_NXPLOG_EXTNS_LOGLEVEL "NXPLOG_EXTNS_LOGLEVEL" +#define NAME_NXPLOG_HAL_LOGLEVEL "NXPLOG_NCIHAL_LOGLEVEL" +#define NAME_NXPLOG_NCIX_LOGLEVEL "NXPLOG_NCIX_LOGLEVEL" +#define NAME_NXPLOG_NCIR_LOGLEVEL "NXPLOG_NCIR_LOGLEVEL" +#define NAME_NXPLOG_FWDNLD_LOGLEVEL "NXPLOG_FWDNLD_LOGLEVEL" +#define NAME_NXPLOG_TML_LOGLEVEL "NXPLOG_TML_LOGLEVEL" + +/* ####################### Set the log module name by Android property ########################## */ +#define PROP_NAME_NXPLOG_GLOBAL_LOGLEVEL "nfc.nxp_log_level_global" +#define PROP_NAME_NXPLOG_EXTNS_LOGLEVEL "nfc.nxp_log_level_extns" +#define PROP_NAME_NXPLOG_HAL_LOGLEVEL "nfc.nxp_log_level_hal" +#define PROP_NAME_NXPLOG_NCI_LOGLEVEL "nfc.nxp_log_level_nci" +#define PROP_NAME_NXPLOG_FWDNLD_LOGLEVEL "nfc.nxp_log_level_dnld" +#define PROP_NAME_NXPLOG_TML_LOGLEVEL "nfc.nxp_log_level_tml" + +/* ####################### Set the logging level for EVERY COMPONENT here ######################## :START: */ +#define NXPLOG_LOG_SILENT_LOGLEVEL 0x00 +#define NXPLOG_LOG_ERROR_LOGLEVEL 0x01 +#define NXPLOG_LOG_WARN_LOGLEVEL 0x02 +#define NXPLOG_LOG_DEBUG_LOGLEVEL 0x03 +/* ####################### Set the default logging level for EVERY COMPONENT here ########################## :END: */ + + +/* The Default log level for all the modules. */ +#define NXPLOG_DEFAULT_LOGLEVEL NXPLOG_LOG_ERROR_LOGLEVEL + + +/* ################################################################################################################ */ +/* ############################################### Component Names ################################################ */ +/* ################################################################################################################ */ + +extern const char * NXPLOG_ITEM_EXTNS; /* Android logging tag for NxpExtns */ +extern const char * NXPLOG_ITEM_NCIHAL; /* Android logging tag for NxpNciHal */ +extern const char * NXPLOG_ITEM_NCIX; /* Android logging tag for NxpNciX */ +extern const char * NXPLOG_ITEM_NCIR; /* Android logging tag for NxpNciR */ +extern const char * NXPLOG_ITEM_FWDNLD; /* Android logging tag for NxpFwDnld */ +extern const char * NXPLOG_ITEM_TML; /* Android logging tag for NxpTml */ + +#ifdef NXP_HCI_REQ +extern const char * NXPLOG_ITEM_HCPX; /* Android logging tag for NxpHcpX */ +extern const char * NXPLOG_ITEM_HCPR; /* Android logging tag for NxpHcpR */ +#endif /*NXP_HCI_REQ*/ + +/* ######################################## Defines used for Logging data ######################################### */ +#ifdef NXP_VRBS_REQ +#define NXPLOG_FUNC_ENTRY(COMP) \ + LOG_PRI( ANDROID_LOG_VERBOSE, (COMP), "+:%s", (__FUNCTION__)) +#define NXPLOG_FUNC_EXIT(COMP) \ + LOG_PRI(ANDROID_LOG_VERBOSE, (COMP), "-:%s", (__FUNCTION__)) +#endif /*NXP_VRBS_REQ*/ + +/* ################################################################################################################ */ +/* ######################################## Logging APIs of actual modules ######################################## */ +/* ################################################################################################################ */ +/* Logging APIs used by NxpExtns module */ +#if (ENABLE_EXTNS_TRACES == TRUE ) +#define NXPLOG_EXTNS_D(...) {if (gLog_level.extns_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_EXTNS, __VA_ARGS__);} +#define NXPLOG_EXTNS_W(...) {if (gLog_level.extns_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_EXTNS, __VA_ARGS__);} +#define NXPLOG_EXTNS_E(...) {if (gLog_level.extns_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_EXTNS, __VA_ARGS__);} +#else +#define NXPLOG_EXTNS_D(...) +#define NXPLOG_EXTNS_W(...) +#define NXPLOG_EXTNS_E(...) +#endif /* Logging APIs used by NxpExtns module */ + +/* Logging APIs used by NxpNciHal module */ +#if (ENABLE_HAL_TRACES == TRUE ) +#define NXPLOG_NCIHAL_D(...) {if (gLog_level.hal_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_NCIHAL, __VA_ARGS__);} +#define NXPLOG_NCIHAL_W(...) {if (gLog_level.hal_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_NCIHAL, __VA_ARGS__);} +#define NXPLOG_NCIHAL_E(...) {if (gLog_level.hal_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_NCIHAL, __VA_ARGS__);} +#else +#define NXPLOG_NCIHAL_D(...) +#define NXPLOG_NCIHAL_W(...) +#define NXPLOG_NCIHAL_E(...) +#endif /* Logging APIs used by HAL module */ + +/* Logging APIs used by NxpNciX module */ +#if (ENABLE_NCIX_TRACES == TRUE ) +#define NXPLOG_NCIX_D(...) {if (gLog_level.ncix_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_NCIX, __VA_ARGS__);} +#define NXPLOG_NCIX_W(...) {if (gLog_level.ncix_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_NCIX, __VA_ARGS__);} +#define NXPLOG_NCIX_E(...) {if (gLog_level.ncix_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_NCIX, __VA_ARGS__);} +#else +#define NXPLOG_NCIX_D(...) +#define NXPLOG_NCIX_W(...) +#define NXPLOG_NCIX_E(...) +#endif /* Logging APIs used by NCIx module */ + +/* Logging APIs used by NxpNciR module */ +#if (ENABLE_NCIR_TRACES == TRUE ) +#define NXPLOG_NCIR_D(...) {if (gLog_level.ncir_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_NCIR, __VA_ARGS__);} +#define NXPLOG_NCIR_W(...) {if (gLog_level.ncir_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_NCIR, __VA_ARGS__);} +#define NXPLOG_NCIR_E(...) {if (gLog_level.ncir_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_NCIR, __VA_ARGS__);} +#else +#define NXPLOG_NCIR_D(...) +#define NXPLOG_NCIR_W(...) +#define NXPLOG_NCIR_E(...) +#endif /* Logging APIs used by NCIR module */ + +/* Logging APIs used by NxpFwDnld module */ +#if (ENABLE_FWDNLD_TRACES == TRUE ) +#define NXPLOG_FWDNLD_D(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#define NXPLOG_FWDNLD_W(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#define NXPLOG_FWDNLD_E(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#else +#define NXPLOG_FWDNLD_D(...) +#define NXPLOG_FWDNLD_W(...) +#define NXPLOG_FWDNLD_E(...) +#endif /* Logging APIs used by NxpFwDnld module */ + +/* Logging APIs used by NxpTml module */ +#if (ENABLE_TML_TRACES == TRUE ) +#define NXPLOG_TML_D(...) {if (gLog_level.tml_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_TML, __VA_ARGS__);} +#define NXPLOG_TML_W(...) {if (gLog_level.tml_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_TML, __VA_ARGS__);} +#define NXPLOG_TML_E(...) {if (gLog_level.tml_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_TML, __VA_ARGS__);} +#else +#define NXPLOG_TML_D(...) +#define NXPLOG_TML_W(...) +#define NXPLOG_TML_E(...) +#endif /* Logging APIs used by NxpTml module */ + +#ifdef NXP_HCI_REQ +/* Logging APIs used by NxpHcpX module */ +#if (ENABLE_HCPX_TRACES == TRUE ) +#define NXPLOG_HCPX_D(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#define NXPLOG_HCPX_W(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#define NXPLOG_HCPX_E(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#else +#define NXPLOG_HCPX_D(...) +#define NXPLOG_HCPX_W(...) +#define NXPLOG_HCPX_E(...) +#endif /* Logging APIs used by NxpHcpX module */ + +/* Logging APIs used by NxpHcpR module */ +#if (ENABLE_HCPR_TRACES == TRUE ) +#define NXPLOG_HCPR_D(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI (ANDROID_LOG_DEBUG, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#define NXPLOG_HCPR_W(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI (ANDROID_LOG_WARN, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#define NXPLOG_HCPR_E(...) {if (gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI (ANDROID_LOG_ERROR, NXPLOG_ITEM_FWDNLD, __VA_ARGS__);} +#else +#define NXPLOG_HCPR_D(...) +#define NXPLOG_HCPR_W(...) +#define NXPLOG_HCPR_E(...) +#endif /* Logging APIs used by NxpHcpR module */ +#endif /* NXP_HCI_REQ */ + +#ifdef NXP_VRBS_REQ +#if (ENABLE_EXTNS_TRACES == TRUE ) +#define NXPLOG_EXTNS_ENTRY() NXPLOG_FUNC_ENTRY (NXPLOG_ITEM_EXTNS) +#define NXPLOG_EXTNS_EXIT() NXPLOG_FUNC_EXIT (NXPLOG_ITEM_EXTNS) +#else +#define NXPLOG_EXTNS_ENTRY() +#define NXPLOG_EXTNS_EXIT() +#endif + +#if (ENABLE_HAL_TRACES == TRUE ) +#define NXPLOG_NCIHAL_ENTRY() NXPLOG_FUNC_ENTRY (NXPLOG_ITEM_NCIHAL) +#define NXPLOG_NCIHAL_EXIT() NXPLOG_FUNC_EXIT (NXPLOG_ITEM_NCIHAL) +#else +#define NXPLOG_NCIHAL_ENTRY() +#define NXPLOG_NCIHAL_EXIT() +#endif + +#if (ENABLE_NCIX_TRACES == TRUE ) +#define NXPLOG_NCIX_ENTRY() NXPLOG_FUNC_ENTRY (NXPLOG_ITEM_NCIX) +#define NXPLOG_NCIX_EXIT() NXPLOG_FUNC_EXIT (NXPLOG_ITEM_NCIX) +#else +#define NXPLOG_NCIX_ENTRY() +#define NXPLOG_NCIX_EXIT() +#endif + +#if (ENABLE_NCIR_TRACES == TRUE ) +#define NXPLOG_NCIR_ENTRY() NXPLOG_FUNC_ENTRY (NXPLOG_ITEM_NCIR) +#define NXPLOG_NCIR_EXIT() NXPLOG_FUNC_EXIT (NXPLOG_ITEM_NCIR) +#else +#define NXPLOG_NCIR_ENTRY() +#define NXPLOG_NCIR_EXIT() +#endif + +#ifdef NXP_HCI_REQ + +#if (ENABLE_HCPX_TRACES == TRUE ) +#define NXPLOG_HCPX_ENTRY() NXPLOG_FUNC_ENTRY (NXPLOG_ITEM_HCPX) +#define NXPLOG_HCPX_EXIT() NXPLOG_FUNC_EXIT (NXPLOG_ITEM_HCPX) +#else +#define NXPLOG_HCPX_ENTRY() +#define NXPLOG_HCPX_EXIT() +#endif + +#if (ENABLE_HCPR_TRACES == TRUE ) +#define NXPLOG_HCPR_ENTRY() NXPLOG_FUNC_ENTRY (NXPLOG_ITEM_HCPR) +#define NXPLOG_HCPR_EXIT() NXPLOG_FUNC_EXIT (NXPLOG_ITEM_HCPR) +#else +#define NXPLOG_HCPR_ENTRY() +#define NXPLOG_HCPR_EXIT() +#endif +#endif /* NXP_HCI_REQ */ + +#endif /* NXP_VRBS_REQ */ + +void phNxpLog_InitializeLogLevel (void); + +#endif /* NXPLOG__H_INCLUDED */ diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc.h b/nci/jni/extns/pn54x/src/mifare/phFriNfc.h new file mode 100755 index 00000000..8aba23b9 --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * NFC FRI Main Header. + */ + +#ifndef PHFRINFC_H +#define PHFRINFC_H +#include <phNfcTypes.h> + +#define LOCK_BITS_CHECK_ENABLE + +#define NFCSTATUS_INVALID_DEVICE_REQUEST (0x10F5) + +/* + * Completion Routine + * + * NFC-FRI components that work in an overlapped style need to provide a function that is compatible + * to this definition. + * It is mandatory to define such a routine for components that interact with other components up or + * down the stack. Moreover, such components shall provide a function within their API to enable the + * setting of the Completion Routine address and parameters. + * + * First Parameter: Context + * Set to the address of the called instance (component instance context structure). For instance, + * a component that needs to give control to a component up the stack needs to call the completion + * routine of the upper component. The value to assign to this parameter is the address of + * the context structure instance of the called component. Such a structure usually contains all + * variables, data or state information a component member needs for operation. The address of the + * upper instance must be known by the lower (completing) instance. The mechanism to ensure that this + * information is present involves the structure phFriNfc_CplRt_t . See its documentation for + * further information. + * + * Second Parameter: Status Value + * The lower layer hands over the completion status via this parameter. The completion + * routine that has been called needs to process the status in a way that is comparable to what + * a regular function return value would require. + * + * The prototype of the component's Process(ing) functions has to be compatible to this + * function pointer declaration for components interacting with others. In other cases, where + * there is no interaction or asynchronous processing the definition of the Process(ing) + * function can be arbitrary, if present at all. + */ +typedef void (*pphFriNfc_Cr_t) (void*, NFCSTATUS); + +/* + * Completion Routine structure + * + * This structure finds itself within each component that requires to report completion + * to an upper (calling) component. + * Depending on the actual implementation (static or dynamic completion information) the stack + * Initialization or the calling component needs to inform the initialized or called component + * about the completion path. This information is submitted via this structure. + */ +typedef struct phFriNfc_CplRt +{ + pphFriNfc_Cr_t CompletionRoutine; /* Address of the upper Layer's Process(ing) function to call upon completion. + * The stack initializer (or depending on the implementation: the calling component) + * needs to set this member to the address of the function that needs to be within + * the completion path: A calling component would give its own processing function + * address to the lower layer. + */ + void *Context; /* Instance address (context) parameter. + * The stack initializer (or depending on the implementation: the calling component) + * needs to set this member to the address of the component context structure instance + * within the completion path: A calling component would give its own instance address + * to the lower layer. + */ +} phFriNfc_CplRt_t; + +#endif /* __PHFRINFC_H__ */ diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifStdFormat.c b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifStdFormat.c new file mode 100755 index 00000000..7018e812 --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifStdFormat.c @@ -0,0 +1,1385 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * Mifare Standard Format implementation + */ + +#include <phFriNfc_MifStdFormat.h> +#include <phNxpExtns_MifareStd.h> +#include <phNfcCompId.h> +#include <phNxpLog.h> + +/* Function prototype declarations */ +static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, uint16_t BlockNo); +static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, NFCSTATUS Status); +static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t BlockNo, const uint8_t *RecvBuf, const uint8_t AcsBits1[], const uint8_t AcsBits2[]); +static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes, uint8_t Sector[]); +static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static void phFriNfc_MfStd_H_StrNdefData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +static int phFriNfc_MfStd_MemCompare(void *s1, void *s2, unsigned int n ); + +/* + * Enum definition contains format states + */ +typedef enum Mfc_format_state{ + MFC_FORMAT_INIT = 0x00, + MFC_FORMAT_NFC_KEY, + MFC_FORMAT_DEF_KEY, + MFC_FORMAT_INVALID +}MFC_FORMAT_STATE; + +/* format key status */ +static MFC_FORMAT_STATE FormatKeyState = MFC_FORMAT_INIT; + +/******************************************************************************* +** +** Function phFriNfc_MfStd_Reset +** +** Description Resets the component instance to the initial state and initializes the +** internal variables. +** +** Returns none +** +*******************************************************************************/ +void phFriNfc_MfStd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + uint8_t NfcForSectArray[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT, + MADSectArray[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K; + + /* Authentication state */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_VAL_1; + + /* Set default key for A or B */ + memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.Default_KeyA_OR_B, + PH_FRINFC_MFSTD_FMT_DEFAULT_KEY, /* 0xFF */ + PH_FRINFC_MFSTD_FMT_VAL_6); + + /* MAD sector key A */ + memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_KeyA, + MADSectArray, /*PH_FRINFC_MFSTD_FMT_VAL_0, */ + PH_FRINFC_MFSTD_FMT_VAL_6); + + /* Copy access bits for MAD sectors */ + memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits, + &MADSectArray[PH_FRINFC_MFSTD_FMT_VAL_6], + PH_FRINFC_MFSTD_FMT_VAL_3); + + /* NFC forum sector key A */ + (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_KeyA, + NfcForSectArray, /*PH_FRINFC_MFSTD_FMT_VAL_0, */ + PH_FRINFC_MFSTD_FMT_VAL_6); + + /* Copy access bits for NFC forum sectors */ + (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits, + &NfcForSectArray[PH_FRINFC_MFSTD_FMT_VAL_6], + PH_FRINFC_MFSTD_FMT_VAL_3); + + /* Sector compliant array initialised to 0 */ + memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl, + PH_FRINFC_MFSTD_FMT_VAL_0, /* 0x00 */ + PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K); + + NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_0; + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK; + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_Format +** +** Description The function initiates and formats the Smart Card.After this formation, remote +** card would be properly initialized and Ndef Compliant. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +NFCSTATUS phFriNfc_MfStd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB ) +{ + NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_INVALID_PARAMETER); + uint8_t index = PH_FRINFC_MFSTD_FMT_VAL_0; + + if(ScrtKeyB != NULL) + { + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = + PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK; + /* Store Key B in the context */ + while(index < PH_FRINFC_MFSTD_FMT_VAL_6) + { + NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB[index] = ScrtKeyB[index]; + index++; + } + /* Set the state */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + /* Initialize current block to the first sector trailer */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = PH_FRINFC_MFSTD_FMT_VAL_3; + /* Set the authenticate state */ + if( MFC_FORMAT_DEF_KEY == FormatKeyState) + { + FormatKeyState = MFC_FORMAT_INIT; + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY; + } + else + { + FormatKeyState = MFC_FORMAT_NFC_KEY; + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY; /* Key Chnage for some cards */ + } + /* Start authentication */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + } + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_Process +** +** Description Completion Routine: This function is called by the lower layer (OVR HAL) +** when an I/O operation has finished. The internal state machine decides +** whether to call into the lower device again or to complete the process +** by calling into the upper layer's completion routine, stored within this +** component's context (phFriNfc_sNdefSmtCrdFmt_t). +** +** Returns none +** +*******************************************************************************/ +void phFriNfc_MfStd_Process(void *Context, NFCSTATUS Status) +{ + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context; + /* Copy the formatting status */ + NdefSmtCrdFmt->FmtProcStatus = Status; + + if(Status == NFCSTATUS_SUCCESS) + { + switch(NdefSmtCrdFmt->State) + { + case PH_FRINFC_MFSTD_FMT_AUTH_SECT: + Status = phFriNfc_MfStd_H_ProAuth(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_DIS_CON: + Status = phFriNfc_MfStd_H_CallCon(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_CON: + if( MFC_FORMAT_DEF_KEY == FormatKeyState) + { + /* retry the format with other key */ + Mfc_FormatNdef(current_key,6); + return; + } + Status = phFriNfc_MfStd_H_ProCon(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_RD_SECT_TR: + Status = phFriNfc_MfStd_H_ProRdSectTr(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_WR_SECT_TR: + Status = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK: + Status = phFriNfc_MfStd_H_ProWrMADBlk(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_WR_TLV: + break; + + case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK: + Status = phFriNfc_MfStd_H_ProUpdMADBlk(NdefSmtCrdFmt); + break; + + default: + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_INVALID_DEVICE_REQUEST); + break; + } + } + else + { + switch(NdefSmtCrdFmt->State) + { + case PH_FRINFC_MFSTD_FMT_AUTH_SECT: + if(MFC_FORMAT_NFC_KEY == FormatKeyState) + { + FormatKeyState = MFC_FORMAT_DEF_KEY; + } + Status = phFriNfc_MfStd_H_ProErrAuth(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_WR_SECT_TR: + Status = phFriNfc_MfStd_H_ErrWrSectTr(NdefSmtCrdFmt); + break; + + case PH_FRINFC_MFSTD_FMT_RD_SECT_TR: + Status = phFriNfc_MfStd_H_ErrRdSectTr(NdefSmtCrdFmt); + break; + + default: + Status = NdefSmtCrdFmt->FmtProcStatus; + break; + } + } + + /* Status is not success then call completion routine */ + if(Status != NFCSTATUS_PENDING) + { + phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status); + } + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_FillSendBuf +** +** Description This function fills the send buffer for transceive function +** +** Returns none +** +*******************************************************************************/ +static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, uint16_t BlockNo) +{ +// void *mem = NULL; /*commented to eliminate unused variable warning*/ + uint8_t MADSectTr1k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K, /* MAD key A, + Access bits and GPB of MAD sector */ + MADSectTr2k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_2K, /* MAD key A, + Access bits and GPB of MAD sector */ + MADSectTr4k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_4K, /* MAD key A, + Access bits and GPB of MAD sector */ + NFCSectTr[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT, /* NFC forum key A, + Access bits and GPB of NFC sector */ + NDEFMsgTLV[16] = {0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, /* NDEF message TLV (INITIALISED state) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, + MADBlk[16] = {0x0F, 0x00, 0x03, 0xE1, 0x03, 0xE1, + 0x03, 0xE1, 0x03, 0xE1, + 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1}; + /* Block number in send buffer */ + NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_0] = (uint8_t)BlockNo; + /* Initialize send receive length */ + *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_MFSTD_FMT_MAX_RECV_LENGTH; + + /* Depending on the different state, fill the send buffer */ + switch(NdefSmtCrdFmt->State) + { + case PH_FRINFC_MFSTD_FMT_AUTH_SECT: + /* Depending on the authentication state, fill the send buffer */ + switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState) + { + case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY: + case PH_FRINFC_MFSTD_FMT_AUTH_KEYB: + /* Fill send buffer with the default key */ + PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_DEF(mem); + break; + + case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY: + /* Fill send buffer with NFC forum sector key */ + PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_NFCSECT_KEYA(mem); + break; + + case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB: + /* Fill send buffer with NFC forum sector key */ + PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_SCRT_KEY(mem); + break; + + case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY: + default: + /* Fill send buffer with MAD sector key */ + PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_MADSECT_KEYA(mem); + break; + } + break; + + case PH_FRINFC_MFSTD_FMT_RD_SECT_TR: + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; + + /* Send length is always one for read operation */ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_1; + break; + + case PH_FRINFC_MFSTD_FMT_WR_SECT_TR: + /* Fill send buffer for writing sector trailer */ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16; + /* Copy the relevant sector trailer value in the buffer */ + switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock) + { + case PH_FRINFC_MFSTD_FMT_VAL_3: + if (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) + { + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + MADSectTr1k, + sizeof(MADSectTr1k)); + } + else if (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD) + { + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + MADSectTr2k, + sizeof(MADSectTr2k)); + } + else + { + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + MADSectTr4k, + sizeof(MADSectTr4k)); + } + break; + case 67: + (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + MADSectTr4k, + sizeof(MADSectTr4k)); + break; + default: + (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + NFCSectTr, + sizeof(NFCSectTr)); + break; + } + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_11], + NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB, + sizeof(NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB)); + + /* Send length is always 17 for write operation */ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH; + break; + + case PH_FRINFC_MFSTD_FMT_WR_TLV: + /* Fill send buffer for writing TLV */ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16; + /* Copy the NDEF message TLV */ + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + NDEFMsgTLV, sizeof(NDEFMsgTLV)); + /* Send length is always 17 for write operation */ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH; + break; + + case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK: + /* Fill send buffer for writing MAD block */ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16; + if((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_2) || + (BlockNo == 65) || (BlockNo == 66)) + { + /* MAD block number 2, 65 and 66 has 0x03, 0xE1 in the + * first two bytes + */ + MADBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x03; + MADBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0xE1; + } + /* Copy the MAD Block values */ + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + MADBlk, sizeof(MADBlk)); + /* Send length is always 17 for write operation */ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH; + break; + + case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK: + default: + /* Fill send buffer for writing MAD block */ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16; + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH; + switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk) + { + case PH_FRINFC_MFSTD_FMT_MAD_BLK_1: + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk, + (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1)); + break; + + case PH_FRINFC_MFSTD_FMT_MAD_BLK_2: + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[16], + (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1)); + break; + + case PH_FRINFC_MFSTD_FMT_MAD_BLK_64: + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32], + (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1)); + break; + + case PH_FRINFC_MFSTD_FMT_MAD_BLK_65: + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[48], + (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1)); + break; + + case PH_FRINFC_MFSTD_FMT_MAD_BLK_66: + default: + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1], + &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[64], + (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1)); + break; + } + break; + } + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_Transceive +** +** Description This function authenticates a block or a sector from the card. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /*set the completion routines for the card operations*/ + NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process; + NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt; + + *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE; + + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_ExtnsTransceive(NdefSmtCrdFmt->pTransceiveInfo, + NdefSmtCrdFmt->Cmd, + NdefSmtCrdFmt->SendRecvBuf, + NdefSmtCrdFmt->SendLength, + NdefSmtCrdFmt->SendRecvLength); + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_CallDisCon +** +** Description This function calls disconnect. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, NFCSTATUS Status) +{ + NFCSTATUS Result = Status; + + /*Set Ndef State*/ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_DIS_CON; + + Result = phNxNciExtns_MifareStd_Reconnect(); + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_CallCon +** +** Description This function calls reconnect. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + /*Set Ndef State*/ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_CON; + + Result = phNxNciExtns_MifareStd_Reconnect(); + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ProCon +** +** Description This function shall process the poll call. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL}; + uint8_t index = PH_FRINFC_MFSTD_FMT_VAL_1; + uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1; + + phFriNfc_MfStd_H_ChangeAuthSt(NdefSmtCrdFmt); + if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK) + { + PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD(); + } + else + { + /* Set the state */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + /* Start authentication */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + } + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ProAuth +** +** Description This function shall process the authenticate call. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Depending on the authentication key check the */ + switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState) + { + case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY: + if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == + PH_FRINFC_MFSTD_FMT_VAL_3) && + (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag == + PH_FRINFC_MFSTD_FMT_VAL_0)) + { + /* Authenticate with default key for block 3 is successful, + * so fill the MAD block of sector 0 + */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + PH_FRINFC_MFSTD_FMT_VAL_1; + /* Write the MAD block */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK; + } + else if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67) + && (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag == + PH_FRINFC_MFSTD_FMT_VAL_0)) + { + /* Authenticate with default key for block 3 is successful, + * so fill the MAD block of sector 64 + */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 64; + /* Write the MAD block */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK; + } + else + { + /* Not a MAD sector */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = + PH_FRINFC_MFSTD_FMT_VAL_0; + /* Write the MAD block */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR; + } + break; + + case PH_FRINFC_MFSTD_FMT_AUTH_KEYB: + if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_1) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_2) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_64) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_65) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_66)) + { + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk; + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK; + } + else + { + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = + PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK; + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR; + } + + break; + + case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB: + if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_1) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_2) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_64) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_65) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_66)) + { + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk; + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK; + } + else + { + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = + PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK; + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR; + } + break; + + case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY: + case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY: + default: + if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_66) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk == + PH_FRINFC_MFSTD_FMT_MAD_BLK_2)) + { + /* Updating the MAD block is complete */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = + PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK; + /* If Mifare 4k card, write the TLV */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_TLV; + } + else + { + /* Depending on the sector trailer, check the access bit */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_RD_SECT_TR; + } + break; + } + /* Call read, write or authenticate */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ErrWrSectTr +** +** Description This function shall process the error status of the writing sector trailer. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) +{ + NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus; + /* If default key A is used for authentication and if write fails, then try to + * authenticate using key B + */ + if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState == + PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY) + { + /* Change the state to authentication */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + /* internal authenticate state = key B */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB; + /* Now call authenticate */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + } + else + { + Result = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt); + } + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ProRdSectTr +** +** Description This function shall process the read access bit call. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL}, + index = PH_FRINFC_MFSTD_FMT_VAL_1, + SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0; + uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1; + + /* Calculate sector index */ + SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC; + + /* Depending on the sector trailer, check the access bit */ + memcompare = phFriNfc_MfStd_H_ChkAcsBit(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock, + NdefSmtCrdFmt->SendRecvBuf, + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits, + NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits); + + /* Check the sector for ndef compliance */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t) + ((memcompare != PH_FRINFC_MFSTD_FMT_VAL_0)? + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL: + PH_FRINFC_MFSTD_FMT_NDEF_COMPL); + + /* Increment the current block */ + PH_FRINFC_MFSTD_FMT_CUR_BLK_INC(); + SectIndex++; + if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK) + { + PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD(); + } + else + { + /* Set the state */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + /* Set the authenticate state */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = + PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY; + /* Start authentication */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + } + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ProWrSectTr +** +** Description This function shall process the write access bit call. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL}, + index = PH_FRINFC_MFSTD_FMT_VAL_1, + SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0; + uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1; + + /* Calculate sector index */ + SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC; + + /* Sector is ndef compliance */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t) + ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)? + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL: + PH_FRINFC_MFSTD_FMT_NDEF_COMPL); + + /* Increment the current block */ + PH_FRINFC_MFSTD_FMT_CUR_BLK_INC(); + SectIndex++; + if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK) + { + PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD(); + } + else + { + /* Set the state */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + /* Set the authenticate state */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = + PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY; + /* Start authentication */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + } + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ChkAcsBit +** +** Description This function checks access bits of each sector trailer. +** +** Returns compare value +** +*******************************************************************************/ +static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t BlockNo, + const uint8_t *RecvBuf, + const uint8_t AcsBits1[], + const uint8_t AcsBits2[]) +{ + uint32_t mem = PH_FRINFC_MFSTD_FMT_VAL_0; + + /* Compare the access bits read from the sector trailer */ + mem = (uint32_t)(((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_3) || + (BlockNo == 67))? + phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6], + (void*)AcsBits1, + PH_FRINFC_MFSTD_FMT_VAL_3): + phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6], + (void*)AcsBits2, + PH_FRINFC_MFSTD_FMT_VAL_3)); + + return mem; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_WrRdAuth +** +** Description This function writes sector trailer using the block number. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + /* Fill send buffer and send length */ + phFriNfc_MfStd_H_FillSendBuf(NdefSmtCrdFmt, + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock); + /* Call ovrhal transceive */ + Result = phFriNfc_MfStd_H_Transceive(NdefSmtCrdFmt); + + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ChangeAuthSt +** +** Description This function changes authentication state and change the block number if required. +** +** Returns none +** +*******************************************************************************/ +static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + uint8_t SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0; + + if( NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState == + PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB) + { + /* Calculate sector index */ + SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC; + + /* Check the sector for ndef compliance */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL; + + PH_FRINFC_MFSTD_FMT_CUR_BLK_INC(); + } + PH_FRINFC_MFSTD_FMT_NXT_AUTH_STATE(); + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_NdefComplSect +** +** Description This function finds contiguous ndef compliant blocks. +** +** Returns none +** +*******************************************************************************/ + static void phFriNfc_MfStd_H_NdefComplSect(uint8_t CardTypes, uint8_t Sector[]) +{ + uint8_t count = PH_FRINFC_MFSTD_FMT_VAL_0, + NdefComplSectMax = PH_FRINFC_MFSTD_FMT_VAL_0, + NdefComplSectTemp = PH_FRINFC_MFSTD_FMT_VAL_1, + SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0, + MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0, + MaxSect = PH_FRINFC_MFSTD_FMT_VAL_0; + + /* Get the maximum sector depending on the sector */ + MaxSect = ((CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)? + PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K: + ((CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)? + PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K: + PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K)); + /* Sector index */ + NdefComplSectTemp = SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1; + /* Check the sector index depending on the card type */ + while(((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) && + (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) || + ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) && + (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD))|| + ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K) && + (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD))) + { + if (Sector[SectIndex] == + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL) + { + if (MaxCont > count) + { + /* Store the maximum contiguous */ + NdefComplSectMax = NdefComplSectTemp; + count = MaxCont; + } + MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0; + /* Increment the sector index */ + PH_FRINFC_MFSTD_FMT_INCR_SECT; + /* Get the next compliant sector */ + NdefComplSectTemp = SectIndex; + } + else + { + /* Increment the sector index */ + PH_FRINFC_MFSTD_FMT_INCR_SECT; + } + MaxCont ++; + + } + if (MaxCont > count) + { + /* Store the maximum contiguous */ + NdefComplSectMax = NdefComplSectTemp; + count = MaxCont; + } + /* Set the sector value has non ndef compliant which are not present with + * contiguous ndef compliant sectors + */ + if((((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_1)) && (CardTypes + == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) || + ((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)) && (CardTypes + == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) || + ((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)) && (CardTypes + == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)))&& + ((NdefComplSectMax > PH_FRINFC_MFSTD_FMT_VAL_0) && + (NdefComplSectMax < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)))) + { + memset(&Sector[PH_FRINFC_MFSTD_FMT_VAL_1], + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL, + (NdefComplSectMax - PH_FRINFC_MFSTD_FMT_VAL_1)); + + + memset(&Sector[(NdefComplSectMax + count)], + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL, + (MaxSect - (NdefComplSectMax + count))); + } + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ProWrMADBlk +** +** Description This function writes the finds MAD block values. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock) + { + case PH_FRINFC_MFSTD_FMT_VAL_1: + /* MAD blocks, still not completed */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK; + /* MAD block number 2 */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + PH_FRINFC_MFSTD_FMT_VAL_2; + break; + + case PH_FRINFC_MFSTD_FMT_VAL_2: + /* Now write to MAD block is completed */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = + PH_FRINFC_MFSTD_FMT_VAL_1; + /* Now write the sector trailer, so change the state */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR; + /* MAD block number 3 = Sector trailer */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + PH_FRINFC_MFSTD_FMT_VAL_3; + break; + + case 64: + /* MAD blocks, still not completed */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK; + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 65; + break; + + case 65: + /* MAD blocks, still not completed */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK; + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 66; + break; + + case 66: + default: + /* Now write to MAD block is completed */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = + PH_FRINFC_MFSTD_FMT_VAL_1; + /* Now write the sector trailer, so change the state */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR; + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 67; + break; + + } + /* Write the block */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ProErrAuth +** +** Description This function shall process the error status of the authentication. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) +{ + NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus; + uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL}, + index = PH_FRINFC_MFSTD_FMT_VAL_1; + uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1; + + if ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67) && + (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState == + PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)) + { + /* Error in the MAD sector 16, so the remaining sector + * information can't be updated + */ + memset(&NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[16], + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL, + (PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K - 16)); + PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD(); + } + else if(((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock > + PH_FRINFC_MFSTD_FMT_VAL_3) && + (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState != + PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)) || + ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == + PH_FRINFC_MFSTD_FMT_VAL_3) && + (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState < + PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB))) + { + /* Authenticate failed, so disconnect, poll and connect */ + Result = phFriNfc_MfStd_H_CallDisCon(NdefSmtCrdFmt, + Result); + } + else + { + if (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == + PH_FRINFC_MFSTD_FMT_VAL_3) + { + memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl, + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL, + PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K); + } + } + + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ProUpdMADBlk +** +** Description This function shall process the error status of the writing sector trailer. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk) + { + case PH_FRINFC_MFSTD_FMT_MAD_BLK_1: + /* Write the next MAD Block */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t) + PH_FRINFC_MFSTD_FMT_MAD_BLK_2; + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + PH_FRINFC_MFSTD_FMT_MAD_BLK_2; + break; + + case PH_FRINFC_MFSTD_FMT_MAD_BLK_2: + case PH_FRINFC_MFSTD_FMT_MAD_BLK_66: + if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) || + (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == + PH_FRINFC_MFSTD_FMT_MAD_BLK_66)) + { + /* Get the block from where the TLV has to be written */ + phFriNfc_MfStd_H_BlkNoToWrTLV(NdefSmtCrdFmt); + + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = + PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY; + } + else + { + /* Write the next MAD Block */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t) + PH_FRINFC_MFSTD_FMT_MAD_BLK_64; + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + PH_FRINFC_MFSTD_FMT_MAD_BLK_64; + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = + PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB; + } + break; + + case PH_FRINFC_MFSTD_FMT_MAD_BLK_64: + /* Write the next MAD Block */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t) + PH_FRINFC_MFSTD_FMT_MAD_BLK_65; + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + PH_FRINFC_MFSTD_FMT_MAD_BLK_65; + break; + + case PH_FRINFC_MFSTD_FMT_MAD_BLK_65: + default: + /* Write the next MAD Block */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t) + PH_FRINFC_MFSTD_FMT_MAD_BLK_66; + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = + PH_FRINFC_MFSTD_FMT_MAD_BLK_66; + break; + } + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_StrNdefData +** +** Description This function shall store ndef compliant in the MAD array +** which will be later used for updating the MAD sector. +** +** Returns none +** +*******************************************************************************/ +static void phFriNfc_MfStd_H_StrNdefData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) +{ + uint8_t SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1, + index = PH_FRINFC_MFSTD_FMT_VAL_0; + + memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk, + 0x00, + PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K); + + /* Zeroth sector of the Mifare card is MAD sector, CRC is 0x14 */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x14; + /* Info byte is 0x01, because the NDEF application is written and as per the MAD spec, + * the value for miscellaneous application is 0x01 + */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0x01; + + if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD) || + (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)) + { + /* If 4k card then sector number 16 is MAD sector, CRC is 0xE8 */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32] = 0xE8; + /* Info byte is 0x01, because the NDEF application is written and + * as per the MAD spec, + * the value for miscellaneous application is 0x01 + */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[33] = 0x01; + } + /* NDEF information has to be updated from */ + index = PH_FRINFC_MFSTD_FMT_VAL_2; + /* Depending on the card type, check the sector index */ + while (((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) && + (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) || + ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) && + (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) || + ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K) && + (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD))) + { + /* Is the sector ndef compliant? */ + if(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] == + PH_FRINFC_MFSTD_FMT_NDEF_COMPL) + { + /* Ndef compliant sector, update the MAD sector array + * in the context with values 0x03 and 0xE1 + * 0x03 and 0xE1 is NDEF information in MAD sector + */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = + PH_FRINFC_MFSTD_FMT_NDEF_INFO1; + index++; + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = + PH_FRINFC_MFSTD_FMT_NDEF_INFO2; + index++; + } + else + { + /* Not a Ndef compliant sector, update the MAD sector array + * in the context with values 0x00 and 0x00 + * 0x00 and 0x00 is NDEF information in MAD sector + */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00; + index++; + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00; + index++; + } + /* Go to next sector */ + SectIndex++; + /* is the sector, a MAD sector 16? */ + if(SectIndex == PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) + { + /* MAD sector number 16, so skip this sector */ + SectIndex = SectIndex + PH_FRINFC_MFSTD_FMT_VAL_1; + index = index + PH_FRINFC_MFSTD_FMT_VAL_2; + } + } + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_BlkNoToWrTLV +** +** Description This function shall find the ndef compliant +** and calculate the block number to write the NDEF TLV. +** +** Returns none +** +*******************************************************************************/ +static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) +{ + uint8_t SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_1; + while (((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) && + (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) || + ((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) && + (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) || + ((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K) && + (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD))) + { + if (NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] == + (uint8_t)PH_FRINFC_MFSTD_FMT_NDEF_COMPL) + { + /* Get the first NFC forum sector's block */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = (uint16_t) + (((SectIndex & 0xE0) >= 32)? + (128 + ((SectIndex % 32) * 16)): + (SectIndex * (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_4)); + /* Break out of the loop */ + SectIndex += (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K; + } + SectIndex++; + } + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_H_ErrRdSectTr +** +** Description This function shall process the error status of the reading sector trailer. +** +** Returns NFCSTATUS_PENDING if successful +** Other values if an error has occurred +** +*******************************************************************************/ +static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) +{ + NFCSTATUS Result = NdefSmtCrdFmt->FmtProcStatus; + uint8_t Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL}, + index = PH_FRINFC_MFSTD_FMT_VAL_1, + SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0; + uint32_t memcompare = PH_FRINFC_MFSTD_FMT_VAL_1; + /* If default key A is used for authentication and if write fails, then try to + * authenticate using key B + */ + if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState == + PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY) + { + /* Change the state to authentication */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + /* internal authenticate state = key B */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB; + /* Now call authenticate */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + } + else + { + /* Calculate sector index */ + SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC; + + /* Sector is ndef compliance */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t) + ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)? + PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL: + PH_FRINFC_MFSTD_FMT_NDEF_COMPL); + + /* Increment the current block */ + PH_FRINFC_MFSTD_FMT_CUR_BLK_INC(); + SectIndex++; + if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK) + { + PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD(); + } + else + { + /* Set the state */ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; + /* Set the authenticate state */ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = + PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY; + /* Start authentication */ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); + } + } + return Result; +} + +/******************************************************************************* +** +** Function phFriNfc_MfStd_MemCompare +** +** Description This function shall process memory comparison. +** +** Returns 0 if memory is same +** Not 0 if different +** +*******************************************************************************/ +static int phFriNfc_MfStd_MemCompare(void *s1, void *s2, unsigned int n ) +{ + int8_t diff = 0; + int8_t *char_1 =(int8_t *)s1; + int8_t *char_2 =(int8_t *)s2; + if(NULL == s1 || NULL == s2) + { + NXPLOG_EXTNS_E("NULL pointer passed to memcompare"); + } + else + { + for(;((n>0)&&(diff==0));n--,char_1++,char_2++) + { + diff = *char_1 - *char_2; + } + } + return (int)diff; +} diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifStdFormat.h b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifStdFormat.h new file mode 100755 index 00000000..ac58453d --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifStdFormat.h @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * Mifare Standard Format implementation + */ + +#ifndef PHFRINFC_MIFSTDFORMAT_H +#define PHFRINFC_MIFSTDFORMAT_H + +#include <phFriNfc.h> +#include <phNfcStatus.h> +#include <phNfcTypes.h> +#include <phFriNfc_SmtCrdFmt.h> + +/********************* Definitions and structures *****************************/ + +/* + * Mifare standard -progress states + */ +#define PH_FRINFC_MFSTD_FMT_RESET_INIT 0 /* Reset state */ +#define PH_FRINFC_MFSTD_FMT_AUTH_SECT 1 /* Sector authentication is in progress */ +#define PH_FRINFC_MFSTD_FMT_DIS_CON 2 /* Disconnect is in progress */ +#define PH_FRINFC_MFSTD_FMT_CON 3 /* Connect is in progress */ +#define PH_FRINFC_MFSTD_FMT_POLL 4 /* Poll is in progress */ +#define PH_FRINFC_MFSTD_FMT_RD_SECT_TR 5 /* Read sector trailer is in progress */ +#define PH_FRINFC_MFSTD_FMT_WR_SECT_TR 6 /* Write sector trailer is in progress */ +#define PH_FRINFC_MFSTD_FMT_WR_TLV 7 /* Write sector trailer is in progress */ +#define PH_FRINFC_MFSTD_FMT_WR_MAD_BLK 8 /* Write MAD is in progress */ +#define PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK 9 /* Write MAD is in progress */ + +/* + * Mifare standard -Authenticate states + */ +#define PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY 0 /* Trying to authenticate with the default key */ +#define PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY 1 /* Trying to authenticate with the MAD key */ +#define PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY 2 /* Trying to authenticate with the NFC forum key */ +#define PH_FRINFC_MFSTD_FMT_AUTH_KEYB 3 /* Trying to authenticate with key B */ +#define PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB 4 /* Trying to authenticate with secret key B */ + +/* + * Mifare standard - Update MAD block flag + */ +#define PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK 0 /* Not a MAD block */ +#define PH_FRINFC_MFSTD_FMT_MAD_BLK_1 1 /* MAD block number 1 */ +#define PH_FRINFC_MFSTD_FMT_MAD_BLK_2 2 /* MAD block number 2 */ +#define PH_FRINFC_MFSTD_FMT_MAD_BLK_64 64 /* MAD block number 64 (only used for Mifare 4k card) */ +#define PH_FRINFC_MFSTD_FMT_MAD_BLK_65 65 /* MAD block number 65 (only used for Mifare 4k card) */ +#define PH_FRINFC_MFSTD_FMT_MAD_BLK_66 66 /* MAD block number 66 (only used for Mifare 4k card) */ + +/* + * Mifare standard - Update MAD block flag +*/ +#define PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K {0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0x78,0x77,0x88,0xC1} +#define PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_2K {0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0x78,0x77,0x88,0xC1} +#define PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_4K {0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0x78,0x77,0x88,0xC2} +#define PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT {0xD3,0xF7,0xD3,0xF7,0xD3,0xF7,0x7F,0x07,0x88,0x40} + +/* + * Mifare standard - Key and access bit constants + */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_KEYA0 0xD3 /* NFC forum sector key A */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_KEYA1 0xF7 /* NFC forum sector key A */ + +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA0 0xA0 /* MAD sector key A */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA1 0xA1 /* MAD sector key A */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA2 0xA2 /* MAD sector key A */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA3 0xA3 /* MAD sector key A */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA4 0xA4 /* MAD sector key A */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA5 0xA5 /* MAD sector key A */ + +#define PH_FRINFC_MFSTD_FMT_DEFAULT_KEY 0xFF /* Default key A or B */ + +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_ACS6 0x78 /* MAD sector access bits 6 */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_ACS7 0x77 /* MAD sector access bits 7 */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_ACS8 0x88 /* MAD sector access bits 8 */ +#define PH_FRINFC_MFSTD_FMT_MAD_SECT_GPB 0xC1 /* MAD sector GPB */ + +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RW6 0x7F /* NFC forum sector access bits 6 for read write */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RW7 0x07 /* NFC forum sector access bits 7 for read write */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RW8 0x88 /* NFC forum sector access bits 8 for read write */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_GPB_RW 0x40 /* NFC forum sector GPB for read write */ + +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RO6 0x07 /* NFC forum sector access bits 6 for read only */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RO7 0x8F /* NFC forum sector access bits 7 for read only */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RO8 0x0F /* NFC forum sector access bits 8 for read only */ +#define PH_FRINFC_MFSTD_FMT_NFC_SECT_GPB_R0 0x43 /* NFC forum sector GPB for read only */ + +/* + * Enum definition contains Mifare standard values + */ +typedef enum{ +PH_FRINFC_MFSTD_FMT_VAL_0, +PH_FRINFC_MFSTD_FMT_VAL_1, +PH_FRINFC_MFSTD_FMT_VAL_2, +PH_FRINFC_MFSTD_FMT_VAL_3, +PH_FRINFC_MFSTD_FMT_VAL_4, +PH_FRINFC_MFSTD_FMT_VAL_5, +PH_FRINFC_MFSTD_FMT_VAL_6, +PH_FRINFC_MFSTD_FMT_VAL_7, +PH_FRINFC_MFSTD_FMT_VAL_8, +PH_FRINFC_MFSTD_FMT_VAL_9, +PH_FRINFC_MFSTD_FMT_VAL_10, +PH_FRINFC_MFSTD_FMT_VAL_11 +}phFriNfc_MfStdVal; + +/* + * Mifare standard - NDEF information constants + */ +#define PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL 0 /* Sector is not ndef compliant */ +#define PH_FRINFC_MFSTD_FMT_NDEF_COMPL 1 /* Sector is ndef compliant */ +#define PH_FRINFC_MFSTD_FMT_NDEF_INFO1 0x03 /* If sector is ndef compliant, then one of the MAD + sector byte is 0x03 */ +#define PH_FRINFC_MFSTD_FMT_NDEF_INFO2 0xE1 /* If sector is ndef compliant, then one of the MAD + sector byte is 0xE1 */ + +/* + * Mifare standard - constants + */ +#define PH_FRINFC_MFSTD_FMT_MAX_RECV_LENGTH 252 /* Maximum receive length */ +#define PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH 17 /* Send length for write */ +#define PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K 16 /* Maximum sector index for Mifare 1k = 16 */ +#define PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K 32 /* Maximum sector index for Mifare 2k = 32 */ +#define PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K 40 /* Maximum sector index for Mifare 4k = 40 */ +#define PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_1K 64 /* Maximum Number of Blocks for Mifare 1k = 64 */ +#define PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_2K 128 /* Maximum Number of Blocks for Mifare 2k = 128 */ +#define PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_4K 256 /* Maximum Number of Blocks for Mifare 4k = 256*/ + +/* + * Copy default keyA to send buffer + */ +#define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_DEF(mem)\ +do\ +{\ + memset(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\ + PH_FRINFC_MFSTD_FMT_DEFAULT_KEY,\ + PH_FRINFC_MFSTD_FMT_VAL_6);\ + NdefSmtCrdFmt->Cmd.MfCmd = ((NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState == \ + PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)? \ + phHal_eMifareAuthentA: \ + phHal_eMifareAuthentB); \ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7; \ +}while(0) + +/* + * NFC forum sector keyA to send buffer + */ +#define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_NFCSECT_KEYA(mem)\ +do \ +{\ + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\ + NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_KeyA,\ + PH_FRINFC_MFSTD_FMT_VAL_6);\ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareAuthentA;\ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7;\ +} while(0) + +/* + * Copy MAD sector keyA to send buffer + */ +#define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_MADSECT_KEYA(mem)\ +do \ +{\ + memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\ + NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_KeyA,\ + PH_FRINFC_MFSTD_FMT_VAL_6);\ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareAuthentA;\ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7;\ +} while(0) + +/* + * Copy MAD sector keyB to send buffer + */ +#define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_SCRT_KEY(mem) \ +do \ +{\ + (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\ + NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB,\ + PH_FRINFC_MFSTD_FMT_VAL_6);\ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareAuthentB;\ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7;\ +} while(0) + +/* + * Get the next block + */ +#define PH_FRINFC_MFSTD_FMT_CUR_BLK_INC() \ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock += \ + ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= 127)?\ + 16:4) + +/* + * Get the sector index + */ +#define PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC \ + ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= 128)?\ + (32 + ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock - 128)/16)):\ + (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock/4)) + +/* + * Check the sector block + */ +#define PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK\ + (((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) && \ + (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= \ + PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_1K)) || \ + ((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD) && \ + (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= \ + PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_4K)) || \ + ((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD) && \ + (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= \ + PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_2K))) + +/* + * Get the next authenticate state + */ +#define PH_FRINFC_MFSTD_FMT_NXT_AUTH_STATE() \ +do \ +{\ + switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)\ + {\ + case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:\ + {\ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = (uint8_t) \ + ((((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock <= 3) || \ + ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock > 63) && \ + (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock < 67))))? \ + PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY: \ + PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY);\ + }\ + break;\ + case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:\ + {\ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \ + PH_FRINFC_MFSTD_FMT_AUTH_KEYB;\ + }\ + break;\ + case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:\ + {\ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \ + PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY;\ + }\ + break;\ + case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:\ + { \ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \ + PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB;\ + } \ + break;\ + case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:\ + default:\ + { \ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \ + PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;\ + }\ + break;\ + }\ +} while(0) + + +/* + * Increment the sector index + */ +#define PH_FRINFC_MFSTD_FMT_INCR_SECT \ +do \ +{\ + SectIndex++;\ + SectIndex = (uint8_t)((SectIndex == 16)?\ + (SectIndex + PH_FRINFC_MFSTD_FMT_VAL_1):\ + SectIndex);\ +} while(0) + + +/* + * Increment the sector index + */ +#define PH_FRINFC_MFSTD_FMT_CHK_SECT_ARRAY \ +do \ +{\ + while ((index < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) && \ + (memcompare != PH_FRINFC_MFSTD_FMT_VAL_0))\ + {\ + /* Compare any one among the sectors is NDEF COMPLIANT */\ + memcompare = (uint32_t)phFriNfc_MfStd_MemCompare(&Buffer[PH_FRINFC_MFSTD_FMT_VAL_0], \ + &NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[index],\ + PH_FRINFC_MFSTD_FMT_VAL_1);\ + /* increment the index */\ + index += (uint8_t)((index == (PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K - \ + PH_FRINFC_MFSTD_FMT_VAL_1))?\ + PH_FRINFC_MFSTD_FMT_VAL_2:\ + PH_FRINFC_MFSTD_FMT_VAL_1);\ + }\ +} while(0) + +/* + * Complete the sector + */ +#define PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD() \ +do \ +{ \ + phFriNfc_MfStd_H_NdefComplSect(NdefSmtCrdFmt->CardType, \ + NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl); \ + PH_FRINFC_MFSTD_FMT_CHK_SECT_ARRAY; \ + if(memcompare == PH_FRINFC_MFSTD_FMT_VAL_0) \ + { \ + phFriNfc_MfStd_H_StrNdefData(NdefSmtCrdFmt); \ + NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = \ + PH_FRINFC_MFSTD_FMT_VAL_1; \ + NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = \ + PH_FRINFC_MFSTD_FMT_MAD_BLK_1; \ + NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \ + PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB; \ + NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; \ + Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); \ + } \ + else \ + { \ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, \ + NFCSTATUS_FORMAT_ERROR); \ + } \ +} while(0) + +void phFriNfc_MfStd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +NFCSTATUS phFriNfc_MfStd_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB); +void phFriNfc_MfStd_Process(void *Context, NFCSTATUS Status); + +#endif /* PHFRINFC_MIFSTDFMT_H */ diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.c b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.c new file mode 100755 index 00000000..a2291fc6 --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.c @@ -0,0 +1,5840 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * NFC Ndef Mapping For Remote Devices. + * + */ + +#include <phFriNfc_MifStdFormat.h> +#include <phNfcCompId.h> +#include <phNxpExtns_MifareStd.h> +#include <phFriNfc_MifareStdMap.h> + +/**************** local methods used in this file only ************************/ +static NFCSTATUS phFriNfc_MifStd_H_RdABlock (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_WrABlock (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_AuthSector (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd4k_H_CheckNdef (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_fillAIDarray (phFriNfc_NdefMap_t *NdefMap); +static uint8_t phFriNfc_MifStd_H_GetSect (uint8_t BlockNumber); +static NFCSTATUS phFriNfc_MifStd_H_BlkChk (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ChkAcsBit (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ChkRdWr (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_ChkNdefCmpltSects (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_RemainTLV (phFriNfc_NdefMap_t *NdefMap, + uint8_t *Flag, + uint8_t *Temp16Bytes); +static NFCSTATUS phFriNfc_MifStd_H_ChkIntLen (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_IntLenWioutNdef (phFriNfc_NdefMap_t *NdefMap, + uint8_t *Flag, + uint8_t *TempintBytes); +static uint8_t phFriNfc_MifStd_H_UpdateTLV (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_WriteNdefLen (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_SetNdefBlkAuth (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_RdWrReset (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_RdtoWrNdefLen (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_GetActCardLen (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ChkTLVs (phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag); +static NFCSTATUS phFriNfc_MifStd_H_GetNxtTLV (phFriNfc_NdefMap_t *NdefMap, + uint16_t *TempLength, + uint8_t *TL4bytesFlag); +static NFCSTATUS phFriNfc_MifStd_H_Chk16Bytes (phFriNfc_NdefMap_t *NdefMap, + uint16_t TempLength); +static NFCSTATUS phFriNfc_MifStd_H_ChkRemainTLVs (phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag, + uint8_t *NDEFFlag); +static void phFriNfc_MifStd_H_Complete (phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS Result); +static void phFriNfc_MifStd_H_Get1kStTrail (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_Get4kStTrail (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProChkNdef (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProAuth (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_Rd16Bytes (phFriNfc_NdefMap_t *NdefMap, + uint8_t BlockNo); +static NFCSTATUS phFriNfc_MifStd_H_ProAcsBits (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_GPBChk (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProStatNotValid (phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS status); +static NFCSTATUS phFriNfc_MifStd_H_RdBeforeWr (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProBytesToWr (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_fillSendBuf (phFriNfc_NdefMap_t *NdefMap, + uint8_t Length); +static NFCSTATUS phFriNfc_MifStd_H_WrTLV (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProWrTLV (phFriNfc_NdefMap_t *NdefMap); +static uint8_t phFriNfc_MifStd_H_UpdRemTLV (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_fillTLV1 (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_fillTLV2 (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_CallWrNdefLen (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1 (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_fillTLV1_1 (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd_H_fillTLV2_1 (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_RdTLV (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProRdTLV (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_WrTermTLV (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProWrABlock (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_CallConnect (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_CallDisCon (phFriNfc_NdefMap_t *NdefMap); +static void phFriNfc_MifStd1k_H_BlkChk (phFriNfc_NdefMap_t *NdefMap, + uint8_t SectorID, + uint8_t *callbreak); +static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo (uint8_t SectorID); +static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor (phFriNfc_NdefMap_t *NdefMap); +static NFCSTATUS phFriNfc_MapTool_ChkSpcVer (const phFriNfc_NdefMap_t *NdefMap, + uint8_t VersionIndex) __attribute__((unused)); + +/* Mifare Standard Mapping - Constants */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1 0xA0 /* internal Authenticate Command for MAD Sector */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2 0xA1 /* internal Authenticate Command for MAD Sector */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3 0xA2 /* internal Authenticate Command for MAD Sector */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4 0xA3 /* internal Authenticate Command for MAD Sector */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5 0xA4 /* internal Authenticate Command for MAD Sector */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6 0xA5 /* internal Authenticate Command for MAD Sector */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1 0xD3 /* internal Authenticate Command for NDEF Sectors 1 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2 0xF7 /* internal Authenticate Command for NDEF Sectors 2 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL2 0x03 /* internal Ndef Compliant command 1 */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL1 0xE1 /* internal Ndef Compliant command 2 */ + +/* Enable access bits check for the MAD sector +#define ENABLE_ACS_BIT_CHK_FOR_MAD */ + +#define PH_FRINFC_NDEFMAP_MFUL_VAL0 0 + +/****************************************************************************** + * Function phFriNfc_MapTool_SetCardState + * + * Description This function sets the appropriate card state. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +NFCSTATUS phFriNfc_MapTool_SetCardState (phFriNfc_NdefMap_t *NdefMap, + uint32_t Length) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + if (Length == PH_FRINFC_NDEFMAP_MFUL_VAL0) + { + /* As the NDEF LEN / TLV Len is Zero, irrespective of any state the card + shall be set to INITIALIZED STATE*/ + NdefMap->CardState =(uint8_t) (((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_READ_ONLY) || + (NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID))? + PH_NDEFMAP_CARD_STATE_INVALID: + PH_NDEFMAP_CARD_STATE_INITIALIZED); + } + else + { + switch (NdefMap->CardState) + { + case PH_NDEFMAP_CARD_STATE_INITIALIZED: + NdefMap->CardState =(uint8_t) ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID)? + NdefMap->CardState: + PH_NDEFMAP_CARD_STATE_READ_WRITE); + break; + + case PH_NDEFMAP_CARD_STATE_READ_ONLY: + NdefMap->CardState = (uint8_t) ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID)? + NdefMap->CardState: + PH_NDEFMAP_CARD_STATE_READ_ONLY); + break; + + case PH_NDEFMAP_CARD_STATE_READ_WRITE: + NdefMap->CardState = (uint8_t) ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID)? + NdefMap->CardState: + PH_NDEFMAP_CARD_STATE_READ_WRITE); + if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) + { + if(NdefMap->StdMifareContainer.ReadOnlySectorIndex && + NdefMap->StdMifareContainer.SectorTrailerBlockNo == NdefMap->StdMifareContainer.currentBlock ) + { + NdefMap->CardState = (uint8_t) ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID)? + NdefMap->CardState: + PH_NDEFMAP_CARD_STATE_READ_ONLY); + } + } + break; + + default: + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + break; + } + } + Result = ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID)? + PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT): + Result); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifareStdMap_H_Reset + * + * Description This function resets the component instance to the initial + * state and lets the component forget about the list of + * registered items. Moreover, the lower device is set. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +NFCSTATUS phFriNfc_MifareStdMap_H_Reset (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint8_t index = PH_FRINFC_MIFARESTD_VAL0; + + if (NdefMap == NULL) + { + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else + { + /* Current Block stores the present block accessed in the card */ + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_VAL0; + + for (index = PH_FRINFC_MIFARESTD_VAL0; index < PH_FRINFC_NDEFMAP_MIFARESTD_ST15_BYTES; index++) + { + /* internal buffer to store the odd bytes of length < 15 */ + NdefMap->StdMifareContainer.internalBuf[index] = PH_FRINFC_MIFARESTD_VAL0; + } + + for (index = 0; index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK; index++) + { + /* aid buffer reset to non ndef compliant */ + NdefMap->StdMifareContainer.aid[index] = PH_FRINFC_MIFARESTD_NON_NDEF_COMP; + } + + /* odd bytes length stored in the internal buffer */ + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED; + + /* Flag to get that last few bytes are taken from the user buffer */ + NdefMap->StdMifareContainer.RemainingBufFlag = PH_FRINFC_MIFARESTD_FLAG0; + + /* Flag to find that the read/write operation has reached the end of the card. + Further reading/writing is not possible */ + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; + + /* Flag to get that last few bytes are taken from the internal buffer */ + NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG0; + + /* Authentication Flag for every sector */ + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + + /* Used in Check Ndef for storing the sector ID */ + NdefMap->StdMifareContainer.SectorIndex = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->StdMifareContainer.NoOfNdefCompBlocks = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->StdMifareContainer.ReadAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.remSizeUpdFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->TLVStruct.prevLenByteValue = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->StdMifareContainer.remainingSize = PH_FRINFC_MIFARESTD_VAL0; + + NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.aidCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.ProprforumSectFlag = PH_FRINFC_MIFARESTD_PROP_1ST_CONFIG; + + NdefMap->StdMifareContainer.ReadCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL1; + + NdefMap->StdMifareContainer.ChkNdefCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.ReadOnlySectorIndex = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.TotalNoSectors = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->StdMifareContainer.SectorTrailerBlockNo = PH_FRINFC_MIFARESTD_FLAG0; + } + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifareStdMap_ChkNdef + * + * Description The function checks whether the peer device is NDEF compliant. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +NFCSTATUS phFriNfc_MifareStdMap_ChkNdef ( phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + uint8_t atq, sak; + + if (NdefMap == NULL) + { + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else + { + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; + NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF; + + /* Get the Select Response and Sense Response to get + the exact Card Type either Mifare 1k or 4k */ + sak = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; + atq = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0]; + + if (0x08 == (sak & 0x18)) + { + /* Total Number of Blocks in Mifare 1k Card */ + NdefMap->StdMifareContainer.NoOfNdefCompBlocks = + PH_FRINFC_NDEFMAP_MIFARESTD_1KNDEF_COMPBLOCK; + NdefMap->StdMifareContainer.remainingSize = + ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0) ? + (PH_FRINFC_NDEFMAP_MIFARESTD_1KNDEF_COMPBLOCK * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) : + NdefMap->StdMifareContainer.remainingSize); + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD; + } + else if (0x19 == (sak & 0x19)) + { + /* Total Number of Blocks in Mifare 2k Card */ + NdefMap->StdMifareContainer.NoOfNdefCompBlocks = + PH_FRINFC_NDEFMAP_MIFARESTD_2KNDEF_COMPBLOCK; + NdefMap->StdMifareContainer.remainingSize = + ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0) ? + (PH_FRINFC_NDEFMAP_MIFARESTD_2KNDEF_COMPBLOCK * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) : + NdefMap->StdMifareContainer.remainingSize); + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD; + } + else + { + /* Total Number of Blocks in Mifare 4k Card */ + NdefMap->StdMifareContainer.NoOfNdefCompBlocks = + PH_FRINFC_NDEFMAP_MIFARESTD_4KNDEF_COMPBLOCK; + NdefMap->StdMifareContainer.remainingSize = + ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0) ? + (PH_FRINFC_NDEFMAP_MIFARESTD_4KNDEF_COMPBLOCK * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) : + NdefMap->StdMifareContainer.remainingSize); + NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD; + } + + + /* phFriNfc_MifareStdMap_ChkNdef should be called only + when currentBlock is 0 OR 64,65 and 66 (for Mifare 4k). + Otherwise return error */ + /* and also Check the Authentication Flag */ + if ((NdefMap->StdMifareContainer.currentBlock != 0) && + (NdefMap->StdMifareContainer.currentBlock != 1) && + (NdefMap->StdMifareContainer.currentBlock != 2) && + (NdefMap->StdMifareContainer.currentBlock != 64) && + (NdefMap->StdMifareContainer.currentBlock != 65) && + (NdefMap->StdMifareContainer.currentBlock != 66)) + { + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else if ( NdefMap->StdMifareContainer.AuthDone == 0) + { + /* Block 0 contains Manufacturer information and + also other informaton. So go for block 1 which + contains AIDs. Authenticating any of the block + in a sector, Authenticates the whole sector */ + if (NdefMap->StdMifareContainer.currentBlock == 0) + { + NdefMap->StdMifareContainer.currentBlock = 1; + } + status = phFriNfc_MifStd_H_AuthSector (NdefMap); + } + else + { + /** + * Mifare 1k, sak = 0x08 atq = 0x04 + * Mifare 2k, sak = 0x19 atq = 0x02 + * Mifare 4k, sak = 0x18 atq = 0x02 + */ + if ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) || + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) || + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) + { + /* Change the state to Check Ndef Compliant */ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_CHK_NDEF_COMP; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; + NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG1; + + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + NdefMap->Cmd.MfCmd = phHal_eMifareRead; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + NdefMap->SendRecvBuf [0] = NdefMap->StdMifareContainer.currentBlock; + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; + + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_ExtnsTransceive (NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + else + { + /* Since we have decided temporarily not to go + for any new error codes we are using + NFCSTATUS_INVALID_PARAMETER even though it is not + the relevant error code here TBD */ + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + } + } + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifareStdMap_RdNdef + * + * Description The function initiates the reading of NDEF information from + * a Remote Device. It performs a reset of the state and starts + * the action (state machine). A periodic call of the + * phFriNfcNdefMap_Process has to be done once the action + * has been triggered. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +NFCSTATUS phFriNfc_MifareStdMap_RdNdef (phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + NdefMap->ApduBufferSize = *PacketDataLength; + NdefMap->NumOfBytesRead = PacketDataLength; + *NdefMap->NumOfBytesRead = 0; + NdefMap->ApduBuffIndex = 0; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; + NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF; + + if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) + || (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED)) + { + /* Card state is not correct */ + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + } + else + { + if ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation == + PH_FRINFC_NDEFMAP_WRITE_OPE)) + { + phFriNfc_MifStd_H_RdWrReset (NdefMap); + NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + /* Offset = Current, but the read has reached the End of Card */ + if ((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && + (NdefMap->StdMifareContainer.ReadWriteCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)) + { + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); + } + else + { + NdefMap->Offset = (((Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) && + (NdefMap->PrevOperation == + PH_FRINFC_NDEFMAP_WRITE_OPE)) ? + PH_FRINFC_NDEFMAP_SEEK_BEGIN : + Offset); + status = phFriNfc_MifStd_H_BlkChk (NdefMap); + if (status == NFCSTATUS_SUCCESS) + { + NdefMap->ApduBuffer = PacketData; + + /* Read Operation in Progress */ + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; + + /* Check Authentication Flag */ + status = + ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) ? + phFriNfc_MifStd_H_RdABlock(NdefMap) : + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + } + } + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifareStdMap_WrNdef + * + * Description The function initiates the writing of NDEF information to + * a Remote Device. It performs a reset of the state and starts + * the action (state machine). A periodic call of the + * phFriNfcNdefMap_Process has to be done once the action + * has been triggered. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +NFCSTATUS phFriNfc_MifareStdMap_WrNdef (phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + NdefMap->ApduBuffer = PacketData; + NdefMap->ApduBufferSize = *PacketDataLength; + NdefMap->ApduBuffIndex = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->WrNdefPacketLength = PacketDataLength; + *NdefMap->WrNdefPacketLength = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; + NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF; + + if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) + || (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) + { + /* Card state is not correct */ + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + } + else + { + if ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || + (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE)) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.remainingSize = + (NdefMap->StdMifareContainer.NoOfNdefCompBlocks * + PH_FRINFC_MIFARESTD_BLOCK_BYTES); + NdefMap->StdMifareContainer.currentBlock = + PH_FRINFC_MIFARESTD_BLK4; + NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL1; + NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* This macro is added, to be compliant with the previous HAL 2.0 + For HAL 2.0, polling is done before writing data to the mifare + std (if the offset is BEGIN), because if an error is reported + during read or write and again write is called, the PN531 state is + unchanged (so write will fail), to bring the PN531 to the correct + state, polling is done. + Changed on 13th Jan 2009 + */ + NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->StdMifareContainer.FirstWriteFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + + if (((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && + (NdefMap->StdMifareContainer.ReadWriteCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)) || ((NdefMap->StdMifareContainer.PollFlag == + PH_FRINFC_MIFARESTD_FLAG1) && (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR))) + { + /* Offset = Current, but the read has reached the End of Card */ + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); + } + else + { + NdefMap->Offset = (((Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) && + (NdefMap->PrevOperation == + PH_FRINFC_NDEFMAP_READ_OPE)) ? + PH_FRINFC_NDEFMAP_SEEK_BEGIN : + Offset); + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + status = phFriNfc_MifStd_H_BlkChk (NdefMap); + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; + if (status == NFCSTATUS_SUCCESS) + { + if (NdefMap->StdMifareContainer.PollFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + /* if poll flag is set then call disconnect because the authentication + has failed so reactivation of card is required */ + status = phFriNfc_MifStd_H_CallDisCon (NdefMap); + } + /* Check Authentication Flag */ + else if (NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) + { + status = ((NdefMap->Offset == + PH_FRINFC_NDEFMAP_SEEK_BEGIN) ? + phFriNfc_MifStd_H_RdBeforeWr (NdefMap) : + phFriNfc_MifStd_H_WrABlock (NdefMap)); + } + else + { + status = phFriNfc_MifStd_H_AuthSector (NdefMap); + } + } + } + } + + return status; +} + + +/****************************************************************************** + * Function phFriNfc_MifareStdMap_Process + * + * Description This function is a Completion Routine, Processing function, + * needed to avoid long blocking. + * This function as a Completion Routine in order to be able + * to notify the component that an I/O has finished and data + * are ready to be processed. + + * Returns void + * + ******************************************************************************/ +void phFriNfc_MifareStdMap_Process (void *Context, + NFCSTATUS Status) +{ + phFriNfc_NdefMap_t *NdefMap; + uint8_t NDEFFlag = 0, + CRFlag = 0, + Temp16Bytes = 0, + i = 0; + + NdefMap = (phFriNfc_NdefMap_t *)Context; + + if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER)) + { + switch (NdefMap->State) + { + case PH_FRINFC_NDEFMAP_STATE_CHK_NDEF_COMP: + Status = phFriNfc_MifStd_H_ProChkNdef (NdefMap); + CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_READ: + /* Receive Length for read shall always be equal to 16 */ + if ((*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) && + (NdefMap->ApduBuffIndex < (uint16_t) NdefMap->ApduBufferSize)) + { + Temp16Bytes = PH_FRINFC_MIFARESTD_VAL0; + NDEFFlag = (uint8_t) PH_FRINFC_MIFARESTD_FLAG1; + if (NdefMap->TLVStruct.BytesRemainLinTLV != 0) + { + NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + CRFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* To read the remaining length (L) in TLV */ + Status = phFriNfc_MifStd_H_RemainTLV (NdefMap, &NDEFFlag, &Temp16Bytes); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + + /* check the NDEFFlag is set. if this is not set, then + in the above RemainTLV function all the 16 bytes has been + read */ + } + else + { + Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_RECEIVE_LENGTH); + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + break; + + case PH_FRINFC_NDEFMAP_STATE_WRITE: + Status = phFriNfc_MifStd_H_ProWrABlock (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + /* Call Completion Routine if CR Flag is Set to 1 */ + if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; + } + break; + + case PH_FRINFC_NDEFMAP_STATE_AUTH: + NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; + Status = phFriNfc_MifStd_H_ProAuth (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT: + Status = phFriNfc_MifStd_H_ProAcsBits (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN: + if (NdefMap->StdMifareContainer.RdAfterWrFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + Status = phFriNfc_MifStd_H_CallWrNdefLen (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + else + { + /* Check this */ + if (NdefMap->StdMifareContainer.TempBlockNo == + NdefMap->StdMifareContainer.currentBlock) + { + memcpy (NdefMap->StdMifareContainer.internalBuf, + NdefMap->StdMifareContainer.Buffer, + NdefMap->StdMifareContainer.internalLength); + + } + *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; + NdefMap->StdMifareContainer.currentBlock = + NdefMap->StdMifareContainer.TempBlockNo; + NdefMap->CardState = (uint8_t) ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INITIALIZED) ? + PH_NDEFMAP_CARD_STATE_READ_WRITE : + NdefMap->CardState); + CRFlag = (uint8_t) PH_FRINFC_MIFARESTD_FLAG1; + } + break; + + case PH_FRINFC_NDEFMAP_STATE_RD_TO_WR_NDEF_LEN: + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + /* Size of NdefMap->SendRecvBuf is set by phLibNfc_Gen_NdefMapReset to PH_LIBNFC_GEN_MAX_BUFFER */ + /* We don't have to check memory here */ + for (i = PH_FRINFC_MIFARESTD_BYTES_READ; i > 0; i--) + { + NdefMap->SendRecvBuf [i] = NdefMap->SendRecvBuf [i-1]; + } + NdefMap->SendRecvBuf [PH_FRINFC_MIFARESTD_VAL0] = + NdefMap->StdMifareContainer.currentBlock; + Status = phFriNfc_MifStd_H_WriteNdefLen (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + break; + + case PH_FRINFC_NDEFMAP_STATE_GET_ACT_CARDSIZE: + NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1; + if (NdefMap->TLVStruct.NoLbytesinTLV > PH_FRINFC_MIFARESTD_VAL0) + { + NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + Status = phFriNfc_MifStd_H_ChkRemainTLVs (NdefMap, &CRFlag, &NDEFFlag); + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_MIFARESTD_VAL0; + } + if ((NDEFFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (CRFlag != PH_FRINFC_MIFARESTD_FLAG1)) + { + Status = phFriNfc_MifStd_H_ChkTLVs (NdefMap, &CRFlag); + } + if (((NdefMap->StdMifareContainer.ReadNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) || + (NdefMap->StdMifareContainer.WrNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1)) && + (Status != NFCSTATUS_PENDING)) + { + NdefMap->StdMifareContainer.NFCforumSectFlag = + PH_FRINFC_MIFARESTD_FLAG1; + CRFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* if the card state has changed to initialised and + read ndef is called then error is returned */ + if (((NdefMap->StdMifareContainer.WrNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) || + ((NdefMap->StdMifareContainer.ReadNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED))) + { + Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } + if (NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG0) + { + Status = phFriNfc_MifStd_H_AuthSector (NdefMap); + } + else + { + Status = ((NdefMap->StdMifareContainer.ReadNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) ? + phFriNfc_MifStd_H_RdTLV (NdefMap) : + phFriNfc_MifStd_H_RdBeforeWr (NdefMap)); + } + NdefMap->StdMifareContainer.ReadNdefFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.WrNdefFlag = + PH_FRINFC_MIFARESTD_FLAG0; + } + + if (NdefMap->StdMifareContainer.ChkNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + break; + + case PH_FRINFC_NDEFMAP_STATE_RD_BEF_WR: + /* Read flag says that already part of TLV has been written */ + Status = phFriNfc_MifStd_H_ProBytesToWr (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_WR_TLV: + Status = phFriNfc_MifStd_H_ProWrTLV (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_RD_TLV: + Status = phFriNfc_MifStd_H_ProRdTLV (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_TERM_TLV: + phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); + NdefMap->StdMifareContainer.currentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + Status = phFriNfc_MifStd_H_RdtoWrNdefLen (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_DISCONNECT: + NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG0; + + Status = phFriNfc_MifStd_H_CallConnect (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_CONNECT: + if (NdefMap->StdMifareContainer.FirstReadFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0; + Status = phFriNfc_MifStd_H_AuthSector (NdefMap); + } + else if ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) && + (NdefMap->StdMifareContainer.ReadOnlySectorIndex && + NdefMap->StdMifareContainer.SectorTrailerBlockNo == NdefMap->StdMifareContainer.currentBlock)) + { + NdefMap->StdMifareContainer.ReadOnlySectorIndex = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.SectorTrailerBlockNo = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_FLAG0; + Status = NFCSTATUS_FAILED; + } + else + { + Status = ((((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && + (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) || + (NdefMap->StdMifareContainer.WrLength > + PH_FRINFC_MIFARESTD_VAL0)) ? + phFriNfc_MifStd_H_ProStatNotValid (NdefMap, Status) : + phFriNfc_MifStd_H_AuthSector (NdefMap)); + } + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + break; + + case PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT: + Status = phFriNfc_MifStd_H_ProSectorTrailorAcsBits (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING)? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + if ((CRFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->StdMifareContainer.WriteAcsBitFlag == PH_FRINFC_MIFARESTD_FLAG0)) + { + Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + } + break; + + case PH_FRINFC_NDEFMAP_STATE_WRITE_SEC: + /* Set flag for writing of Acs bit */ + NdefMap->StdMifareContainer.WriteAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG1; + + /* The first NDEF sector is already made read only, + set card state to read only and proceed*/ + if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY) + { + Status = phFriNfc_MapTool_SetCardState (NdefMap, NdefMap->TLVStruct.BytesRemainLinTLV); + if (Status != NFCSTATUS_SUCCESS) + { + CRFlag = (uint8_t) PH_FRINFC_MIFARESTD_FLAG1; + } + } + + if (CRFlag != PH_FRINFC_MIFARESTD_FLAG1) + { + Status = phFriNfc_MifStd_H_ProWrSectorTrailor (NdefMap); + CRFlag = (uint8_t) ((Status != NFCSTATUS_PENDING) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + break; + + default: + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + } + else if (NdefMap->State == PH_FRINFC_NDEFMAP_STATE_AUTH) + { + NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG1; + if(NdefMap->StdMifareContainer.FirstWriteFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.FirstWriteFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.WrLength = + ((NdefMap->StdMifareContainer.NFCforumSectFlag == + PH_FRINFC_MIFARESTD_FLAG0) ? + PH_FRINFC_MIFARESTD_VAL1 : + NdefMap->StdMifareContainer.WrLength); + } + if (NdefMap->StdMifareContainer.WrLength == PH_FRINFC_MIFARESTD_VAL0) + { + Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + else + { + /* Authentication has failed */ + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; /* Call Completion Routine */ + Status = NFCSTATUS_FAILED;/* Update Status Flag */ + } + } + else + { + Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + /* Call Completion Routine if CR Flag is Set to 1 */ + if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + phFriNfc_MifStd_H_Complete (NdefMap, Status); + } + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_RdABlock + * + * Description This function is a Helper function for Mifare Std. It Reads + * a block from the card. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_RdABlock (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_READ; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + if (NdefMap->ApduBuffIndex < (uint16_t) NdefMap->ApduBufferSize) + { + + if (NdefMap->StdMifareContainer.internalLength > PH_FRINFC_MIFARESTD_VAL0) + { + status = phFriNfc_MifStd_H_ChkIntLen (NdefMap); + } /* internal Length Check */ + else + { + NdefMap->SendRecvBuf [PH_FRINFC_MIFARESTD_VAL0] = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + NdefMap->Cmd.MfCmd = phHal_eMifareRead; + + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_ExtnsTransceive (NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + } + else + { + /* Check for the Card Size */ + if((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BYTES_READ) == 0) || + (NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex)) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + (uint8_t) ((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BYTES_READ) == 0) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + status = PHNFCSTVAL (CID_NFC_NONE, NFCSTATUS_SUCCESS); + } + else + { + /* Error: The control should not ideally come here. Return Error. */ + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); + } + } + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_WrABlock + * + * Description This function writes into a block of the card. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_WrABlock (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + uint16_t RemainingBytes = 0, + BytesRemained = 0, + index = 0; + uint8_t Temp16Bytes = 0; + + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WRITE; + + /* User Buffer Check */ + if( NdefMap->ApduBuffIndex < (uint16_t) NdefMap->ApduBufferSize) + { + RemainingBytes = (((uint16_t) (NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex) < + NdefMap->StdMifareContainer.remainingSize) ? + (uint16_t)(NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex) : + NdefMap->StdMifareContainer.remainingSize); + + NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock; + Temp16Bytes += PH_FRINFC_MIFARESTD_INC_1; + + /* Check for internal bytes */ + if (NdefMap->StdMifareContainer.internalLength > 0) + { + /* copy the bytes previously written in the internal Buffer */ + memcpy (&(NdefMap->SendRecvBuf [Temp16Bytes]), + NdefMap->StdMifareContainer.internalBuf, + NdefMap->StdMifareContainer.internalLength); + + Temp16Bytes += (uint8_t) (NdefMap->StdMifareContainer.internalLength); + if (RemainingBytes >= (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)) + { + /* Copy the Remaining bytes from the user buffer to make the send + data and length = 16 */ + memcpy (&(NdefMap->SendRecvBuf [Temp16Bytes]), + NdefMap->ApduBuffer, + (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)); + + NdefMap->NumOfBytesWritten = + (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); + Temp16Bytes += (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); + *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); + } + else + { + memcpy (&(NdefMap->SendRecvBuf [Temp16Bytes]), + NdefMap->ApduBuffer, + RemainingBytes); + + NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->NumOfBytesWritten = RemainingBytes; + Temp16Bytes += (uint8_t) (RemainingBytes); + *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); + + BytesRemained = (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); + /* Pad empty bytes with Zeroes to complete 16 bytes*/ + for (index = 0; index < BytesRemained; index++) + { + NdefMap->SendRecvBuf [(Temp16Bytes + index)] = + (uint8_t) ((index == PH_FRINFC_MIFARESTD_VAL0) ? + PH_FRINFC_MIFARESTD_TERMTLV_T : + PH_FRINFC_MIFARESTD_NULLTLV_T); + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + Temp16Bytes += (uint8_t) (BytesRemained); + } + } + else + { + if (RemainingBytes >= (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)) + { + /* Bytes left to write < 16, copy remaining bytes */ + memcpy (&(NdefMap->SendRecvBuf [ + Temp16Bytes]), + &(NdefMap->ApduBuffer [ + NdefMap->ApduBuffIndex]), + (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)); + + NdefMap->NumOfBytesWritten = (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); + Temp16Bytes += (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes); + *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); + } + else + { + /* Bytes left to write < 16, copy remaining bytes */ + memcpy (&(NdefMap->SendRecvBuf [ + Temp16Bytes]), + &(NdefMap->ApduBuffer [ + NdefMap->ApduBuffIndex]), + RemainingBytes); + + NdefMap->StdMifareContainer.RemainingBufFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->NumOfBytesWritten = RemainingBytes; + Temp16Bytes += (uint8_t) (RemainingBytes); + *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1); + + + /* Pad empty bytes with Zeroes to complete 16 bytes */ + for (index = Temp16Bytes; index < MIFARE_MAX_SEND_BUF_TO_WRITE; index++) + { + NdefMap->SendRecvBuf [index] = (uint8_t) ((index == + Temp16Bytes) ? + PH_FRINFC_MIFARESTD_TERMTLV_T : + PH_FRINFC_MIFARESTD_NULLTLV_T); + + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + } + } + /* Buffer to store 16 bytes which is writing to the present block */ + memcpy (NdefMap->StdMifareContainer.Buffer, + &(NdefMap->SendRecvBuf [PH_FRINFC_MIFARESTD_INC_1]), + PH_FRINFC_MIFARESTD_BLOCK_BYTES); + + /* Write from here */ + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; + NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_ExtnsTransceive (NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + else /* Check User Buffer */ + { + if (NdefMap->StdMifareContainer.NdefBlocks > + NdefMap->StdMifareContainer.NoOfNdefCompBlocks) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + status = PHNFCSTVAL (CID_NFC_NONE, + NFCSTATUS_SUCCESS); + } + else if (NdefMap->ApduBuffIndex == (uint16_t) NdefMap->ApduBufferSize) + { + status = PHNFCSTVAL (CID_NFC_NONE, NFCSTATUS_SUCCESS); + } + else + { + /* Error: The control should not ideally come here. Return Error. */ + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); + } + } + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_AuthSector + * + * Description This function authenticates one sector at a time. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_AuthSector (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_AUTH; + + /* Authenticate */ + NdefMap->Cmd.MfCmd = phHal_eMifareAuthentA; + + NdefMap->SendRecvBuf [PH_FRINFC_MIFARESTD_VAL0] = + ((NdefMap->TLVStruct.NdefTLVAuthFlag == + PH_FRINFC_MIFARESTD_FLAG1) ? + NdefMap->TLVStruct.NdefTLVBlock : + NdefMap->StdMifareContainer.currentBlock); + + /* if MAD blocks then authentication key is + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 else + 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 */ + if (((NdefMap->StdMifareContainer.currentBlock != PH_FRINFC_MIFARESTD_MAD_BLK0) && + (NdefMap->StdMifareContainer.currentBlock != PH_FRINFC_MIFARESTD_MAD_BLK1) && + (NdefMap->StdMifareContainer.currentBlock != PH_FRINFC_MIFARESTD_MAD_BLK2) && + (NdefMap->StdMifareContainer.currentBlock != PH_FRINFC_MIFARESTD_MAD_BLK64) && + (NdefMap->StdMifareContainer.currentBlock != PH_FRINFC_MIFARESTD_MAD_BLK65) && + (NdefMap->StdMifareContainer.currentBlock != PH_FRINFC_MIFARESTD_MAD_BLK66)) || + (NdefMap->TLVStruct.NdefTLVAuthFlag == + (uint8_t) PH_FRINFC_MIFARESTD_FLAG1)) + { + NdefMap->SendRecvBuf [1] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ + NdefMap->SendRecvBuf [2] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ + NdefMap->SendRecvBuf [3] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ + NdefMap->SendRecvBuf [4] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ + NdefMap->SendRecvBuf [5] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ + NdefMap->SendRecvBuf [6] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ + } + else + { + NdefMap->SendRecvBuf [1] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1; /* 0xA0 */ + NdefMap->SendRecvBuf [2] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2; /* 0xA1 */ + NdefMap->SendRecvBuf [3] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3; /* 0xA2 */ + NdefMap->SendRecvBuf [4] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4; /* 0xA3 */ + NdefMap->SendRecvBuf [5] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5; /* 0xA4 */ + NdefMap->SendRecvBuf [6] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6; /* 0xA5 */ + } + + if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) + { + if (NdefMap->StdMifareContainer.ReadOnlySectorIndex && + NdefMap->StdMifareContainer.SectorTrailerBlockNo == NdefMap->StdMifareContainer.currentBlock) + { + memcpy (&NdefMap->SendRecvBuf [1], &NdefMap->StdMifareContainer.UserScrtKeyB [0], PH_FRINFC_MIFARESTD_KEY_LEN); + + /* Authenticate with KeyB */ + NdefMap->Cmd.MfCmd = phHal_eMifareAuthentB; + } + } + + NdefMap->SendLength = MIFARE_AUTHENTICATE_CMD_LENGTH; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_ExtnsTransceive (NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_Complete + * + * Description It is used to call the Completion Routine + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_Complete (phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS Result) +{ + /* set the state back to the Reset_Init state */ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; + + /* set the completion routine */ + NdefMap->CompletionRoutine [NdefMap->StdMifareContainer.CRIndex]. + CompletionRoutine (NdefMap->CompletionRoutine->Context, Result); + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd4k_H_CheckNdef + * + * Description This function is used for Mifare 4k Check Ndef to + * get the next AID blocks. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd4k_H_CheckNdef (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Get the AID Block */ + if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK2) + { + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK64; + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + } + else if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK64) + { + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK65; + } + else + { + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK66; + } + + Result = phFriNfc_MifareStdMap_ChkNdef (NdefMap); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_fillAIDarray + * + * Description This function storew the AIDs for check ndef. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_fillAIDarray (phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t byteindex = 0; + + if ((NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK1) || + (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK64)) + { + /* The First Two Bytes in Receive Buffer + are CRC bytes so it is not copied + instead, 0 is copied in AID[0] & AID[1] */ + NdefMap->StdMifareContainer.aid [NdefMap->StdMifareContainer.SectorIndex] = + PH_FRINFC_MIFARESTD_NON_NDEF_COMP; + NdefMap->StdMifareContainer.SectorIndex++; + byteindex = 2; + } + + while (byteindex < PH_FRINFC_MIFARESTD_BYTES_READ) + { + if ((NdefMap->SendRecvBuf [byteindex] == PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL2) && + (NdefMap->SendRecvBuf [(byteindex + 1)] == PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL1)) + { + /* This flag is set when a NFC forum sector is found in a + MAD block for the first time */ + NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.SectorIndex] = + PH_FRINFC_MIFARESTD_NDEF_COMP; + NdefMap->StdMifareContainer.SectorIndex++; + } + else + { + NdefMap->StdMifareContainer.aid [NdefMap->StdMifareContainer.SectorIndex] = + PH_FRINFC_MIFARESTD_NON_NDEF_COMP; + NdefMap->StdMifareContainer.SectorIndex++; + /* AID complete flag is set when a non NFC forum sector is found in a + MAD block after the NFC forum sector. After setting this, all other + values are ignored and are NOT NDEF compliant */ + NdefMap->StdMifareContainer.aidCompleteFlag = + ((NdefMap->StdMifareContainer.NFCforumSectFlag == + PH_FRINFC_MIFARESTD_FLAG1) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; + if (NdefMap->StdMifareContainer.aidCompleteFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + break; + } + } + byteindex += 2; + } + + /* If "aidCompleteFlag" is set then the remaining sectors are made NOT + NDEF compliant */ + if ((NdefMap->StdMifareContainer.aidCompleteFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) + { + /* for Mifare 1k there are 16 sectors, till this number all sectors + are made NOT NDEF compliant */ + for (byteindex = NdefMap->StdMifareContainer.SectorIndex; + byteindex < PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR; + byteindex++) + { + NdefMap->StdMifareContainer.aid [byteindex] = + PH_FRINFC_MIFARESTD_NON_NDEF_COMP; + } + } + else if ((NdefMap->StdMifareContainer.aidCompleteFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) + { + /* for Mifare 2k there are 32 sectors, till this number all sectors + are made NOT NDEF compliant */ + for (byteindex = NdefMap->StdMifareContainer.SectorIndex; + byteindex < PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR; + byteindex++) + { + NdefMap->StdMifareContainer.aid[byteindex] = + PH_FRINFC_MIFARESTD_NON_NDEF_COMP; + } + } + else + { + /* for Mifare 4k there are 40 sectors, till this number all sectors + are made NOT NDEF compliant */ + if ((NdefMap->StdMifareContainer.aidCompleteFlag == PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)) + { + for(byteindex = NdefMap->StdMifareContainer.SectorIndex; + byteindex < PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; + byteindex++) + { + NdefMap->StdMifareContainer.aid [byteindex] = + PH_FRINFC_MIFARESTD_NON_NDEF_COMP; + } + } + } + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_BlkChk + * + * Description This function is to check the Ndef compliance of the + * current block, if the block is not Ndef Compliant, + * increment the block till the next Ndef compliant block + * using the Get Sector Helper function + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_BlkChk (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t SectorID = 0, callbreak = 0; + + for (;;) + { + /* Get a Sector ID for the Current Block */ + SectorID = phFriNfc_MifStd_H_GetSect (NdefMap->StdMifareContainer.currentBlock); + /* Check the card Type 1k or 4k */ + /* enter if Mifare 1k card. For Mifare 4k go to else */ + if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) + { + /* if Sector Id > 15 No Sectors to write */ + if (SectorID > 15) + { + SectorID = phFriNfc_MifStd_H_GetSect (NdefMap->StdMifareContainer.currentBlock); + /*Error: No Ndef Compliant Sectors present */ + Result = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + callbreak = 1; + } + else + { + phFriNfc_MifStd1k_H_BlkChk (NdefMap, SectorID, &callbreak); + } + } /* End of if */ /* End of Mifare 1k check */ + else if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) /* Mifare 2k check starts here */ + { + /* Sector > 39 no ndef compliant sectors found*/ + if (SectorID > PH_FRINFC_MIFARESTD_SECTOR_NO31) + { + /*Error: No Ndef Compliant Sectors present */ + Result = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + callbreak = 1; + } + else if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK64) + { + NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; + } + else if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) /* sector < 32 contains 4 blocks in each sector */ + { + /* If the block checked is 63, the 3 blocks after this + are AID(MAD) blocks so its need to be skipped */ + if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK63) + { + NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; + } + else + { + phFriNfc_MifStd1k_H_BlkChk (NdefMap, SectorID, &callbreak); + } + } + else + { + phFriNfc_MifStd1k_H_BlkChk (NdefMap, SectorID, &callbreak); + } + }/* End of if*/ /* End of Mifare 2k check*/ + else /* Mifare 4k check starts here */ + { + /* Sector > 39 no ndef compliant sectors found*/ + if (SectorID > PH_FRINFC_MIFARESTD_SECTOR_NO39) + { + /*Error: No Ndef Compliant Sectors present */ + Result = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + callbreak = 1; + } + else if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK64) + { + NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; + } + else if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) /* sector < 32 contains 4 blocks in each sector */ + { + /* If the block checked is 63, the 3 blocks after this + are AID(MAD) blocks so its need to be skipped */ + if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK63) + { + NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; + } + else + { + phFriNfc_MifStd1k_H_BlkChk (NdefMap, SectorID, &callbreak); + } + } + else + { + /* every last block of a sector needs to be skipped */ + if (((NdefMap->StdMifareContainer.currentBlock + 1) % + PH_FRINFC_MIFARESTD_BLOCK_BYTES) == 0) + { + NdefMap->StdMifareContainer.currentBlock++; + } + else + { + if (NdefMap->StdMifareContainer.aid [SectorID] == + PH_FRINFC_MIFARESTD_NDEF_COMP) + { + /* Check whether the block is first block of a (next)new sector and + also check if it is first block then internal length is zero + or not. Because once Authentication is done for the sector again + we should not authenticate it again */ + /* In this case 32 sectors contains 4 blocks and next remaining 8 sectors + contains 16 blocks that is why (32 * 4) + (sectorID - 32) *16*/ + if ((NdefMap->StdMifareContainer.currentBlock == + ((PH_FRINFC_MIFARESTD_SECTOR_NO32 * PH_FRINFC_MIFARESTD_BLK4) + + ((SectorID - PH_FRINFC_MIFARESTD_SECTOR_NO32) * PH_FRINFC_MIFARESTD_BLOCK_BYTES))) && + (NdefMap->StdMifareContainer.internalLength == 0)) + { + NdefMap->StdMifareContainer.AuthDone = 0; + } + callbreak = 1; + } + else + { + NdefMap->StdMifareContainer.currentBlock += 16; + } + } + } + } + if (callbreak == 1) + { + break; + } + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_GetSect + * + * Description This function to get the Sector from the current block + * + * Returns uint8_t SectorID + * + ******************************************************************************/ +static uint8_t phFriNfc_MifStd_H_GetSect (uint8_t BlockNumber) +{ + uint8_t SectorID = 0; + + if (BlockNumber >= PH_FRINFC_MIFARESTD4K_BLK128) + { + SectorID = (uint8_t) (PH_FRINFC_MIFARESTD_SECTOR_NO32 + + ((BlockNumber - PH_FRINFC_MIFARESTD4K_BLK128)/ + PH_FRINFC_MIFARESTD_BLOCK_BYTES)); + } + else + { + SectorID = (BlockNumber/PH_FRINFC_MIFARESTD_BLK4); + } + + return SectorID; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_RdAcsBit + * + * Description It read the access bits of each sector. + * NCI messages. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT; + + if (NdefMap->StdMifareContainer.ReadOnlySectorIndex && + NdefMap->StdMifareContainer.currentBlock == NdefMap->StdMifareContainer.SectorTrailerBlockNo) + { + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT; + } + + if (NdefMap->StdMifareContainer.ReadAcsBitFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + /* Get the sector trailer */ + ((NdefMap->StdMifareContainer.currentBlock > 127) ? + phFriNfc_MifStd_H_Get4kStTrail(NdefMap) : + phFriNfc_MifStd_H_Get1kStTrail(NdefMap)); + } + else + { + /* Give the current block to read */ + NdefMap->SendRecvBuf [PH_FRINFC_MIFARESTD_VAL0] = + NdefMap->StdMifareContainer.currentBlock; + } + + Result = phFriNfc_MifStd_H_Rd16Bytes(NdefMap, + NdefMap->SendRecvBuf [PH_FRINFC_MIFARESTD_VAL0]); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ChkAcsBit + * + * Description This function check the access bits of each sector. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ChkAcsBit (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Blocks from 0 to 3 and from 64 to 67(MAD blocks) */ + if ((NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK0) || + (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK1) || + (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK2) || + (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK3) || + (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK64) || + (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK65) || + (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_MAD_BLK66) ) + { + /* Access bits check removed for the MAD blocks */ +#ifdef ENABLE_ACS_BIT_CHK_FOR_MAD + + if (((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL6] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE6) && + ((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL7] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE7) && + ((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL8] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_ACS_BYTE8)) + { + NdefMap->StdMifareContainer.WriteFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.ReadFlag = + PH_FRINFC_MIFARESTD_FLAG1; + } + else + { + NdefMap->StdMifareContainer.WriteFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.ReadFlag = + PH_FRINFC_MIFARESTD_FLAG0; + } + +#else /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ + + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED; + +#endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ + } + else + { + /* Check for Access bytes 6, 7 and 8 value = + 0x7F, 0x07, 0x88 NFC forum sectors*/ + if (((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL6] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE6) && + ((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL7] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE7) && + ((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL8] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_ACS_BYTE8)) + { + NdefMap->StdMifareContainer.WriteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->StdMifareContainer.ReadFlag = + PH_FRINFC_MIFARESTD_FLAG1; + } + else if (((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL6] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6) && + ((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL7] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7) && + ((NdefMap->SendRecvBuf [ + PH_FRINFC_MIFARESTD_VAL8] & + PH_FRINFC_MIFARESTD_MASK_FF) == + PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8)) + { + /* Read Only state */ + /* Check for Access bytes 6, 7 and 8 value = + 0x55, 0xAD, 0x2A NFC forum Sectors */ + NdefMap->StdMifareContainer.WriteFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.ReadFlag = + PH_FRINFC_MIFARESTD_FLAG1; + } + else + { + NdefMap->StdMifareContainer.WriteFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.ReadFlag = + PH_FRINFC_MIFARESTD_FLAG0; + } + +#ifdef ENABLE_ACS_BIT_CHK_FOR_MAD + /* Do nothing */ +#else /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ + Result = phFriNfc_MifStd_H_GPBChk (NdefMap); +#endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ + } + +#ifdef ENABLE_ACS_BIT_CHK_FOR_MAD + Result = phFriNfc_MifStd_H_GPBChk (NdefMap); +#endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */ + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ChkRdWr + * + * Description This function is for read access bits, depending + * on the read/write/check ndef function called. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ChkRdWr (phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + switch (NdefMap->PrevOperation) + { + case PH_FRINFC_NDEFMAP_CHECK_OPE: + if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) + { + /* No permission to read */ + Result = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_READ_FAILED); + } + else if ((NdefMap->StdMifareContainer.currentBlock > 3) && + (NdefMap->StdMifareContainer.ChkNdefCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->StdMifareContainer.currentBlock != + PH_FRINFC_MIFARESTD_MAD_BLK65) && + (NdefMap->StdMifareContainer.currentBlock != + PH_FRINFC_MIFARESTD_MAD_BLK66)) + { + Result = ((NdefMap->StdMifareContainer.ReadAcsBitFlag == + PH_FRINFC_MIFARESTD_FLAG0) ? + phFriNfc_MifStd_H_RdAcsBit(NdefMap) : + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + else + { + Result = phFriNfc_MifareStdMap_ChkNdef (NdefMap); + } + break; + + case PH_FRINFC_NDEFMAP_READ_OPE: + if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) + { + /* No permission to Read */ + Result = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED); + } + else if (NdefMap->StdMifareContainer.ReadNdefFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + Result = phFriNfc_MifStd_H_GetActCardLen (NdefMap); + } + else + { + Result = phFriNfc_MifStd_H_RdABlock (NdefMap); + } + break; + + case PH_FRINFC_NDEFMAP_WRITE_OPE: + if ((NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID) || + (NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_READ_ONLY)) + { + /* No permission to Read */ + Result = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_WRITE_FAILED); + } + else if (NdefMap->StdMifareContainer.WrNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + Result = phFriNfc_MifStd_H_GetActCardLen (NdefMap); + } + else if (NdefMap->StdMifareContainer.RdBeforeWrFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + /*NdefMap->StdMifareContainer.ReadFlag = + PH_FRINFC_MIFARESTD_FLAG0;*/ + Result = phFriNfc_MifStd_H_RdBeforeWr (NdefMap); + } + else if (NdefMap->StdMifareContainer.RdAfterWrFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + Result = phFriNfc_MifStd_H_RdtoWrNdefLen (NdefMap); + } + else + { + Result = (((NdefMap->TLVStruct.NdefTLVBlock == + NdefMap->StdMifareContainer.currentBlock) && + (NdefMap->Offset == + PH_FRINFC_NDEFMAP_SEEK_BEGIN)) ? + phFriNfc_MifStd_H_RdBeforeWr (NdefMap) : + phFriNfc_MifStd_H_WrABlock (NdefMap)); + } + break; + + case PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE: + Result = ((NdefMap->StdMifareContainer.ReadFlag == + PH_FRINFC_MIFARESTD_FLAG0) ? + (PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_READ_FAILED)) : + phFriNfc_MifStd_H_GetActCardLen (NdefMap)); + break; + + default: + /* Operation is not correct */ + Result = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + + break; + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ChkNdefCmpltSects + * + * Description This function is used to check ndef to check the + * ndef compliant sectors. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_ChkNdefCmpltSects (phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t index = 0; + uint8_t index_max_4k_2k= 0; + if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) + { + index_max_4k_2k = PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; + } + else + { + index_max_4k_2k = PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR; + } + + if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) + { + for (index = PH_FRINFC_MIFARESTD_SECTOR_NO1; index < index_max_4k_2k; index++)/*Block 0 is MAD block, so it should start with 1*/ + { + /* For Mifare 4k, Block 0 to 31 contains 4 blocks */ + /* sector 0 and 15 are aid blocks */ + if (index != PH_FRINFC_MIFARESTD_SECTOR_NO16) + { + if (((index < 32) && (index != PH_FRINFC_MIFARESTD_SECTOR_NO0)) + && (NdefMap->StdMifareContainer.aid [index] == + PH_FRINFC_MIFARESTD_NON_NDEF_COMP)) + { + /* Only 3 blocks can be read/written till sector 31 */ + NdefMap->StdMifareContainer.NoOfNdefCompBlocks -= + PH_FRINFC_MIFARESTD_MAD_BLK3; + + } + else + { + /* For Mifare 4k, Block 32 to 39 contains 16 blocks */ + if(NdefMap->StdMifareContainer.aid [index] == + PH_FRINFC_MIFARESTD_NON_NDEF_COMP) + { + /* Only 15 blocks can be read/written from sector 31 */ + NdefMap->StdMifareContainer.NoOfNdefCompBlocks -= + PH_FRINFC_MIFARESTD_BLK15; + } + } + } + } /* For index > 40 */ + } + else + { + for (index = PH_FRINFC_MIFARESTD_SECTOR_NO1; + index < PH_FRINFC_MIFARESTD_SECTOR_NO16; index++) + { + if (NdefMap->StdMifareContainer.aid [index] == + PH_FRINFC_MIFARESTD_NON_NDEF_COMP) + { + /* Only three blocks can be read/written in + a sector. So if a sector is non-ndef + compliant, decrement 3 */ + NdefMap->StdMifareContainer.NoOfNdefCompBlocks -= + PH_FRINFC_MIFARESTD_MAD_BLK3; + } + } + } + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_RemainTLV + * + * Description This function is used for read ndef to process the + * remaining bytes of length (L) in the TLV. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_RemainTLV (phFriNfc_NdefMap_t *NdefMap, + uint8_t *Flag, + uint8_t *Temp16Bytes) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t CRFlag = 0; + uint16_t RemainingBytes = 0; + + RemainingBytes = ((uint16_t) NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + + if (NdefMap->StdMifareContainer.remainingSize < RemainingBytes) + { + /* If the user Buffer is greater than the Card Size + set LastBlockFlag = 1. This Flag is used to read bytes + till the end of the card only */ + RemainingBytes = NdefMap->StdMifareContainer.remainingSize; + } + + /* Remaining Bytes of length (L) in TLV <= 16 */ + if ((NdefMap->TLVStruct.BytesRemainLinTLV <= + (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && + (RemainingBytes <= NdefMap->TLVStruct.BytesRemainLinTLV)) + { + /* Copy data to user buffer */ + memcpy (&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf [(*Temp16Bytes)]), + RemainingBytes); + + NdefMap->ApduBuffIndex += RemainingBytes; + NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; + + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + if (RemainingBytes != NdefMap->TLVStruct.BytesRemainLinTLV) + { + memcpy (NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->SendRecvBuf [((*Temp16Bytes) + RemainingBytes)]), + ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes)); + + /* internal buffer length */ + NdefMap->StdMifareContainer.internalLength = + ((PH_FRINFC_MIFARESTD_BYTES_READ - + (*Temp16Bytes)) - RemainingBytes); + } + *Temp16Bytes += ((uint8_t)RemainingBytes); + /* Remaining Bytes of length value in TLV */ + NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; + + if (NdefMap->StdMifareContainer.internalLength == PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t) + (((NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + /* internal length bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + } + + if (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0) + { + /* Remaining Bytes of length (L) in TLV is Zero means that the next + coming bytes are containing type (T), length (L) in TLV */ + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + /* call completion routine */ + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + } + else if ((NdefMap->TLVStruct.BytesRemainLinTLV <= + (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && + (RemainingBytes > NdefMap->TLVStruct.BytesRemainLinTLV)) + { + /* Copy data to user buffer */ + memcpy (&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf [(*Temp16Bytes)]), + NdefMap->TLVStruct.BytesRemainLinTLV); + + NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV; + NdefMap->StdMifareContainer.remainingSize -= NdefMap->TLVStruct.BytesRemainLinTLV; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + *Temp16Bytes += ((uint8_t) NdefMap->TLVStruct.BytesRemainLinTLV); + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; + + *Flag = PH_FRINFC_MIFARESTD_FLAG1; + + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* 16 bytes completed */ + if (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_BYTES_READ) + { + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk (NdefMap); + if (Result == NFCSTATUS_SUCCESS) + { + if (NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) + { + Result = phFriNfc_MifStd_H_RdABlock (NdefMap); + } + else + { + Result = phFriNfc_MifStd_H_AuthSector (NdefMap); + } + } + } + else + { + NdefMap->TLVStruct.BytesRemainLinTLV = + PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; + /* The read operation has finished. so, completion routine + can be called. set the Completion routine(CR) flag */ + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + } + else if ((NdefMap->TLVStruct.BytesRemainLinTLV > + (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && + (RemainingBytes <= (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)))) + { + /* Copy data to user buffer */ + memcpy (&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf [(*Temp16Bytes)]), + RemainingBytes); + NdefMap->ApduBuffIndex += RemainingBytes; + NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; + + /* Remaining Bytes of length (L) in TLV */ + NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + memcpy (NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->SendRecvBuf[(RemainingBytes + (*Temp16Bytes))]), + ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) + - RemainingBytes)); + + /* internal buffer length */ + NdefMap->StdMifareContainer.internalLength = + ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes); + + if (RemainingBytes == (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t) + (((NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + /* internal length bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + } + *Temp16Bytes += ((uint8_t) RemainingBytes); + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + } + else + { + if ((NdefMap->TLVStruct.BytesRemainLinTLV > + (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) && + (RemainingBytes > (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)))) + { + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + /* Copy data to user buffer */ + memcpy (&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->SendRecvBuf [(*Temp16Bytes)]), + (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))); + NdefMap->ApduBuffIndex += (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); + NdefMap->StdMifareContainer.remainingSize -= + (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); + NdefMap->TLVStruct.BytesRemainLinTLV -= (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); + *Temp16Bytes += (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)); + if (NdefMap->TLVStruct.BytesRemainLinTLV != PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + /* 16 bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk (NdefMap); + if (Result == NFCSTATUS_SUCCESS) + { + Result = ((NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG1) ? + phFriNfc_MifStd_H_RdABlock(NdefMap) : + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + } + } + + if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t) + (((NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ChkIntLen + * + * Description This function reads ndef to process the internal bytes. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success, + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ChkIntLen(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1; + uint8_t TempintBytes = 0; + + if(NdefMap->TLVStruct.BytesRemainLinTLV != 0) + { + NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* To read the remaining length (L) in TLV */ + Result = phFriNfc_MifStd_H_IntLenWioutNdef(NdefMap, &NDEFFlag, &TempintBytes); + } + NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* check the NDEFFlag is set. if this is not set, then + in the above RemainTLV function all the 16 bytes has been + read */ + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_IntLenWioutNdef + * + * Description This function reads ndef to check the internal bytes + * without ndef tlv flag. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success, + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_IntLenWioutNdef (phFriNfc_NdefMap_t *NdefMap, + uint8_t *Flag, + uint8_t *TempintBytes) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t CRFlag = 0; + uint16_t RemainingBytes = 0; + + RemainingBytes = ((uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + + if (NdefMap->StdMifareContainer.remainingSize < RemainingBytes) + { + /* If the user Buffer is greater than the Card Size + set LastBlockFlag = 1. This Flag is used to read bytes + till the end of the card only */ + RemainingBytes = NdefMap->StdMifareContainer.remainingSize; + } + + /* Remaining Bytes of length (L) in TLV <= internal length */ + if ((NdefMap->TLVStruct.BytesRemainLinTLV <= + NdefMap->StdMifareContainer.internalLength) && + (RemainingBytes <= NdefMap->TLVStruct.BytesRemainLinTLV)) + { + memcpy (&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf [(*TempintBytes)]), + RemainingBytes); + NdefMap->ApduBuffIndex += RemainingBytes; + NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; + *TempintBytes += ((uint8_t) RemainingBytes); + + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + memcpy (NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->StdMifareContainer.internalBuf [RemainingBytes]), + (NdefMap->StdMifareContainer.internalLength - RemainingBytes)); + + /* internal buffer length */ + NdefMap->StdMifareContainer.internalLength -= RemainingBytes; + + NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; + if (NdefMap->StdMifareContainer.internalLength == PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t) + (((NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + /* internal length bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + } + + /* Remaining Bytes of length value in TLV */ + if (NdefMap->TLVStruct.BytesRemainLinTLV == 0) + { + /* Remaining Bytes of length (L) in TLV is Zero means that the next + coming bytes are containing type (T), length (L) in TLV */ + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + /* call completion routine */ + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + } + else if ((NdefMap->TLVStruct.BytesRemainLinTLV <= + NdefMap->StdMifareContainer.internalLength) && + (RemainingBytes > NdefMap->TLVStruct.BytesRemainLinTLV)) + { + memcpy (&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf [(*TempintBytes)]), + NdefMap->TLVStruct.BytesRemainLinTLV); + + NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV; + NdefMap->StdMifareContainer.remainingSize -= NdefMap->TLVStruct.BytesRemainLinTLV; + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1; + + *TempintBytes += ((uint8_t) NdefMap->TLVStruct.BytesRemainLinTLV); + *Flag = PH_FRINFC_MIFARESTD_FLAG1; + + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t) + (((NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + if (PH_FRINFC_MIFARESTD_FLAG1 == NdefMap->StdMifareContainer.ReadWriteCompleteFlag) + { + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + + if (NdefMap->TLVStruct.BytesRemainLinTLV == NdefMap->StdMifareContainer.internalLength) + { + /* Remaining Bytes in Length (L) field of TLV is 0 */ + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + /* internal length bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk (NdefMap); + if (Result == NFCSTATUS_SUCCESS) + { + Result = + ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) ? + phFriNfc_MifStd_H_RdABlock (NdefMap) : + phFriNfc_MifStd_H_AuthSector (NdefMap)); + } + } + else + { + /* Remaining Bytes in Length (L) field of TLV is 0 */ + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0; + *Flag = PH_FRINFC_MIFARESTD_FLAG1; + } + } + else if ((NdefMap->TLVStruct.BytesRemainLinTLV > + NdefMap->StdMifareContainer.internalLength) && + (RemainingBytes <= NdefMap->StdMifareContainer.internalLength)) + { + memcpy(&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf [(*TempintBytes)]), + RemainingBytes); + + NdefMap->ApduBuffIndex += RemainingBytes; + NdefMap->StdMifareContainer.remainingSize -= RemainingBytes; + *TempintBytes += ((uint8_t) RemainingBytes); + /* Remaining Bytes of length (L) in TLV */ + NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes; + + /* copy the bytes to internal buffer, that are read, + but not used for the user buffer */ + memcpy (NdefMap->StdMifareContainer.internalBuf, + &(NdefMap->StdMifareContainer.internalBuf [RemainingBytes]), + (NdefMap->StdMifareContainer.internalLength - RemainingBytes)); + + /* internal buffer length */ + NdefMap->StdMifareContainer.internalLength -= RemainingBytes; + if (NdefMap->StdMifareContainer.internalLength == PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t) + (((NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0)) ? + PH_FRINFC_MIFARESTD_FLAG1 : + PH_FRINFC_MIFARESTD_FLAG0); + + /* internal length bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + } + + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + } + else + { + if ((NdefMap->TLVStruct.BytesRemainLinTLV > + NdefMap->StdMifareContainer.internalLength) && + (RemainingBytes > NdefMap->StdMifareContainer.internalLength)) + { + memcpy (&(NdefMap->ApduBuffer [NdefMap->ApduBuffIndex]), + &(NdefMap->StdMifareContainer.internalBuf [(*TempintBytes)]), + NdefMap->StdMifareContainer.internalLength); + *Flag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->ApduBuffIndex += NdefMap->StdMifareContainer.internalLength; + NdefMap->StdMifareContainer.remainingSize -= + NdefMap->StdMifareContainer.internalLength; + NdefMap->TLVStruct.BytesRemainLinTLV -= NdefMap->StdMifareContainer.internalLength; + + if(NdefMap->TLVStruct.BytesRemainLinTLV != PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0) + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + /* internal length bytes completed */ + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + if(Result == NFCSTATUS_SUCCESS) + { + Result = ((NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG1)? + phFriNfc_MifStd_H_RdABlock(NdefMap): + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + } + } + + if(CRFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t) + (((NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_WriteNdefLen + * + * Description This function is Helper function for write ndef + * to write the Length TLV. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_WriteNdefLen(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN; + + /* If Current block = Ndef TLV block then the starting point + is writing from type of TLV + Else */ + + if(NdefMap->StdMifareContainer.currentBlock == + NdefMap->TLVStruct.NdefTLVBlock) + { + + if(NdefMap->TLVStruct.NULLTLVCount >= + PH_FRINFC_MIFARESTD_VAL2) + { + phFriNfc_MifStd_H_fillTLV1(NdefMap); + } + else + { + phFriNfc_MifStd_H_fillTLV2(NdefMap); + } + } + else + { + if(NdefMap->TLVStruct.NULLTLVCount >= + PH_FRINFC_MIFARESTD_VAL2) + { + phFriNfc_MifStd_H_fillTLV1_1(NdefMap); + } + else + { + phFriNfc_MifStd_H_fillTLV2_1(NdefMap); + } + } + + memcpy( NdefMap->StdMifareContainer.Buffer, + &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]), + PH_FRINFC_MIFARESTD_BYTES_READ); + + + /* Write from here */ + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; + + NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_RdWrReset + * + * Description It resets ndef TLV values. This is used when the offset + * is BEGIN. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_RdWrReset(phFriNfc_NdefMap_t *NdefMap) +{ + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4; + NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL1; + NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_MIFARESTD_MAD_BLK0; + NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.remainingSize = (uint16_t) + (NdefMap->StdMifareContainer.NoOfNdefCompBlocks * + PH_FRINFC_MIFARESTD_BLOCK_BYTES); + NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL1; + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_RdtoWrNdefLen + * + * Description This function is used to read the first ndef compliant + * block to change the length. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_RdtoWrNdefLen(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_TO_WR_NDEF_LEN; + + if(NdefMap->TLVStruct.NdefTLVAuthFlag == PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + Result = phFriNfc_MifStd_H_AuthSector(NdefMap); + } + else + { + NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock; + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + NdefMap->Cmd.MfCmd = phHal_eMifareRead; + + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_SetNdefBlkAuth + * + * Description This function is used to set the authentication flag + * for the ndef TLV block. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_SetNdefBlkAuth(phFriNfc_NdefMap_t *NdefMap) +{ + NdefMap->TLVStruct.NdefTLVAuthFlag = + ((phFriNfc_MifStd_H_GetSect(NdefMap->TLVStruct.NdefTLVBlock) + == phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock))? + PH_FRINFC_MIFARESTD_FLAG0: + PH_FRINFC_MIFARESTD_FLAG1); + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_GetActCardLen + * + * Description Helper function to get the actual length of card. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_GetActCardLen(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_GET_ACT_CARDSIZE; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE; + + Result = ((NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG0)? + phFriNfc_MifStd_H_AuthSector(NdefMap): + phFriNfc_MifStd_H_Rd16Bytes(NdefMap, + NdefMap->StdMifareContainer.currentBlock)); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ChkTLVs + * + * Description Helper function to check all the TLVs. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ChkTLVs(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t TempLength = PH_FRINFC_MIFARESTD_VAL0, + ShiftLength = PH_FRINFC_MIFARESTD_VAL0; + uint8_t TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; + + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE; + TempLength = NdefMap->TLVStruct.NdefTLVByte; + + for(;;) + { + if((NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_TERMTLV_T) && + (NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_NULLTLV_T) && + (NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_NDEFTLV_T) && + (FALSE == NdefMap->TLVStruct.NdefTLVFoundFlag)) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + NdefMap->TLVStruct.BytesRemainLinTLV = 0; + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + + } + else + if((NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_TERMTLV_T) && + (NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_NULLTLV_T)) + { + if(NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_NDEFTLV_T) + { + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = (uint8_t)TempLength; + NdefMap->TLVStruct.NdefTLVFoundFlag = + ((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_MIFARESTD_NDEFTLV_T)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->TLVStruct.NULLTLVCount = ((NdefMap->TLVStruct.NULLTLVCount + == PH_FRINFC_MIFARESTD_VAL1)? + PH_FRINFC_MIFARESTD_VAL0: + NdefMap->TLVStruct.NULLTLVCount); + } + else + { + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + } + + TempLength++; + if(TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_MIFARESTD_VAL3; + } + Result = phFriNfc_MifStd_H_Chk16Bytes( NdefMap, + TempLength); + if(Result != NFCSTATUS_SUCCESS) + { + *CRFlag = (uint8_t)((Result == NFCSTATUS_PENDING)? + PH_FRINFC_MIFARESTD_FLAG0: + PH_FRINFC_MIFARESTD_FLAG1); + break; + } + + if((((( NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) + + (PH_FRINFC_MIFARESTD_BLOCK_BYTES - + TempLength)) < + NdefMap->SendRecvBuf[TempLength]) && + ((NdefMap->SendRecvBuf[TempLength] < + PH_FRINFC_MIFARESTD_NDEFTLV_L) && + (NdefMap->TLVStruct.NdefTLVFoundFlag != + PH_FRINFC_MIFARESTD_VAL1))) + { + /* Result = Error */ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + + if((((( NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) + + (PH_FRINFC_MIFARESTD_BLOCK_BYTES - + TempLength)) < + NdefMap->SendRecvBuf[TempLength]) && + ((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_MIFARESTD_VAL0) && + (NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_VAL1))) + { + /* Result = Error */ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + + if((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->SendRecvBuf[TempLength] < + PH_FRINFC_MIFARESTD_NDEFTLV_L)) + { + Result = phFriNfc_MapTool_SetCardState(NdefMap, + NdefMap->SendRecvBuf[TempLength]); + NdefMap->TLVStruct.BytesRemainLinTLV = + NdefMap->SendRecvBuf[TempLength]; + NdefMap->StdMifareContainer.remainingSize -= + PH_FRINFC_MIFARESTD_VAL2; + /* This flag is set */ + NdefMap->StdMifareContainer.remSizeUpdFlag = + (uint8_t)((NdefMap->TLVStruct.NULLTLVCount >= + PH_FRINFC_MIFARESTD_VAL2)? + PH_FRINFC_MIFARESTD_FLAG0: + PH_FRINFC_MIFARESTD_FLAG1); + + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + + NdefMap->StdMifareContainer.remainingSize -= + (( NdefMap->SendRecvBuf[TempLength] < + PH_FRINFC_MIFARESTD_NDEFTLV_L)? + (NdefMap->SendRecvBuf[TempLength] + + PH_FRINFC_MIFARESTD_VAL2): + PH_FRINFC_MIFARESTD_VAL0); + + if(( NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_MIFARESTD_VAL0)) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + + TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* get the next TLV after the proprietary TLV */ + Result = + ((NdefMap->SendRecvBuf[TempLength] < + PH_FRINFC_MIFARESTD_NDEFTLV_L)? + phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag): + NFCSTATUS_PENDING); + + if((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) && + (Result == NFCSTATUS_SUCCESS)) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_MIFARESTD_VAL0; + + Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); + *CRFlag = (uint8_t)((Result != NFCSTATUS_PENDING)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + break; + } + else + { + if(Result == NFCSTATUS_PENDING) + { + TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG1; + Result = ((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_MIFARESTD_NDEFTLV_L) ? + NFCSTATUS_SUCCESS: + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER))); + + if(Result != NFCSTATUS_SUCCESS) + { + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + TempLength++; + /* Check 0xFF */ + if(TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_MIFARESTD_VAL2; + } + Result = phFriNfc_MifStd_H_Chk16Bytes( NdefMap, + TempLength); + if(Result != NFCSTATUS_SUCCESS) + { + break; + } + + ShiftLength = NdefMap->SendRecvBuf[TempLength]; + TempLength++; + if(TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_MIFARESTD_VAL1; + NdefMap->TLVStruct.prevLenByteValue = + NdefMap->SendRecvBuf[(TempLength - + PH_FRINFC_MIFARESTD_VAL1)]; + } + Result = phFriNfc_MifStd_H_Chk16Bytes( NdefMap, + TempLength); + if(Result != NFCSTATUS_SUCCESS) + { + break; + } + + + if(((( NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) + + (PH_FRINFC_MIFARESTD_BLOCK_BYTES - + TempLength)) < + (( ShiftLength + << 8) + NdefMap->SendRecvBuf[TempLength])) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + + break; + } + + if(NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + ShiftLength = (( ShiftLength<< 8) + + NdefMap->SendRecvBuf[TempLength]); + NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength; + Result = phFriNfc_MapTool_SetCardState(NdefMap, + ShiftLength); + NdefMap->StdMifareContainer.remainingSize -= + PH_FRINFC_MIFARESTD_VAL4; + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + break; + } + + NdefMap->StdMifareContainer.remainingSize -= + ((ShiftLength<< 8) + + NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]); + TempLength++; + + /* get the next TLV after the proprietary TLV */ + Result = phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag); + + if((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) && + (Result == NFCSTATUS_SUCCESS)) + { + NdefMap->TLVStruct.TcheckedinTLVFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->TLVStruct.NoLbytesinTLV = + PH_FRINFC_MIFARESTD_VAL0; + Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); + + break; + } + break; + } + } + } + else if((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_TERMTLV_T) && + (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG0)) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + break; + + } + else if(NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_NULLTLV_T) + { + TempLength++; + NdefMap->TLVStruct.NULLTLVCount += PH_FRINFC_MIFARESTD_VAL1; + ShiftLength = NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)]; + NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL1; + if(NdefMap->StdMifareContainer.remainingSize < + (( ShiftLength << 8) + NdefMap->SendRecvBuf[TempLength])) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + break; + } + Result = phFriNfc_MifStd_H_Chk16Bytes( NdefMap, + TempLength); + if(Result != NFCSTATUS_SUCCESS) + { + NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0; + break; + } + } + else + { + if((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_TERMTLV_T) && + (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1)) + { + TempLength++; + Result = NFCSTATUS_SUCCESS; + NdefMap->StdMifareContainer.remainingSize -= + PH_FRINFC_MIFARESTD_VAL1; + } + } + } + + if(NdefMap->TLVStruct.BytesRemainLinTLV > + NdefMap->StdMifareContainer.remainingSize) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + } + else + { + if(NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) + { + Result = ((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + NFCSTATUS_SUCCESS: + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER))); + } + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_GetNxtTLV + * + * Description This is a Helper function to get the next TLV. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_GetNxtTLV(phFriNfc_NdefMap_t *NdefMap, + uint16_t *TempLength, + uint8_t *TL4bytesFlag) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t LengthRemaining = PH_FRINFC_MIFARESTD_VAL0, + TempLen = PH_FRINFC_MIFARESTD_VAL0, + ShiftLength = PH_FRINFC_MIFARESTD_VAL0; + + TempLen = (*TempLength); + LengthRemaining = (PH_FRINFC_MIFARESTD_BYTES_READ - + (TempLen + PH_FRINFC_MIFARESTD_VAL1)); + + if(*TL4bytesFlag == PH_FRINFC_MIFARESTD_FLAG0) + { + (*TempLength) += (NdefMap->SendRecvBuf[TempLen] + + PH_FRINFC_MIFARESTD_VAL1); + + if(NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG0) + { + LengthRemaining = + (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)? + PH_FRINFC_MIFARESTD_VAL0: + (NdefMap->SendRecvBuf[TempLen] - + LengthRemaining)); + } + else + { + LengthRemaining = + (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)? + PH_FRINFC_MIFARESTD_VAL0: + (NdefMap->SendRecvBuf[TempLen] - + LengthRemaining)); + } + } + else + { + *TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; + if(NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_MIFARESTD_VAL1) + { + ShiftLength = NdefMap->TLVStruct.prevLenByteValue; + (*TempLength) += ((ShiftLength + << 8) + NdefMap->SendRecvBuf[TempLen] + + PH_FRINFC_MIFARESTD_VAL1); + + LengthRemaining = + (((ShiftLength + << 8) + NdefMap->SendRecvBuf[TempLen]) - + LengthRemaining); + } + else + { + ShiftLength = NdefMap->SendRecvBuf[(TempLen - PH_FRINFC_MIFARESTD_VAL1)]; + (*TempLength) += ((ShiftLength + << 8) + NdefMap->SendRecvBuf[TempLen] + + PH_FRINFC_MIFARESTD_VAL1); + + LengthRemaining = + (((ShiftLength + << 8) + NdefMap->SendRecvBuf[TempLen]) - + LengthRemaining); + } + } + + NdefMap->TLVStruct.NdefTLVByte = + (uint8_t)(((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)? + (*TempLength): + (LengthRemaining % PH_FRINFC_MIFARESTD_BYTES_READ)); + + while(LengthRemaining != PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + LengthRemaining -= + ((LengthRemaining <= PH_FRINFC_MIFARESTD_BYTES_READ)? + LengthRemaining: + PH_FRINFC_MIFARESTD_BYTES_READ); + } + + if(NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_Chk16Bytes + * + * Description This Helper function is used to know whether the read + * 16 bytes are parsed completely. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_Chk16Bytes(phFriNfc_NdefMap_t *NdefMap, + uint16_t TempLength) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + if(TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + + Result = + ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1)? + phFriNfc_MifStd_H_GetActCardLen(NdefMap): + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ChkRemainTLVs + * + * Description This function is used to know whether the read + * 16 bytes are parsed completely. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ChkRemainTLVs(phFriNfc_NdefMap_t *NdefMap, + uint8_t *CRFlag, + uint8_t *NDEFFlag) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t TempLength = PH_FRINFC_MIFARESTD_VAL0, + ShiftLength = PH_FRINFC_MIFARESTD_VAL0; + uint8_t TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; + + switch(NdefMap->TLVStruct.NoLbytesinTLV) + { + case PH_FRINFC_MIFARESTD_VAL3: + /* if TLV is found then set card state */ + Result = ((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + phFriNfc_MapTool_SetCardState(NdefMap, + NdefMap->SendRecvBuf[TempLength]): + Result); + + Result = ((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1)? 1 : Result); + + + /* Check the length field is less than or + equal to 0xFF if yes enter below statement + else enter else if*/ + if((NdefMap->SendRecvBuf[TempLength] < + PH_FRINFC_MIFARESTD_NDEFTLV_L) && + (Result == NFCSTATUS_SUCCESS)) + { + NdefMap->StdMifareContainer.remainingSize -= + PH_FRINFC_MIFARESTD_VAL2; + + Result = ((NdefMap->SendRecvBuf[TempLength] > + NdefMap->StdMifareContainer.remainingSize)? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT)): + Result); + TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; + if((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (Result == NFCSTATUS_SUCCESS)) + { + NdefMap->TLVStruct.BytesRemainLinTLV = + NdefMap->SendRecvBuf[TempLength]; + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + + } + else if(Result == NFCSTATUS_SUCCESS) + { + TempLength++; + Result = phFriNfc_MifStd_H_GetNxtTLV(NdefMap, + &TempLength, &TL4bytesFlag); + + NdefMap->StdMifareContainer.remainingSize -= + NdefMap->SendRecvBuf[TempLength]; + if((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) && + (*CRFlag == PH_FRINFC_MIFARESTD_FLAG0)) + { + *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); + } + } + + else + { + /* do nothing */ + } + } + else if((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_MIFARESTD_NDEFTLV_L) && + (Result == NFCSTATUS_SUCCESS)) + { + TempLength++; + NdefMap->StdMifareContainer.remainingSize -= + PH_FRINFC_MIFARESTD_VAL4; + TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0; + Result = (((((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)]) > + NdefMap->StdMifareContainer.remainingSize)? + (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT)): + Result); + if((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (Result == NFCSTATUS_SUCCESS)) + { + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.BytesRemainLinTLV = + (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)]); + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + else if(Result == NFCSTATUS_SUCCESS) + { + TempLength++; + + Result = phFriNfc_MifStd_H_GetNxtTLV(NdefMap, + &TempLength, &TL4bytesFlag); + NdefMap->StdMifareContainer.remainingSize -= + (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)]); + + *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); + } + else + { + /* do nothing */ + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + } + else + { + /* Result = Error */ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + break; + + case PH_FRINFC_MIFARESTD_VAL2: + case PH_FRINFC_MIFARESTD_VAL1: + ShiftLength = ((NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_MIFARESTD_VAL1)? + ((NdefMap->TLVStruct.prevLenByteValue << 8) + + NdefMap->SendRecvBuf[TempLength]): + (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) + + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)])); + if(((( NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + NdefMap->StdMifareContainer.NdefBlocks) * + PH_FRINFC_MIFARESTD_BLOCK_BYTES) + + (PH_FRINFC_MIFARESTD_BLOCK_BYTES - + TempLength)) < + ShiftLength) + { + /* Result = Error */ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + else + { + NdefMap->StdMifareContainer.remainingSize -= + PH_FRINFC_MIFARESTD_VAL2; + if(NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength; + if(NdefMap->TLVStruct.BytesRemainLinTLV > + NdefMap->StdMifareContainer.remainingSize) + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT); + } + *CRFlag = PH_FRINFC_MIFARESTD_FLAG1; + *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + } + else + { + NdefMap->StdMifareContainer.remainingSize -= + ShiftLength; + *CRFlag = PH_FRINFC_MIFARESTD_FLAG0; + TempLength += PH_FRINFC_MIFARESTD_VAL2; + TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG1; + Result = ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1)? + NFCSTATUS_SUCCESS: + phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag)); + + *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap); + } + } + break; + + default: + break; + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_Get1kStTrail + * + * Description This function is used to get the Mifare 1k Sector Trailer. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_Get1kStTrail(phFriNfc_NdefMap_t *NdefMap) +{ + switch((NdefMap->StdMifareContainer.currentBlock % 4)) + { + case PH_FRINFC_MIFARESTD_VAL0: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_MAD_BLK3); + break; + + case PH_FRINFC_MIFARESTD_VAL1: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_MAD_BLK2); + break; + + case PH_FRINFC_MIFARESTD_VAL2: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_MAD_BLK1); + break; + + default: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + NdefMap->StdMifareContainer.currentBlock; + break; + } + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_Get4kStTrail + * + * Description This function gets the Mifare 4k Sector Trailer. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_Get4kStTrail(phFriNfc_NdefMap_t *NdefMap) +{ + switch((NdefMap->StdMifareContainer.currentBlock % 16)) + { + case PH_FRINFC_MIFARESTD_MAD_BLK0: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK15); + break; + + case PH_FRINFC_MIFARESTD_MAD_BLK1: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK14); + break; + + case PH_FRINFC_MIFARESTD_MAD_BLK2: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK13); + break; + + case PH_FRINFC_MIFARESTD_MAD_BLK3: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK12); + break; + + case PH_FRINFC_MIFARESTD_BLK4: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK11); + break; + + case PH_FRINFC_MIFARESTD_BLK5: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK10); + break; + + case PH_FRINFC_MIFARESTD_BLK6: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK9); + break; + + case PH_FRINFC_MIFARESTD_BLK7: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK8); + break; + + case PH_FRINFC_MIFARESTD_BLK8: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK7); + break; + + case PH_FRINFC_MIFARESTD_BLK9: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK6); + break; + + case PH_FRINFC_MIFARESTD_BLK10: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK5); + break; + + case PH_FRINFC_MIFARESTD_BLK11: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK4); + break; + + case PH_FRINFC_MIFARESTD_BLK12: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_MAD_BLK3); + break; + + case PH_FRINFC_MIFARESTD_BLK13: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_MAD_BLK2); + break; + + case PH_FRINFC_MIFARESTD_BLK14: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + (NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_MAD_BLK1); + break; + + default: + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + NdefMap->StdMifareContainer.currentBlock; + break; + } + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProChkNdef + * + * Description This function processes the check ndef call. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProChkNdef(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Copy remaining bytes into the AID array + from Receive Buffer till array number 7 in aid */ + if(NdefMap->StdMifareContainer.currentBlock == + PH_FRINFC_MIFARESTD_VAL1) + { + /* Helper Function to Store AID Information */ + phFriNfc_MifStd_H_fillAIDarray(NdefMap); + + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_VAL2; + /* read remaining AIDs from block number 2 */ + Result = ((NdefMap->StdMifareContainer.aidCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + Result: + phFriNfc_MifareStdMap_ChkNdef( NdefMap)); + } + else if(((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) && + (NdefMap->StdMifareContainer.currentBlock == + PH_FRINFC_MIFARESTD_MAD_BLK2)) || ( + (NdefMap->StdMifareContainer.currentBlock == + PH_FRINFC_MIFARESTD_MAD_BLK66) && + (NdefMap->CardType == + PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || + NdefMap->CardType == + PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))) + { + /* Helper Function to Store AID Information */ + phFriNfc_MifStd_H_fillAIDarray(NdefMap); + + NdefMap->StdMifareContainer.aidCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + } /* Mifare 1k and Mifare 4k end Check */ + else if((NdefMap->StdMifareContainer.currentBlock > + PH_FRINFC_MIFARESTD_VAL1) && + (NdefMap->CardType == + PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || + NdefMap->CardType == + PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) + { + phFriNfc_MifStd_H_fillAIDarray(NdefMap); + /* read remaining AIDs from block number 2 */ + /* Mifare 4k Helper Function */ + Result = ((NdefMap->StdMifareContainer.aidCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + Result: + phFriNfc_MifStd4k_H_CheckNdef(NdefMap)); + } /* Card Type 4k Check */ + else + { + /* Since we have decided temporarily not to go + for any new error codes we are using + NFCSTATUS_INVALID_PARAMETER even though it is not + the relevant error code here TBD */ + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + } + + if(NdefMap->StdMifareContainer.aidCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->StdMifareContainer.ChkNdefCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + /* The check for NDEF compliant information is now over for + the Mifare 1K card. + Update(decrement) the NoOfNdefCompBlocks as much required, + depending on the NDEF compliant information found */ + /* Check the Sectors are Ndef Compliant */ + phFriNfc_MifStd_H_ChkNdefCmpltSects(NdefMap); + if((NdefMap->StdMifareContainer.NoOfNdefCompBlocks == 0) || + (NdefMap->StdMifareContainer.NoOfNdefCompBlocks > 255)) + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } + else + { + NdefMap->StdMifareContainer.aidCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.NFCforumSectFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + Result = ((Result != NFCSTATUS_SUCCESS)? + Result:phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProAuth + * + * Description This function process the authentication of a sector. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProAuth(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + if(NdefMap->TLVStruct.NdefTLVAuthFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + NdefMap->TLVStruct.NdefTLVAuthFlag = + PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG1; + Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); + } + else + { + NdefMap->StdMifareContainer.AuthDone = 1; + NdefMap->StdMifareContainer.ReadAcsBitFlag = 1; + Result = phFriNfc_MifStd_H_RdAcsBit(NdefMap); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_Rd16Bytes + * + * Description This function reads 16 bytes from a specifed block no. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_Rd16Bytes(phFriNfc_NdefMap_t *NdefMap, + uint8_t BlockNo) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = BlockNo; + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + NdefMap->Cmd.MfCmd = phHal_eMifareRead; + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProAcsBits + * + * Description It processes access bits of the sector trailer. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProAcsBits(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t CRFlag = PH_FRINFC_MIFARESTD_FLAG0; + + if(*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + if(NdefMap->StdMifareContainer.ReadAcsBitFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + /* check for the correct access bits */ + Result = phFriNfc_MifStd_H_ChkAcsBit(NdefMap); + + if((NdefMap->StdMifareContainer.ChkNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (Result == NFCSTATUS_SUCCESS)) + { + if(NdefMap->CardState == + PH_NDEFMAP_CARD_STATE_INVALID) + { + NdefMap->StdMifareContainer.NoOfNdefCompBlocks = + ((NdefMap->StdMifareContainer.currentBlock >= + PH_FRINFC_MIFARESTD4K_BLK128)? + (NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + PH_FRINFC_MIFARESTD_BLK15): + (NdefMap->StdMifareContainer.NoOfNdefCompBlocks - + PH_FRINFC_MIFARESTD_MAD_BLK3)); + + NdefMap->StdMifareContainer.ProprforumSectFlag = + ((NdefMap->StdMifareContainer.NFCforumSectFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG: + PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG); + + Result = phFriNfc_MifStd_H_ProStatNotValid(NdefMap, Result); + } + else + { + NdefMap->StdMifareContainer.NFCforumSectFlag = + (((NdefMap->StdMifareContainer.currentBlock == 64) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)|| + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))? + NdefMap->StdMifareContainer.NFCforumSectFlag: + PH_FRINFC_MIFARESTD_FLAG1); + } + + if(NdefMap->StdMifareContainer.ProprforumSectFlag != + PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG) + { + NdefMap->StdMifareContainer.ReadAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* ((NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + PH_FRINFC_MIFARESTD_FLAG0: + PH_FRINFC_MIFARESTD_FLAG1);*/ + + NdefMap->StdMifareContainer.ReadCompleteFlag = + (uint8_t)((((((NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL4) >= + PH_FRINFC_MIFARESTD1K_MAX_BLK) && + (NdefMap->CardType == + PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) && + (NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG0)) || + (NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->StdMifareContainer.ReadCompleteFlag = + (uint8_t)((((((uint16_t)(NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL4) >= + PH_FRINFC_MIFARESTD4K_MAX_BLK) && + (NdefMap->CardType == + PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) && + (NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG0)) || + (NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->StdMifareContainer.ReadCompleteFlag = + (uint8_t)((((((uint16_t)(NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL4) >= + PH_FRINFC_MIFARESTD4K_MAX_BLK) && + (NdefMap->CardType == + PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)) && + (NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG0)) || + (NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->StdMifareContainer.currentBlock = + ((NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + PH_FRINFC_MIFARESTD_BLK4: + NdefMap->StdMifareContainer.currentBlock); + + Result = + ((NdefMap->StdMifareContainer.ReadCompleteFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + phFriNfc_MifStd_H_BlkChk(NdefMap): + Result); + } + } + + Result = ((Result != NFCSTATUS_SUCCESS)? + Result: + phFriNfc_MifStd_H_ChkRdWr(NdefMap)); + } + else + { + NdefMap->StdMifareContainer.ChkNdefFlag = + PH_FRINFC_MIFARESTD_FLAG0; + /* Here its required to read the entire card to know the */ + /* Get exact ndef size of the card */ + Result = phFriNfc_MifStd_H_ChkTLVs(NdefMap, &CRFlag); + } + } + else + { + /* Since we have decided temporarily not to go + for any new error codes we are using + NFCSTATUS_INVALID_PARAMETER even though it is not + the relevant error code here TBD */ + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_GPBChk + * + * Description This function is checks the GPB bytes. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Spec version needs to be checked every time (Version check is not enabled) */ + /* Result = phFriNfc_MapTool_ChkSpcVer(NdefMap, PH_FRINFC_MIFARESTD_VAL9); */ + + /* Check rhe read and write access field + in GPB is 00b + bit 0 and 1 for write access check + bit 2 and 3 for read access check */ + if(Result == NFCSTATUS_SUCCESS) + { + if(((NdefMap->SendRecvBuf[ + PH_FRINFC_MIFARESTD_VAL9] & + PH_FRINFC_MIFARESTD_MASK_GPB_WR) == + PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL) && + ((NdefMap->SendRecvBuf[ + PH_FRINFC_MIFARESTD_VAL9] & + PH_FRINFC_MIFARESTD_MASK_GPB_RD) == + PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL)) + { + NdefMap->CardState = (((NdefMap->StdMifareContainer.ChkNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) || + (NdefMap->StdMifareContainer.ReadNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1) || + (NdefMap->StdMifareContainer.WrNdefFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_NDEFMAP_CARD_STATE_INITIALIZED: + PH_NDEFMAP_CARD_STATE_READ_WRITE); + } + else if(((NdefMap->SendRecvBuf[ + PH_FRINFC_MIFARESTD_VAL9] & + PH_FRINFC_MIFARESTD_MASK_GPB_WR) != + PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL) && + ((NdefMap->SendRecvBuf[ + PH_FRINFC_MIFARESTD_VAL9] & + PH_FRINFC_MIFARESTD_MASK_GPB_RD) == + PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL)) + { + /* write access not given + only read access check */ + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; + } + else + { + NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; + } + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProStatNotValid + * + * Description This function checks for the different status value in the + * process because of proprietary forum sector. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProStatNotValid(phFriNfc_NdefMap_t *NdefMap, + NFCSTATUS status) +{ + NFCSTATUS Result = status; + + /* if NFC forum sector is not found before the proprietary one then + authenticate the next sector + Else it is a error*/ + if(NdefMap->StdMifareContainer.NFCforumSectFlag == + PH_FRINFC_MIFARESTD_FLAG0) + { + NdefMap->StdMifareContainer.ProprforumSectFlag = + PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG; + if(NdefMap->StdMifareContainer.currentBlock < + PH_FRINFC_MIFARESTD4K_BLK128) + { + /* Fix for the disovery problem, + if 1st sector is invalid then ignore the remaining sectors and + send an error if the card is mifare 1k, + if the card is mifare 4k, then update the block number to 67 and + continue. + Even if the authentication of that block fails then send error */ + if(((NdefMap->StdMifareContainer.currentBlock < + PH_FRINFC_MIFARESTD_BLK4) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) || + ((NdefMap->StdMifareContainer.currentBlock <= + PH_FRINFC_MIFARESTD_MAD_BLK67) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))) + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } + else if((NdefMap->StdMifareContainer.currentBlock < + PH_FRINFC_MIFARESTD_BLK4) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD || + NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) + { + Result = NFCSTATUS_SUCCESS; + NdefMap->StdMifareContainer.currentBlock = + PH_FRINFC_MIFARESTD_MAD_BLK67; + } + else if(((NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK4) > + PH_FRINFC_MIFARESTD1K_MAX_BLK) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } + else + { + NdefMap->StdMifareContainer.remainingSize -= + (PH_FRINFC_MIFARESTD_MAD_BLK3 * PH_FRINFC_MIFARESTD_BLOCK_BYTES); + NdefMap->StdMifareContainer.currentBlock += + PH_FRINFC_MIFARESTD_BLK4; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + } + } + else if((NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_BLK15) > + PH_FRINFC_MIFARESTD4K_MAX_BLK) + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } + else + { + NdefMap->StdMifareContainer.remainingSize -= + (PH_FRINFC_MIFARESTD_BLK15 * PH_FRINFC_MIFARESTD_BLOCK_BYTES); + NdefMap->StdMifareContainer.currentBlock += + PH_FRINFC_MIFARESTD_BLOCK_BYTES; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + } + Result = ((Result != NFCSTATUS_SUCCESS)? + (PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT)): + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + else if((NdefMap->StdMifareContainer.ProprforumSectFlag == + PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG) && + (NdefMap->StdMifareContainer.NFCforumSectFlag == + PH_FRINFC_MIFARESTD_FLAG1)) + { + /* if the proprietary forum sector are found before + NFC forum sector then again a proprietary + forum sector are found after the NFC forum + sector */ + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } + else + { + NdefMap->StdMifareContainer.ProprforumSectFlag = + PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG; + switch(NdefMap->PrevOperation) + { + case PH_FRINFC_NDEFMAP_CHECK_OPE: + case PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE: + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + break; + + case PH_FRINFC_NDEFMAP_READ_OPE: + if((NdefMap->TLVStruct.NdefTLVFoundFlag == + PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->TLVStruct.NoLbytesinTLV == + PH_FRINFC_MIFARESTD_VAL0)) + { + *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; + Result = NFCSTATUS_SUCCESS; + } + else + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } + break; + + case PH_FRINFC_NDEFMAP_WRITE_OPE: + default: + /* This means the further write is not possible, + EOF_NDEF_CONTAINER_REACHED */ + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + PH_FRINFC_MIFARESTD_FLAG1; + /* Write the length to the L field in the TLV */ + NdefMap->StdMifareContainer.TempBlockNo = + NdefMap->StdMifareContainer.currentBlock; + phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); + NdefMap->StdMifareContainer.currentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); + break; + } + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_RdBeforeWr + * + * Description This function is used to read the NDEF TLV block. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_RdBeforeWr(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_BEF_WR; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; + + Result = phFriNfc_MifStd_H_Rd16Bytes(NdefMap, + NdefMap->StdMifareContainer.currentBlock); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProBytesToWr + * + * Description This function processes the NDEF TLV block read bytes to + * start write from the NDEF TLV. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProBytesToWr(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0; + + if(*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + memcpy(&NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1], + NdefMap->SendRecvBuf, + PH_FRINFC_MIFARESTD_BLOCK_BYTES); + + /* Write to Ndef TLV Block */ + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + NdefMap->StdMifareContainer.currentBlock; + + TempLength = ((NdefMap->StdMifareContainer.currentBlock == + NdefMap->TLVStruct.NdefTLVBlock)? + phFriNfc_MifStd_H_UpdateTLV(NdefMap): + phFriNfc_MifStd_H_UpdRemTLV(NdefMap)); + + NdefMap->StdMifareContainer.remainingSize -= + ((NdefMap->StdMifareContainer.remSizeUpdFlag == + PH_FRINFC_MIFARESTD_FLAG1)? + PH_FRINFC_MIFARESTD_VAL2: + PH_FRINFC_MIFARESTD_VAL0); + + NdefMap->StdMifareContainer.remSizeUpdFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_TLV; + Result = ((TempLength == PH_FRINFC_MIFARESTD_BLOCK_BYTES)? + phFriNfc_MifStd_H_WrTLV(NdefMap): + phFriNfc_MifStd_H_fillSendBuf(NdefMap, TempLength)); + } + else + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_READ_FAILED); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_UpdateTLV + * + * Description This function writes ndef to add the TLV structure. + * + * Returns uint8_t TempLength + * + ******************************************************************************/ +static uint8_t phFriNfc_MifStd_H_UpdateTLV(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0; + + TempLength = (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL1); + /* Creating TLV */ + if(NdefMap->TLVStruct.NULLTLVCount >= 2) + { + if((PH_FRINFC_MIFARESTD_BYTES_READ - TempLength) == + PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + } + else + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; + } + } + else + { + switch((PH_FRINFC_MIFARESTD_BYTES_READ - + TempLength)) + { + case PH_FRINFC_MIFARESTD_VAL0: + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + break; + + case PH_FRINFC_MIFARESTD_VAL1: + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->TLVStruct.prevLenByteValue = + (uint16_t)((NdefMap->SendRecvBuf[TempLength] >= + PH_FRINFC_MIFARESTD_NDEFTLV_L)? + PH_FRINFC_MIFARESTD_VAL0: + NdefMap->SendRecvBuf[TempLength]); + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + break; + + case PH_FRINFC_MIFARESTD_VAL2: + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->TLVStruct.prevLenByteValue = + (uint16_t)((NdefMap->SendRecvBuf[TempLength] >= + PH_FRINFC_MIFARESTD_NDEFTLV_L)? + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)]: + NdefMap->SendRecvBuf[TempLength]); + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + break; + + default: + NdefMap->TLVStruct.prevLenByteValue = + NdefMap->SendRecvBuf[TempLength]; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; + break; + } + } + + return TempLength; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_fillSendBuf + * + * Description It fill the send buffer to write. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_fillSendBuf(phFriNfc_NdefMap_t *NdefMap, + uint8_t Length) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint16_t RemainingBytes = PH_FRINFC_MIFARESTD_VAL0, + BytesToWrite = PH_FRINFC_MIFARESTD_VAL0; + uint8_t index = PH_FRINFC_MIFARESTD_VAL0; + + Length = (Length + PH_FRINFC_MIFARESTD_VAL1); + + RemainingBytes = (uint16_t)((NdefMap->StdMifareContainer.remainingSize + < (uint16_t)(NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex))? + NdefMap->StdMifareContainer.remainingSize: + (NdefMap->ApduBufferSize - + NdefMap->ApduBuffIndex)); + + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = + NdefMap->StdMifareContainer.currentBlock; + /* Get the number of bytes that can be written after copying + the internal buffer */ + BytesToWrite = ((RemainingBytes < + ((PH_FRINFC_MIFARESTD_WR_A_BLK - Length) - + NdefMap->StdMifareContainer.internalLength))? + RemainingBytes: + ((PH_FRINFC_MIFARESTD_WR_A_BLK - Length) - + NdefMap->StdMifareContainer.internalLength)); + + if(NdefMap->StdMifareContainer.internalLength > + PH_FRINFC_MIFARESTD_VAL0) + { + /* copy the internal buffer to the send buffer */ + memcpy(&(NdefMap->SendRecvBuf[ + Length]), + NdefMap->StdMifareContainer.internalBuf, + NdefMap->StdMifareContainer.internalLength); + } + + /* Copy Bytes to write in the send buffer */ + memcpy(&(NdefMap->SendRecvBuf[ + (Length + + NdefMap->StdMifareContainer.internalLength)]), + &(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), + BytesToWrite); + + /* update number of bytes written from the user buffer */ + NdefMap->NumOfBytesWritten = BytesToWrite; + + /* check the exact number of bytes written to a block including the + internal length */ + *NdefMap->DataCount = + ((BytesToWrite + NdefMap->StdMifareContainer.internalLength + + Length) - PH_FRINFC_MIFARESTD_VAL1); + + /* if total bytes to write in the card is less than 4 bytes then + pad zeroes till 4 bytes */ + if((BytesToWrite + NdefMap->StdMifareContainer.internalLength + + Length) < PH_FRINFC_MIFARESTD_WR_A_BLK) + { + for(index = (uint8_t)(BytesToWrite + + NdefMap->StdMifareContainer.internalLength + + Length); + index < PH_FRINFC_MIFARESTD_WR_A_BLK; + index++) + { + NdefMap->SendRecvBuf[index] = (uint8_t)((index == + (BytesToWrite + Length + + NdefMap->StdMifareContainer.internalLength))? + PH_FRINFC_MIFARESTD_TERMTLV_T: + PH_FRINFC_MIFARESTD_NULLTLV_T); + + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + } + } + + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1; + + /* A temporary buffer to hold four bytes of data that is + written to the card */ + memcpy(NdefMap->StdMifareContainer.Buffer, + &(NdefMap->SendRecvBuf[ + PH_FRINFC_MIFARESTD_VAL1]), + PH_FRINFC_MIFARESTD_BLOCK_BYTES); + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_TLV; + Result = phFriNfc_MifStd_H_WrTLV(NdefMap); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_WrTLV + * + * Description This function writes 16 bytes in a block. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + /* Write from here */ + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; + + NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; + + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + /* Call the Overlapped HAL Transceive function */ + Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProWrTLV + * + * Description This function processes the write TLV bytes in a block. + * + * Returns This function return NFCSTATUS_SUCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Check that if complete TLV has been written in the + card if yes enter the below check or go to else*/ + if(((((PH_FRINFC_MIFARESTD_BLOCK_BYTES - + NdefMap->TLVStruct.NdefTLVByte) == + PH_FRINFC_MIFARESTD_VAL1) && + (NdefMap->TLVStruct.NULLTLVCount >= + PH_FRINFC_MIFARESTD_VAL2)) || + (((PH_FRINFC_MIFARESTD_BLOCK_BYTES - + NdefMap->TLVStruct.NdefTLVByte) <= + PH_FRINFC_MIFARESTD_VAL3) && + (NdefMap->TLVStruct.NULLTLVCount == + PH_FRINFC_MIFARESTD_VAL0))) && + (NdefMap->StdMifareContainer.currentBlock == + NdefMap->TLVStruct.NdefTLVBlock)) + { + /* increment the block and chekc the block is in the same sector + using the block check function */ + NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.NdefBlocks++; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + if(Result == NFCSTATUS_SUCCESS) + { + Result = ((NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG0)? + phFriNfc_MifStd_H_AuthSector(NdefMap): + phFriNfc_MifStd_H_RdBeforeWr(NdefMap)); + } + } + else + { + NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG0; + if(NdefMap->ApduBuffIndex < + (uint16_t)NdefMap->ApduBufferSize) + { + if(*NdefMap->DataCount < PH_FRINFC_MIFARESTD_BLOCK_BYTES) + { + /* Write complete, so next byte shall be */ + NdefMap->StdMifareContainer.internalLength = + *NdefMap->DataCount; + + /* Copy bytes less than 16 to internal buffer + for the next write this can be used */ + memcpy( NdefMap->StdMifareContainer.internalBuf, + NdefMap->StdMifareContainer.Buffer, + NdefMap->StdMifareContainer.internalLength); + } + + /* Increment the Send Buffer index */ + NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; + + NdefMap->StdMifareContainer.remainingSize -= + NdefMap->NumOfBytesWritten; + + /* Check for the End of Card */ + if((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize)) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + (uint8_t)((NdefMap->StdMifareContainer.remainingSize == 0)? + PH_FRINFC_MIFARESTD_FLAG1:PH_FRINFC_MIFARESTD_FLAG0); + + if(NdefMap->StdMifareContainer.internalLength == + PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.currentBlock++; + /* Mifare 4k Card, After 128th Block + each sector = 16 blocks in Mifare 4k */ + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + NdefMap->StdMifareContainer.NdefBlocks++; + } + + NdefMap->TLVStruct.SetTermTLVFlag = + (uint8_t)(((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + } + else + { + NdefMap->StdMifareContainer.currentBlock++; + /* Mifare 4k Card, After 128th Block + each sector = 16 blocks in Mifare 4k */ + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + if(Result == NFCSTATUS_SUCCESS) + { + NdefMap->StdMifareContainer.NdefBlocks++; + Result = ((NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG1)? + phFriNfc_MifStd_H_WrABlock(NdefMap): + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + } + } + } + + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag != + PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->StdMifareContainer.remainingSize > + PH_FRINFC_MIFARESTD_VAL0)) + { + Result = phFriNfc_MifStd_H_WrTermTLV(NdefMap); + } + else + { + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_MIFARESTD_FLAG1)) + { + /* Write the length to the L field in the TLV */ + NdefMap->StdMifareContainer.TempBlockNo = + NdefMap->StdMifareContainer.currentBlock; + phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); + NdefMap->StdMifareContainer.currentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); + } + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_UpdRemTLV + * + * Description This function updates the remaining TLV. + * + * Returns uint8_t TempLength : length value + * + ******************************************************************************/ +static uint8_t phFriNfc_MifStd_H_UpdRemTLV(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL1; + + if(NdefMap->TLVStruct.NULLTLVCount >= + PH_FRINFC_MIFARESTD_VAL2) + { + NdefMap->TLVStruct.prevLenByteValue = NdefMap->SendRecvBuf[TempLength]; + NdefMap->SendRecvBuf[TempLength] = + PH_FRINFC_MIFARESTD_NDEFTLV_L0; + } + else + { + switch((PH_FRINFC_MIFARESTD_BLOCK_BYTES - + NdefMap->TLVStruct.NdefTLVByte)) + { + case PH_FRINFC_MIFARESTD_VAL1: + NdefMap->TLVStruct.prevLenByteValue = + (((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_MIFARESTD_NDEFTLV_L))? + (((uint16_t)NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] + << PH_FRINFC_MIFARESTD_LEFTSHIFT8) + + NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL2)]): + NdefMap->SendRecvBuf[TempLength]); + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; + break; + + case PH_FRINFC_MIFARESTD_VAL2: + NdefMap->TLVStruct.prevLenByteValue = + (((NdefMap->SendRecvBuf[TempLength] == + PH_FRINFC_MIFARESTD_NDEFTLV_L))? + (((uint16_t)NdefMap->SendRecvBuf[TempLength] << + PH_FRINFC_MIFARESTD_LEFTSHIFT8) + + NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]): + NdefMap->SendRecvBuf[TempLength]); + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; + break; + + case PH_FRINFC_MIFARESTD_VAL3: + default: + NdefMap->TLVStruct.prevLenByteValue = + ((NdefMap->TLVStruct.prevLenByteValue << + PH_FRINFC_MIFARESTD_LEFTSHIFT8) + + NdefMap->SendRecvBuf[TempLength]); + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0; + break; + } + } + + return TempLength; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_fillTLV1 + * + * Description This function updates the length field if more than one + * NULL TLVs exists before of the NDEF TLV. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_fillTLV1(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t TempLength = (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_MIFARESTD_VAL1); + + NdefMap->TLVStruct.prevLenByteValue = + ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR)? + (NdefMap->TLVStruct.prevLenByteValue + + NdefMap->ApduBuffIndex): + NdefMap->ApduBuffIndex); + + NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG1; + switch(NdefMap->TLVStruct.NdefTLVByte) + { + case PH_FRINFC_MIFARESTD_VAL0: + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + else + { + NdefMap->SendRecvBuf[TempLength] = + PH_FRINFC_MIFARESTD_NDEFTLV_T; + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + + NdefMap->StdMifareContainer.RdAfterWrFlag = + PH_FRINFC_MIFARESTD_FLAG0; + } + break; + + case PH_FRINFC_MIFARESTD_VAL1: + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NdefMap->SendRecvBuf[TempLength - PH_FRINFC_MIFARESTD_VAL1] = + PH_FRINFC_MIFARESTD_NDEFTLV_L; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + else + { + NdefMap->SendRecvBuf[TempLength] = + PH_FRINFC_MIFARESTD_NDEFTLV_T; + NdefMap->SendRecvBuf[(TempLength + + PH_FRINFC_MIFARESTD_VAL1)] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + NdefMap->StdMifareContainer.RdAfterWrFlag = + PH_FRINFC_MIFARESTD_FLAG0; + } + break; + + case PH_FRINFC_MIFARESTD_VAL15: + /* if "Type" of TLV present at byte 15 */ + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + /* Update the null TLV, ndef TLV block and ndef TLV byte */ + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = + (TempLength - PH_FRINFC_MIFARESTD_VAL3); + + NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL2)] = + PH_FRINFC_MIFARESTD_NDEFTLV_T; + NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)] = + PH_FRINFC_MIFARESTD_NDEFTLV_L; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + } + else + { + NdefMap->SendRecvBuf[TempLength] = + PH_FRINFC_MIFARESTD_NDEFTLV_T; + } + break; + + default: + /* Already the TLV is present so just append the length field */ + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + /* Update the null TLV, ndef TLV block and ndef TLV byte */ + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = + (TempLength - PH_FRINFC_MIFARESTD_VAL3); + + NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL2)] = + (uint8_t)PH_FRINFC_MIFARESTD_NDEFTLV_T; + NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)] = + (uint8_t)PH_FRINFC_MIFARESTD_NDEFTLV_L; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + else + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + NdefMap->StdMifareContainer.RdAfterWrFlag = + PH_FRINFC_MIFARESTD_FLAG0; + break; + } + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_fillTLV2 + * + * Description This function is updates the length field if more than one + * NULL TLVs does not exists before the TLV. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_fillTLV2(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t TempLength = (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_MIFARESTD_VAL1); + + NdefMap->TLVStruct.prevLenByteValue = ((NdefMap->Offset == + PH_FRINFC_NDEFMAP_SEEK_CUR)? + (NdefMap->TLVStruct.prevLenByteValue + + NdefMap->ApduBuffIndex): + NdefMap->ApduBuffIndex); + NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG1; + switch(NdefMap->TLVStruct.NdefTLVByte) + { + case PH_FRINFC_MIFARESTD_VAL13: + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + } + else + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + + /* Update the null TLV, ndef TLV block and ndef TLV byte */ + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = + (TempLength - PH_FRINFC_MIFARESTD_VAL1); + + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + } + break; + + case PH_FRINFC_MIFARESTD_VAL14: + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L; + } + else + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + } + break; + + case PH_FRINFC_MIFARESTD_VAL15: + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + } + else + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + } + break; + + default: + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + TempLength++; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + else + { + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + + /* Update the null TLV, ndef TLV block and ndef TLV byte */ + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = + (TempLength - PH_FRINFC_MIFARESTD_VAL1); + + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; + break; + } + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_CallWrNdefLen + * + * Description This function is used to increment/decrement the ndef tlv block + * and read the block. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_CallWrNdefLen(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + if(NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) + { + if((NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL1) ) + { + /* In this case, current block is decremented because the + NULL TLVs are in the previous block */ + NdefMap->StdMifareContainer.currentBlock--; + Result = phFriNfc_MifStd_H_BlkChk_1(NdefMap); + } + else + { + /* case NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL15: + Current block is incremented to update the remaining TLV + structure */ + NdefMap->StdMifareContainer.currentBlock++; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + } + } + else + { + if((NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL13) || + (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL14) || + (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL15)) + { + /* Current block is incremented to update the remaining TLV + structure */ + NdefMap->StdMifareContainer.currentBlock++; + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + } + } + + Result = ((Result == NFCSTATUS_SUCCESS)? + phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap): + Result); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_BlkChk_1 + * + * Description This function check the current block is valid or not + * if not valid decrement the current block till the valid block. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t SectorID = PH_FRINFC_MIFARESTD_VAL0; + + /* Get a Sector ID for the Current Block */ + SectorID = phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock); + + /* Check the sector id is valid or not and if valid then check the + current block is greater than 128 */ + if((NdefMap->StdMifareContainer.aid[SectorID] == + PH_FRINFC_MIFARESTD_NDEF_COMP) && + (((SectorID <= PH_FRINFC_MIFARESTD_VAL15) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) || + ((SectorID <= PH_FRINFC_MIFARESTD_SECTOR_NO31) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) || + ((SectorID <= PH_FRINFC_MIFARESTD_SECTOR_NO39) && + (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)))) + { + if(NdefMap->StdMifareContainer.currentBlock > 128) + { + NdefMap->TLVStruct.NdefTLVAuthFlag = + ((((NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL1) % + PH_FRINFC_MIFARESTD_MAD_BLK16) == + PH_FRINFC_MIFARESTD_VAL0)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->StdMifareContainer.currentBlock -= + ((((NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL1) % + PH_FRINFC_MIFARESTD_MAD_BLK16) == + PH_FRINFC_MIFARESTD_VAL0)? + PH_FRINFC_MIFARESTD_VAL1: + PH_FRINFC_MIFARESTD_VAL0); + + } + else + { + NdefMap->TLVStruct.NdefTLVAuthFlag = + ((((NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL1) % + PH_FRINFC_MIFARESTD_BLK4) == + PH_FRINFC_MIFARESTD_VAL0)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->StdMifareContainer.currentBlock -= + ((((NdefMap->StdMifareContainer.currentBlock + + PH_FRINFC_MIFARESTD_VAL1) % + PH_FRINFC_MIFARESTD_BLK4) == + PH_FRINFC_MIFARESTD_VAL1)? + PH_FRINFC_MIFARESTD_VAL1: + PH_FRINFC_MIFARESTD_VAL0); + + } + } + else + { + /*Error: No Ndef Compliant Sectors present.*/ + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_fillTLV1_1 + * + * Description This function updates the length of the TLV if NULL TLVs + * greater than or equal to 2. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_fillTLV1_1(phFriNfc_NdefMap_t *NdefMap) +{ + switch(NdefMap->TLVStruct.NdefTLVByte) + { + case PH_FRINFC_MIFARESTD_VAL0: + /* In the first write ndef length procedure, the + length is updated, in this case T and L = 0xFF of TLV are + updated */ + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL14; + + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL15] = + PH_FRINFC_MIFARESTD_NDEFTLV_T; + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL16] = + PH_FRINFC_MIFARESTD_NDEFTLV_L; + break; + + case PH_FRINFC_MIFARESTD_VAL1: + /* In the first write ndef length procedure, the + length is updated, in this case T of TLV is + updated */ + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = + PH_FRINFC_MIFARESTD_VAL15; + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL16] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + break; + + case PH_FRINFC_MIFARESTD_VAL15: + default: + /* In the first ndef write length, part of the L field or only T + (if update length is less than 255) is updated */ + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + break; + } + NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_fillTLV2_1 + * + * Description This function updates the length of the TLV if NULL TLVs + * less than 2. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd_H_fillTLV2_1(phFriNfc_NdefMap_t *NdefMap) +{ + uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL1; + switch(NdefMap->TLVStruct.NdefTLVByte) + { + case PH_FRINFC_MIFARESTD_VAL13: + /* In last write ndef length, part of length (L) field of TLV + is updated now */ + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + break; + + case PH_FRINFC_MIFARESTD_VAL14: + /* In last write ndef length, part of length (L) field of TLV + is updated now */ + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + TempLength++; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + else + { + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = + (TempLength - PH_FRINFC_MIFARESTD_VAL1); + NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + break; + + case PH_FRINFC_MIFARESTD_VAL15: + default: + if(NdefMap->TLVStruct.prevLenByteValue >= + PH_FRINFC_MIFARESTD_NDEFTLV_L) + { + /* In last write ndef length, only T of TLV is updated and + length (L) field of TLV is updated now */ + NdefMap->SendRecvBuf[TempLength] = + PH_FRINFC_MIFARESTD_NDEFTLV_L; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >> + PH_FRINFC_MIFARESTD_RIGHTSHIFT8); + TempLength++; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + else + { + NdefMap->SendRecvBuf[TempLength] = + PH_FRINFC_MIFARESTD_NULLTLV_T; + TempLength++; + NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2; + NdefMap->TLVStruct.NdefTLVBlock = + NdefMap->StdMifareContainer.currentBlock; + NdefMap->TLVStruct.NdefTLVByte = + (TempLength - PH_FRINFC_MIFARESTD_VAL1); + NdefMap->SendRecvBuf[TempLength] = + PH_FRINFC_MIFARESTD_NDEFTLV_T; + TempLength++; + NdefMap->SendRecvBuf[TempLength] = + (uint8_t)NdefMap->TLVStruct.prevLenByteValue; + } + break; + } + NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; + + return; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_RdTLV + * + * Description This function reads the TLV block. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_RdTLV(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_TLV; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; + + Result = phFriNfc_MifStd_H_Rd16Bytes(NdefMap, + NdefMap->StdMifareContainer.currentBlock); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProRdTLV + * + * Description This function processes the read TLV block. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProRdTLV(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0, + NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1; + + /*TempLength = (uint8_t)(((NdefMap->TLVStruct.NULLTLVCount >= + PH_FRINFC_MIFARESTD_VAL2) && + (NdefMap->TLVStruct.BytesRemainLinTLV > 0xFE))? + ((NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_MIFARESTD_VAL2)% + PH_FRINFC_MIFARESTD_VAL16): + ((NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_MIFARESTD_VAL4)% + PH_FRINFC_MIFARESTD_VAL16));*/ + + TempLength = (uint8_t)((NdefMap->TLVStruct.BytesRemainLinTLV <= 0xFE)? + ((NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_MIFARESTD_VAL2)% + PH_FRINFC_MIFARESTD_VAL16): + ((NdefMap->TLVStruct.NdefTLVByte + + PH_FRINFC_MIFARESTD_VAL4)% + PH_FRINFC_MIFARESTD_VAL16)); + + if((*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) && + (NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize)) + { + if(NdefMap->TLVStruct.BytesRemainLinTLV != 0) + { + NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0; + /* To read the remaining length (L) in TLV */ + Result = phFriNfc_MifStd_H_RemainTLV(NdefMap, &NDEFFlag, &TempLength); + } + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_WrTermTLV + * + * Description This function is used to write the terminator TLV. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_WrTermTLV(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + uint8_t index = PH_FRINFC_MIFARESTD_VAL0; + + /* Change the state to check ndef compliancy */ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_TERM_TLV; + + NdefMap->SendRecvBuf[index] = + NdefMap->StdMifareContainer.currentBlock; + index++; + NdefMap->SendRecvBuf[index] = PH_FRINFC_MIFARESTD_TERMTLV_T; + index++; + + while(index < PH_FRINFC_MIFARESTD_WR_A_BLK) + { + NdefMap->SendRecvBuf[index] = PH_FRINFC_MIFARESTD_NULLTLV_T; + index++; + } + + NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG0; + + Result = phFriNfc_MifStd_H_WrTLV(NdefMap); + + return Result; +} + + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProWrABlock + * + * Description This function processes the write a block. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProWrABlock(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL0; + if(NdefMap->ApduBuffIndex < + (uint16_t)NdefMap->ApduBufferSize) + { + /* Remaining bytes to write < 16 */ + if(NdefMap->StdMifareContainer.RemainingBufFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + /* Write complete, so next byte shall be */ + NdefMap->StdMifareContainer.internalLength = + *NdefMap->DataCount; + + /* Copy bytes less than 16 to internal buffer + for the next write this can be used */ + memcpy( NdefMap->StdMifareContainer.internalBuf, + NdefMap->StdMifareContainer.Buffer, + NdefMap->StdMifareContainer.internalLength); + + /* Increment the Send Buffer index */ + NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; + + NdefMap->StdMifareContainer.remainingSize -= + NdefMap->NumOfBytesWritten; + + NdefMap->StdMifareContainer.RemainingBufFlag = PH_FRINFC_MIFARESTD_VAL0; + /* Check for the End of Card */ + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + (uint8_t)((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0)? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->TLVStruct.SetTermTLVFlag = + (uint8_t)(((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + } /* internal Buffer > Send Buffer */ + else if(NdefMap->StdMifareContainer.internalBufFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + memcpy(NdefMap->StdMifareContainer.internalBuf, + NdefMap->StdMifareContainer.Buffer, + *NdefMap->DataCount); + + NdefMap->StdMifareContainer.internalLength = + *NdefMap->DataCount; + + /* Increment the Send Buffer index */ + NdefMap->ApduBuffIndex += + NdefMap->NumOfBytesWritten; + + NdefMap->StdMifareContainer.remainingSize -= + NdefMap->NumOfBytesWritten; + + NdefMap->StdMifareContainer.internalBufFlag = + PH_FRINFC_MIFARESTD_FLAG0; + /* Check for the End of Card */ + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + (uint8_t)(((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) && + (NdefMap->StdMifareContainer.internalLength == + PH_FRINFC_MIFARESTD_VAL0))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + + NdefMap->TLVStruct.SetTermTLVFlag = + (uint8_t)(((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + } + else + { + NdefMap->StdMifareContainer.internalLength = 0; + /* Increment the Send Buffer index */ + NdefMap->ApduBuffIndex += + NdefMap->NumOfBytesWritten; + NdefMap->StdMifareContainer.remainingSize -= + NdefMap->NumOfBytesWritten; + + /* Check for the End of Card */ + if((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize)) + { + NdefMap->StdMifareContainer.ReadWriteCompleteFlag = + (uint8_t)((NdefMap->StdMifareContainer.remainingSize == 0)? + PH_FRINFC_MIFARESTD_FLAG1:PH_FRINFC_MIFARESTD_FLAG0); + + if(NdefMap->StdMifareContainer.internalLength == + PH_FRINFC_MIFARESTD_VAL0) + { + NdefMap->StdMifareContainer.currentBlock++; + /* Mifare 4k Card, After 128th Block + each sector = 16 blocks in Mifare 4k */ + Result = ((NdefMap->StdMifareContainer.remainingSize == 0)? + Result: + phFriNfc_MifStd_H_BlkChk(NdefMap)); + NdefMap->StdMifareContainer.NdefBlocks++; + } + NdefMap->TLVStruct.SetTermTLVFlag = + (uint8_t)(((NdefMap->StdMifareContainer.remainingSize == + PH_FRINFC_MIFARESTD_VAL0) || + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_MIFARESTD_FLAG1))? + PH_FRINFC_MIFARESTD_FLAG1: + PH_FRINFC_MIFARESTD_FLAG0); + } + else + { + NdefMap->StdMifareContainer.currentBlock++; + NdefMap->StdMifareContainer.WrLength = + (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); + /* Mifare 4k Card, After 128th Block + each sector = 16 blocks in Mifare 4k */ + Result = phFriNfc_MifStd_H_BlkChk(NdefMap); + if(Result == NFCSTATUS_SUCCESS) + { + NdefMap->StdMifareContainer.NdefBlocks++; + Result = ((NdefMap->StdMifareContainer.AuthDone == + PH_FRINFC_MIFARESTD_FLAG1)? + phFriNfc_MifStd_H_WrABlock(NdefMap): + phFriNfc_MifStd_H_AuthSector(NdefMap)); + } + } + } + } + else + { + Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_DEVICE_REQUEST); + } + + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag != + PH_FRINFC_MIFARESTD_FLAG1) && + (NdefMap->StdMifareContainer.remainingSize > + PH_FRINFC_MIFARESTD_VAL0)) + { + Result = phFriNfc_MifStd_H_WrTermTLV(NdefMap); + } + else + { + if((Result == NFCSTATUS_SUCCESS) && + (NdefMap->TLVStruct.SetTermTLVFlag == + PH_FRINFC_MIFARESTD_FLAG1)) + { + /* Write the length to the L field in the TLV */ + NdefMap->StdMifareContainer.TempBlockNo = + NdefMap->StdMifareContainer.currentBlock; + phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap); + NdefMap->StdMifareContainer.currentBlock = + NdefMap->TLVStruct.NdefTLVBlock; + Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap); + } + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_CallDisCon + * + * Description This function trigger disconnect after the authentication + * has failed. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_CallDisCon(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Set Ndef State */ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_DISCONNECT; + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + Result = phNxNciExtns_MifareStd_Reconnect(); + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_CallConnect + * + * Description This function sets card state to connect after the + * authentication has failed. + * + * Returns NFCSTATUS_SUCCESS + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + /* Set Ndef State */ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_CONNECT; + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd1k_H_BlkChk + * + * Description This function used to update the current block. + * + * Returns void + * + ******************************************************************************/ +static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t *NdefMap, + uint8_t SectorID, + uint8_t *callbreak) +{ + /* every last block of a sector needs to be skipped */ + if(((NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_INC_1) % + PH_FRINFC_MIFARESTD_BLK4) == 0) + { + NdefMap->StdMifareContainer.currentBlock++; + } + else + { + if(NdefMap->StdMifareContainer.aid[SectorID] == + PH_FRINFC_MIFARESTD_NDEF_COMP) + { + /* Check whether the block is first block of a (next)new sector and + also check if it is first block then internal length is zero + or not. Because once Authentication is done for the sector again + we should not authenticate it again */ + if((NdefMap->StdMifareContainer.currentBlock == + (SectorID * PH_FRINFC_MIFARESTD_BLK4)) && + (NdefMap->StdMifareContainer.internalLength == 0)) + { + NdefMap->StdMifareContainer.AuthDone = 0; + } + *callbreak = 1; + } + else + { + NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4; + } + } + + return; +} + +/****************************************************************************** + * Function phFrinfc_MifareClassic_GetContainerSize + * + * Description This function calculate the card size. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +NFCSTATUS phFrinfc_MifareClassic_GetContainerSize(const phFriNfc_NdefMap_t *NdefMap, + uint32_t *maxSize, uint32_t *actualSize) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + uint16_t valid_no_of_bytes = 0; + uint8_t sect_aid_index = 0; + /* Mifare std card */ + + /* Max size is the number of NDEF compliant blocks in the card + multiplied by 16 bytes */ + + /* Skip all the non ndef sectors */ + while ((sect_aid_index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK) && + (PH_FRINFC_MIFARESTD_NON_NDEF_COMP == NdefMap->StdMifareContainer.aid[sect_aid_index])) + { + sect_aid_index++; + } + + /* Parse only the contiguous NDEF sectors for the max size calculation */ + while ((sect_aid_index <PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK)&& + (PH_FRINFC_MIFARESTD_NDEF_COMP ==NdefMap->StdMifareContainer.aid[sect_aid_index])) + { + if (((PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD == NdefMap->CardType)|| + (PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD == NdefMap->CardType)) && (sect_aid_index >= 32)) + { + /* Mifare classic card of 4k size, sector >= 32 has + 16 blocks per sector and in that 15 blocks are valid data blocks + 16 is the block number in a sector + 15 is the number of valid data blocks in a sector + */ + valid_no_of_bytes += (uint16_t)(16 * 15); + } + else + { + valid_no_of_bytes += (uint16_t)(16 * 3); + } + + sect_aid_index++; + if (16 == sect_aid_index) + { + /* Because sector index is 16, that is "MAD 2" block + For calculating size MAD block shall be ignored + */ + sect_aid_index++; + } + } + /* The below check is for the 3 byte length format of the NDEF TLV + If the length field > 255, Max size will less by 4 + else Max size will less by 2 (Type and Length of the NDEF TLV + has to be skipped to provide the maximum size in the card */ + *maxSize = (valid_no_of_bytes > 0xFF) ? (valid_no_of_bytes - 4) : (valid_no_of_bytes - 2); + + *actualSize = NdefMap->TLVStruct.BytesRemainLinTLV; + + return result; +} + +/****************************************************************************** + * Function phFriNfc_MifareStdMap_ConvertToReadOnly + * + * Description This function converts the Mifare card to read-only. + * It check preconditions before converting to read only. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +NFCSTATUS +phFriNfc_MifareStdMap_ConvertToReadOnly ( + phFriNfc_NdefMap_t *NdefMap, + const uint8_t *ScrtKeyB) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + uint8_t totalNoSectors = 0 , sectorTrailerBlockNo = 0; + + if ( NdefMap == NULL) + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else if ( PH_NDEFMAP_CARD_STATE_INVALID == NdefMap->CardState ) + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_STATE); + } + else + { + /* card state is PH_NDEFMAP_CARD_STATE_READ_WRITE now */ + /* get AID array and parse */ + if( PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD == NdefMap->CardType ) + { + totalNoSectors = PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR; + } + else if ( PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD == NdefMap->CardType ) + { + totalNoSectors = PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR; + } + else if ( PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD == NdefMap->CardType ) + { + totalNoSectors = PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; + } + + /* Store Key B in the context */ + if(ScrtKeyB ==NULL) + { + memset (NdefMap->StdMifareContainer.UserScrtKeyB, PH_FRINFC_MIFARESTD_DEFAULT_KEY, + PH_FRINFC_MIFARESTD_KEY_LEN); + } + else + { + memcpy (NdefMap->StdMifareContainer.UserScrtKeyB, ScrtKeyB, PH_FRINFC_MIFARESTD_KEY_LEN); + } + + NdefMap->StdMifareContainer.TotalNoSectors = totalNoSectors; + if(totalNoSectors == 0) + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else + { + NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0; + NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0; + NdefMap->StdMifareContainer.WriteAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG0; + + /* Sector 0 is MAD sector .Start from Sector 1 */ + for(NdefMap->StdMifareContainer.ReadOnlySectorIndex = PH_FRINFC_MIFARESTD_FLAG1; + NdefMap->StdMifareContainer.ReadOnlySectorIndex < totalNoSectors; + NdefMap->StdMifareContainer.ReadOnlySectorIndex++) + { + /* skip MAD sectors */ + if( PH_FRINFC_MIFARESTD_SECTOR_NO16 == NdefMap->StdMifareContainer.ReadOnlySectorIndex ) + { + continue; + } + + /* if not NDEF compliant skip */ + if( PH_FRINFC_MIFARESTD_NON_NDEF_COMP == + NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) + { + continue; + } + + if (PH_FRINFC_MIFARESTD_NDEF_COMP == + NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) + { + /*get the sector trailer block number */ + sectorTrailerBlockNo = + phFriNfc_MifStd_H_GetSectorTrailerBlkNo(NdefMap->StdMifareContainer.ReadOnlySectorIndex); + NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo; + NdefMap->StdMifareContainer.SectorTrailerBlockNo = sectorTrailerBlockNo; + + /* Proceed to authenticate the sector with Key B + and modify the sector trailor bits to make it read only*/ + result = phFriNfc_MifStd_H_AuthSector(NdefMap); + + if (result == NFCSTATUS_PENDING ) + { + break; + } + } + } /* end for */ + + /* There are no NDEF sectors in this card , return */ + if(NdefMap->StdMifareContainer.ReadOnlySectorIndex == totalNoSectors && + NFCSTATUS_PENDING!= result ) + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT); + } + } /* end else */ + } + + return result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_GetSectorTrailerBlkNo + * + * Description This function returns the block number of the sector + * trailor for the given sector trailer Id. + * + * Returns uint8_t sectorTrailerblockNumber : sector trailor + * + ******************************************************************************/ +static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo (uint8_t SectorID) +{ + uint8_t sectorTrailerblockNumber = 0; + + /* every last block of a sector needs to be skipped */ + if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) + { + sectorTrailerblockNumber = (SectorID * PH_FRINFC_MIFARESTD_BLK4 ) + 3; + } + else + { + sectorTrailerblockNumber = ((PH_FRINFC_MIFARESTD_SECTOR_NO32 * PH_FRINFC_MIFARESTD_BLK4) + + ((SectorID - PH_FRINFC_MIFARESTD_SECTOR_NO32) * PH_FRINFC_MIFARESTD_SECTOR_BLOCKS)) + 15; + } + + return sectorTrailerblockNumber; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProSectorTrailorAcsBits + * + * Description This function is called during ConvertToReadonly process to + * Authenticate NDEF compliant Sector. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS Result = NFCSTATUS_SUCCESS; + + if(*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) + { + if(NdefMap->StdMifareContainer.ReadAcsBitFlag == + PH_FRINFC_MIFARESTD_FLAG1) + { + /* check for the correct access bits */ + Result = phFriNfc_MifStd_H_ChkAcsBit(NdefMap); + if(Result == NFCSTATUS_SUCCESS) + { + + if(NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY) + { + /* Go to next sector */ + Result = phFriNfc_MifStd_H_ProWrSectorTrailor(NdefMap); + } + else + { + /* tranceive to write the data into SendRecvBuff */ + Result = phFriNfc_MifStd_H_WrSectorTrailorBlock(NdefMap); + } + } + } + } + else + { + Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_PARAMETER); + } + + return Result; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_WrSectorTrailorBlock + * + * Description This function makes current NDEF compliant Sector ReadOnly + * modify the sector trailor bits and write it to the card. + * + * Returns This function return NFCSTATUS_PENDING in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; + + /* next state (update sector index) */ + NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WRITE_SEC; + + /* Buffer Check */ + if(NdefMap->SendRecvBuf != NULL) + { + NdefMap->SendRecvBuf[10] = 0x00; + NdefMap->SendRecvBuf[10] = NdefMap->SendRecvBuf[9] | PH_FRINFC_MIFARESTD_MASK_GPB_WR; /* WR bits 11*/ + + /*The NdefMap->SendRecvBuf already has the sector trailor. + modify the bits to make Read Only */ + NdefMap->SendRecvBuf[1] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ + NdefMap->SendRecvBuf[2] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ + NdefMap->SendRecvBuf[3] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ + NdefMap->SendRecvBuf[4] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ + NdefMap->SendRecvBuf[5] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */ + NdefMap->SendRecvBuf[6] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */ + + NdefMap->SendRecvBuf[7] = PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6;/* 0x0F */ + NdefMap->SendRecvBuf[8] = PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7;/* 0x07 */ + NdefMap->SendRecvBuf[9] = PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8;/* 0x8F */ + + NdefMap->SendRecvBuf[11] = NdefMap->StdMifareContainer.UserScrtKeyB[0]; + NdefMap->SendRecvBuf[12] = NdefMap->StdMifareContainer.UserScrtKeyB[1]; + NdefMap->SendRecvBuf[13] = NdefMap->StdMifareContainer.UserScrtKeyB[2]; + NdefMap->SendRecvBuf[14] = NdefMap->StdMifareContainer.UserScrtKeyB[3]; + NdefMap->SendRecvBuf[15] = NdefMap->StdMifareContainer.UserScrtKeyB[4]; + NdefMap->SendRecvBuf[16] = NdefMap->StdMifareContainer.UserScrtKeyB[5]; + + /* Write to Ndef Sector Block */ + NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = NdefMap->StdMifareContainer.currentBlock; + + /* Copy Ndef Sector Block into buffer */ + memcpy(NdefMap->StdMifareContainer.Buffer, + &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]), + PH_FRINFC_MIFARESTD_BLOCK_BYTES); + + /* Write from here */ + NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE; + NdefMap->Cmd.MfCmd = phHal_eMifareWrite16; + *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; + + /* Call the Overlapped HAL Transceive function */ + status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + else + { + /* Error: The control should not ideally come here. + Return Error.*/ + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED); + } + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProWrSectorTrailor + * + * Description This function makes next NDEF compliant Sector ReadOnly. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor(phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + uint8_t sectorTrailerBlockNo = 0; + + /*Increment Sector Index */ + NdefMap->StdMifareContainer.ReadOnlySectorIndex++; + + /* skip if MAD2 */ + if(PH_FRINFC_MIFARESTD_SECTOR_NO16 == NdefMap->StdMifareContainer.ReadOnlySectorIndex ) + { + NdefMap->StdMifareContainer.ReadOnlySectorIndex++; + } + + /* if current sector index exceeds total sector index then + all ndef sectors are made readonly then return success + If a NON def sector is encountered return success*/ + if (NdefMap->StdMifareContainer.ReadOnlySectorIndex >= NdefMap->StdMifareContainer.TotalNoSectors || + PH_FRINFC_MIFARESTD_NON_NDEF_COMP == + NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) + { + status = NFCSTATUS_SUCCESS; + } + else if(PH_FRINFC_MIFARESTD_NDEF_COMP == NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) + { + /* Convert next NDEF sector to read only */ + sectorTrailerBlockNo = phFriNfc_MifStd_H_GetSectorTrailerBlkNo(NdefMap->StdMifareContainer.ReadOnlySectorIndex); + NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo; + NdefMap->StdMifareContainer.SectorTrailerBlockNo = sectorTrailerBlockNo; + + status = phFriNfc_MifStd_H_AuthSector(NdefMap); + } + + return status; +} + +/****************************************************************************** + * Function phFriNfc_MifStd_H_ProWrSectorTrailor + * + * Description This function checks mapping spec version. + * + * Returns This function return NFCSTATUS_SUCCESS in case of success + * In case of failure returns other failure value. + * + ******************************************************************************/ +static NFCSTATUS phFriNfc_MapTool_ChkSpcVer( const phFriNfc_NdefMap_t *NdefMap, + uint8_t VersionIndex) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + uint8_t TagVerNo = NdefMap->SendRecvBuf[VersionIndex]; + + if ( TagVerNo == 0 ) + { + /* Return Status Error invalid format */ + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT); + } + else + { + switch (NdefMap->CardType) + { + case PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD: + case PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD: + case PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD: + { + /* calculate the major and minor version number of Mifare std version number */ + status = (( (( PH_NFCFRI_MFSTDMAP_NFCDEV_MAJOR_VER_NUM == + PH_NFCFRI_MFSTDMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&& + ( PH_NFCFRI_MFSTDMAP_NFCDEV_MINOR_VER_NUM == + PH_NFCFRI_MFSTDMAP_GET_MINOR_TAG_VERNO(TagVerNo))) || + (( PH_NFCFRI_MFSTDMAP_NFCDEV_MAJOR_VER_NUM == + PH_NFCFRI_MFSTDMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&& + ( PH_NFCFRI_MFSTDMAP_NFCDEV_MINOR_VER_NUM < + PH_NFCFRI_MFSTDMAP_GET_MINOR_TAG_VERNO(TagVerNo) )))? + NFCSTATUS_SUCCESS: + PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_FORMAT)); + break; + } + + default: + { + /* calculate the major and minor version number of T3VerNo */ + if( (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == + PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&& + ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM == + PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo))) || + (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == + PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&& + ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM < + PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo) ))) + { + status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); + } + else + { + if ((PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM < + PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) || + (PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM > + PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo))) + { + status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT); + } + } + break; + } + } + } + + return (status); +} + diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.h b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.h new file mode 100755 index 00000000..e717dd74 --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_MifareStdMap.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2015 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. + */ + + /* + * NFC Ndef Mapping For Remote Devices. + */ + +#ifndef PHFRINFC_MIFARESTDMAP_H +#define PHFRINFC_MIFARESTDMAP_H + +#include <phFriNfc.h> +#include <phNfcStatus.h> +#include <phNfcTypes.h> +#include <phFriNfc_NdefMap.h> + +/* NFC Device Major and Minor Version numbers */ +/* !!CAUTION!! these needs to be updated periodically.Major and Minor version numbers + should be compatible to the version number of currently implemented mapping document. + Example : NFC Device version Number : 1.0 , specifies + Major VNo is 1, + Minor VNo is 0 */ +#define PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM 0x01 +#define PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM 0x00 +#define PH_NFCFRI_MFSTDMAP_NFCDEV_MAJOR_VER_NUM 0x40 +#define PH_NFCFRI_MFSTDMAP_NFCDEV_MINOR_VER_NUM 0x00 + +/* Macros to find major and minor TAG : Ex:Type1/Type2/Type3/Type4 version numbers */ +#define PH_NFCFRI_MFSTDMAP_GET_MAJOR_TAG_VERNO(a) ((a) & (0x40)) /* must be 0xC0 */ +#define PH_NFCFRI_MFSTDMAP_GET_MINOR_TAG_VERNO(a) ((a) & (0x30)) + +/* Macros to find major and minor TAG : Ex:Type1/Type2/Type3/Type4 version numbers */ +#define PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(a) (((a) & (0xf0))>>(4)) +#define PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(a) ((a) & (0x0f)) + +/* NDEF Mapping - states of the Finite State machine */ +#define PH_FRINFC_NDEFMAP_STATE_INIT 0 /* Init state. The start-up state */ +#define PH_FRINFC_NDEFMAP_STATE_READ 1 /* Read State */ +#define PH_FRINFC_NDEFMAP_STATE_WRITE 2 /* Write is going on*/ +#define PH_FRINFC_NDEFMAP_STATE_AUTH 3 /* Authenticate is going on*/ +#define PH_FRINFC_NDEFMAP_STATE_CHK_NDEF_COMP 4 /* Check Ndef is going on */ +#define PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT 5 /* Read access bit is in progress */ +#define PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN 6 /* Write NDEF TLV LEngth*/ +#define PH_FRINFC_NDEFMAP_STATE_RD_TO_WR_NDEF_LEN 7 /* read to write the Ndef TLV*/ +#define PH_FRINFC_NDEFMAP_STATE_GET_ACT_CARDSIZE 8 /* Get the card size */ +#define PH_FRINFC_NDEFMAP_STATE_RD_BEF_WR 9 /* Read the NDEF TLV block before starting write */ +#define PH_FRINFC_NDEFMAP_STATE_WR_TLV 10 /* Read the NDEF TLV block before starting write */ +#define PH_FRINFC_NDEFMAP_STATE_RD_TLV 11 /* Read the NDEF TLV block */ +#define PH_FRINFC_NDEFMAP_STATE_TERM_TLV 12 /* Write terminator TLV block */ +#define PH_FRINFC_NDEFMAP_STATE_POLL 13 /* Poll in progress */ +#define PH_FRINFC_NDEFMAP_STATE_DISCONNECT 14 /* Disconnect in progress */ +#define PH_FRINFC_NDEFMAP_STATE_CONNECT 15 /* Connect in progress */ + +#define PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT 16 /* Convert to ReadOnly in progress */ +#define PH_FRINFC_NDEFMAP_STATE_WRITE_SEC 17 /* Convert to ReadOnly in progress */ + + +/* Mifare Standard - NDEF Compliant Flags */ +#define PH_FRINFC_MIFARESTD_NDEF_COMP 0 /* Sector is NDEF Compliant */ +#define PH_FRINFC_MIFARESTD_NON_NDEF_COMP 1 /* Sector is not NDEF Compliant */ + +/* Mifare Standard - NDEF Compliant Flag */ +#define PH_FRINFC_MIFARESTD_PROP_1ST_CONFIG 0 /* No proprietary forum sector found */ +#define PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG 1 /* Here the proprietary + forum sector exists after NFC forum + sector */ +#define PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG 2 /* Here the proprietary forum sector exists before + NFC forum sector */ + +/* Mifare Standard - NDEF Compliant Flags */ +#define PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE6 0x78 /* Access Bit for Byte 6 in + MAD sector trailer */ +#define PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE7 0x77 /* Access Bit for Byte 7 in + MAD sector trailer */ +#define PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE6 0x7F /* Access Bit for Byte 6 in + NFC forum sector trailer */ +#define PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE7 0x07 /* Access Bit for Byte 7 in + NFC forum sector trailer */ +#define PH_FRINFC_MIFARESTD_ACS_BYTE8 0x88 /* Access Bit for Byte 8 in + all sector trailer */ +#define PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6 0x0F /* Access Bit for Byte 6 in + NFC forum sector trailer for + Read Only State */ +#define PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7 0x07 /* Access Bit for Byte 7 in + NFC forum sector trailer + Read Only State */ +#define PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8 0x8F /* Access Bit for Byte 8 in + NFC forum sector trailer + Read Only State */ + /* Mifare Standard constants */ +#define MIFARE_MAX_SEND_BUF_TO_READ 1 /* Send Length for Reading a Block */ +#define MIFARE_MAX_SEND_BUF_TO_WRITE 17 /* Send Length for writing a Block */ +#define MIFARE_AUTHENTICATE_CMD_LENGTH 7 /* Send Length for authenticating a Block */ + +/* Mifare standard - Constants */ +#define PH_FRINFC_MIFARESTD_MAD_BLK0 0 /* Block number 0 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK1 1 /* Block number 1 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK2 2 /* Block number 2 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK3 3 /* Block number 3 */ +#define PH_FRINFC_MIFARESTD_BLK4 4 /* Block number 4 */ +#define PH_FRINFC_MIFARESTD_BLK5 5 /* Block number 5 */ +#define PH_FRINFC_MIFARESTD_BLK6 6 /* Block number 6 */ +#define PH_FRINFC_MIFARESTD_BLK7 7 /* Block number 7 */ +#define PH_FRINFC_MIFARESTD_BLK8 8 /* Block number 8 */ +#define PH_FRINFC_MIFARESTD_BLK9 9 /* Block number 9 */ +#define PH_FRINFC_MIFARESTD_BLK10 10 /* Block number 10 */ +#define PH_FRINFC_MIFARESTD_BLK11 11 /* Block number 11 */ +#define PH_FRINFC_MIFARESTD_BLK12 12 /* Block number 12 */ +#define PH_FRINFC_MIFARESTD_BLK13 13 /* Block number 13 */ +#define PH_FRINFC_MIFARESTD_BLK14 14 /* Block number 14 */ +#define PH_FRINFC_MIFARESTD_BLK15 15 /* Block number 15 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK16 16 /* Block number 16 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK63 63 /* Block number 63 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK64 64 /* Block number 64 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK65 65 /* Block number 65 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK66 66 /* Block number 66 */ +#define PH_FRINFC_MIFARESTD_MAD_BLK67 67 /* Block number 67 */ +#define PH_FRINFC_MIFARESTD4K_BLK128 128 /* Block number 128 for Mifare 4k */ +#define PH_FRINFC_MIFARESTD_SECTOR_NO0 0 /* Sector 0 */ +#define PH_FRINFC_MIFARESTD_SECTOR_NO1 1 /* Sector 1 */ +#define PH_FRINFC_MIFARESTD_SECTOR_NO16 16 /* Sector 16 */ +#define PH_FRINFC_MIFARESTD_SECTOR_NO31 31 /* Sector 31 */ +#define PH_FRINFC_MIFARESTD_SECTOR_NO39 39 /* Sector 39 */ +#define PH_FRINFC_MIFARESTD_SECTOR_NO32 32 /* Sector 32 */ +#define PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR 40 /* Sector 40 */ +#define PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR 16 /* Sector 16 */ +#define PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR 32 /* Sector 32 */ +#define PH_FRINFC_MIFARESTD_BYTES_READ 16 /* Bytes read */ +#define PH_FRINFC_MIFARESTD_BLOCK_BYTES 16 /* Bytes per block */ +#define PH_FRINFC_MIFARESTD_SECTOR_BLOCKS 16 /* Blocks per sector */ +#define PH_FRINFC_MIFARESTD_WR_A_BLK 17 /* 17 bytes (including current block) + are given to transfer */ +#define PH_FRINFC_MIFARESTD4K_MAX_BLOCKS 210 /* Maximum number of Mifare 4k Blocks + excluding sector trailer */ +#define PH_FRINFC_MIFARESTD1K_MAX_BLK 63 /* Maximum number of Mifare 1k blocks + including the sector trailer*/ +#define PH_FRINFC_MIFARESTD2K_MAX_BLK 127 /* Maximum number of Mifare 2k blocks + including the sector trailer*/ +#define PH_FRINFC_MIFARESTD4K_MAX_BLK 254 /* Maximum number of Mifare 4k blocks + including the sector trailer*/ +#define PH_FRINFC_MIFARESTD_FLAG1 1 /* Flag to set 1 */ +#define PH_FRINFC_MIFARESTD_FLAG0 0 /* Flag to set 0 */ +#define PH_FRINFC_MIFARESTD_INC_1 1 /* increment by 1 */ +#define PH_FRINFC_MIFARESTD_INC_2 2 /* increment by 2 */ +#define PH_FRINFC_MIFARESTD_INC_3 3 /* increment by 3 */ +#define PH_FRINFC_MIFARESTD_INC_4 4 /* increment by 4 */ +#define PH_FRINFC_MIFARESTD_VAL0 0 /* Value initialised to 0 */ +#define PH_FRINFC_MIFARESTD_VAL1 1 /* Value initialised to 1 */ +#define PH_FRINFC_MIFARESTD_VAL2 2 /* Value initialised to 2 */ +#define PH_FRINFC_MIFARESTD_VAL3 3 /* Value initialised to 3 */ +#define PH_FRINFC_MIFARESTD_VAL4 4 /* Value initialised to 4 */ +#define PH_FRINFC_MIFARESTD_VAL5 5 /* Value initialised to 5 */ +#define PH_FRINFC_MIFARESTD_VAL6 6 /* Value initialised to 6 */ +#define PH_FRINFC_MIFARESTD_VAL7 7 /* Value initialised to 7 */ +#define PH_FRINFC_MIFARESTD_VAL8 8 /* Value initialised to 8 */ +#define PH_FRINFC_MIFARESTD_VAL9 9 /* Value initialised to 9 */ +#define PH_FRINFC_MIFARESTD_VAL10 10 /* Value initialised to 10 */ +#define PH_FRINFC_MIFARESTD_VAL11 11 /* Value initialised to 11 */ +#define PH_FRINFC_MIFARESTD_VAL12 12 /* Value initialised to 12 */ +#define PH_FRINFC_MIFARESTD_VAL13 13 /* Value initialised to 13 */ +#define PH_FRINFC_MIFARESTD_VAL14 14 /* Value initialised to 14 */ +#define PH_FRINFC_MIFARESTD_VAL15 15 /* Value initialised to 15 */ +#define PH_FRINFC_MIFARESTD_VAL16 16 /* Value initialised to 16 */ +#define PH_FRINFC_MIFARESTD_VAL31 31 /* Value initialised to 31 */ +#define PH_FRINFC_MIFARESTD_VAL32 32 /* Value initialised to 32 */ +#define PH_FRINFC_MIFARESTD_NDEFTLV_L 0xFF /* Length of the TLV */ +#define PH_FRINFC_MIFARESTD_NDEFTLV_T 0x03 /* Length of the TLV */ +#define PH_FRINFC_MIFARESTD_NDEFTLV_L0 0x00 /* Length of the TLV */ +#define PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0 0 /* Number of bytes taken by length (L) of the TLV */ +#define PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES1 1 /* Number of bytes taken by length (L) of the TLV */ +#define PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES2 2 /* Number of bytes taken by length (L) of the TLV */ +#define PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES3 3 /* Number of bytes taken by length (L) of the TLV */ +#define PH_FRINFC_MIFARESTD_PROPTLV_T 0xFD /* Type of Proprietary TLV */ +#define PH_FRINFC_MIFARESTD_TERMTLV_T 0xFE /* Type of Terminator TLV */ +#define PH_FRINFC_MIFARESTD_NULLTLV_T 0x00 /* Type of NULL TLV */ +#define PH_FRINFC_MIFARESTD_LEFTSHIFT8 8 /* Left shift by 8 */ +#define PH_FRINFC_MIFARESTD_RIGHTSHIFT8 8 /* Right shift by 8 */ +#define PH_FRINFC_MIFARESTD_MASK_FF 0xFF /* Mask 0xFF */ +#define PH_FRINFC_MIFARESTD_MASK_GPB_WR 0x03 /* Mask 0x03 for GPB byte */ +#define PH_FRINFC_MIFARESTD_MASK_GPB_RD 0x0C /* Mask 0xOC for GPB byte */ +#define PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL 0x00 /* GPB Read Write value */ +#define PH_FRINFC_MIFARESTD_KEY_LEN 0x06 /* MIFARE Std key length */ +#define PH_FRINFC_MIFARESTD_DEFAULT_KEY 0xFF /* MIFARE Std Default Key */ + + +NFCSTATUS phFriNfc_MifareStdMap_H_Reset( phFriNfc_NdefMap_t *NdefMap); +NFCSTATUS phFriNfc_MifareStdMap_RdNdef( phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset); +NFCSTATUS phFriNfc_MifareStdMap_WrNdef( phFriNfc_NdefMap_t *NdefMap, + uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset); +NFCSTATUS phFriNfc_MifareStdMap_ChkNdef(phFriNfc_NdefMap_t *NdefMap); + +void phFriNfc_MifareStdMap_Process( void *Context, + NFCSTATUS Status); +extern +NFCSTATUS phFrinfc_MifareClassic_GetContainerSize(const phFriNfc_NdefMap_t *NdefMap, + uint32_t *maxSize, uint32_t *actualSize); + +NFCSTATUS +phFriNfc_MifareStdMap_ConvertToReadOnly (phFriNfc_NdefMap_t *NdefMap, const uint8_t *ScrtKeyB); + +#endif /* PHFRINFC_MIFARESTDMAP_H */ diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_NdefMap.h b/nci/jni/extns/pn54x/src/mifare/phFriNfc_NdefMap.h new file mode 100755 index 00000000..9f81a9bb --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_NdefMap.h @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * NFC Ndef Mapping For Different Smart Cards. + * + */ + +#ifndef PHFRINFC_NDEFMAP_H +#define PHFRINFC_NDEFMAP_H + + +/*include files*/ +#include <phNfcTypes.h> +#include <phNfcStatus.h> +#include <phFriNfc.h> +#include <phNfcTypes_Mapping.h> + +/* NDEF Mapping Component + * + * This component implements the read/write/check NDEF functions for remote devices. + * NDEF data, as defined by the NFC Forum NDEF specification are written to or read from + * a remote device that can be a smart- or memory card. + * Please notice that the NDEF mapping command sequence must + * be contiguous (after correct initialization) + * + */ + +/* + * NDEF Mapping - specifies the different card types + * These are the only recognized card types in this version. + * + */ + +#define PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD 7 /* Mifare Standard */ +#define PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD 8 /* Mifare Standard */ +#define PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD 11 /*internal Mifare Standard */ +#define PH_FRINFC_NDEFMAP_EMPTY_NDEF_MSG {0xD0, 0x00, 0x00} /* Empty ndef message */ +#define PH_FRINFC_NDEFMAP_MFUL_4BYTES_BUF 4 /* To store 4 bytes after write */ + + +/* Enum represents the different card state*/ +typedef enum +{ + PH_NDEFMAP_CARD_STATE_INITIALIZED, + PH_NDEFMAP_CARD_STATE_READ_ONLY, + PH_NDEFMAP_CARD_STATE_READ_WRITE, + PH_NDEFMAP_CARD_STATE_INVALID +}phNDEF_CARD_STATE; + + +/* + * NDEF Mapping - specifies the Compliant Blocks in the Mifare 1k and 4k card types + * + */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_1KNDEF_COMPBLOCK 45 /* Total Ndef Compliant blocks Mifare 1k */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_2KNDEF_COMPBLOCK 90 /* Total Ndef Compliant blocks Mifare 2k */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_4KNDEF_COMPBLOCK 210 /* Total Ndef Compliant blocks Mifare 4k */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_RDWR_SIZE 16 /* Bytes read/write for one read/write operation*/ +#define PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK 40 /* Total number of sectors in Mifare 4k */ +#define PH_FRINFC_NDEFMAP_MIFARESTD_ST15_BYTES 15 /* To store 15 bytes after reading a block */ + +/* + * Completion Routine Indices + * + * These are the indices of the completion routine pointers within the component context. + * Completion routines belong to upper components. + * + */ +#define PH_FRINFC_NDEFMAP_CR_CHK_NDEF 0 /* */ +#define PH_FRINFC_NDEFMAP_CR_RD_NDEF 1 /* */ +#define PH_FRINFC_NDEFMAP_CR_WR_NDEF 2 /* */ +#define PH_FRINFC_NDEFMAP_CR_ERASE_NDEF 3 /* */ +#define PH_FRINFC_NDEFMAP_CR_INVALID_OPE 4 /* */ +#define PH_FRINFC_NDEFMAP_CR 5 /* */ + +/* + * File Offset Attributes + * + * Following values are used to determine the offset value for Read/Write. This specifies whether + * the Read/Write operation needs to be restarted/continued from the last offset set. + * + */ +/* Read/Write operation shall start from the last offset set */ +#define PH_FRINFC_NDEFMAP_SEEK_CUR 0 /* */ +/* Read/Write operation shall start from the beginning of the file/card */ +#define PH_FRINFC_NDEFMAP_SEEK_BEGIN 1 /* */ + +/* Read operation invalid */ +#define PH_FRINFC_NDEFMAP_SEEK_INVALID 0xFF /* */ + +/* + * Buffer Size Definitions + * + */ +/* Minimum size of the TRX buffer required */ +#define PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE 252 /* */ +/* The size of s MIFARE block */ +#define PH_FRINFC_NDEFMAP_MF_READ_BLOCK_SIZE 16 /* */ + +typedef struct phFriNfc_MifareStdCont +{ + /* to store bytes that will be used in the next write/read operation, if any */ + uint8_t internalBuf[PH_FRINFC_NDEFMAP_MIFARESTD_ST15_BYTES]; + /* to Store the length of the internalBuf */ + uint16_t internalLength; + /* holds the block number which is presently been used */ + uint8_t currentBlock; + /* the number of Ndef compliant blocks written/read */ + uint8_t NdefBlocks; + /* Total Number of Ndef compliant Blocks */ + uint16_t NoOfNdefCompBlocks; + /* used in write ndef, to know that internal byte are accessed */ + uint8_t internalBufFlag; + /* used in write ndef, to know that last 16 bytes are used to write*/ + uint8_t RemainingBufFlag; + /* indicates that Read has reached the end of the card */ + uint8_t ReadWriteCompleteFlag; + /* indicates that Read has reached the end of the card */ + uint8_t ReadCompleteFlag; + /* indicates that Write is possible or not */ + uint8_t WriteFlag; + /* indicates that Write is possible or not */ + uint8_t ReadFlag; + /* indicates that Write is possible or not */ + uint8_t RdBeforeWrFlag; + /* Authentication Flag indicating that a particular sector is authenticated or not */ + uint8_t AuthDone; + /* to store the last Sector ID in Check Ndef */ + uint8_t SectorIndex; + /* to read the access bits of each sector */ + uint8_t ReadAcsBitFlag; + /* Flag to check if Acs bit was written in this call */ + uint8_t WriteAcsBitFlag; + /* Buffer to store 16 bytes */ + uint8_t Buffer[PH_FRINFC_NDEFMAP_MIFARESTD_RDWR_SIZE]; + /* to store the AIDs of Mifare 1k or 4k */ + uint8_t aid[PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK]; + /* flag to write with offset begin */ + uint8_t WrNdefFlag; + /* flag to read with offset begin */ + uint8_t ReadNdefFlag; + /* flag to check with offset begin */ + uint8_t ChkNdefFlag; + /* To store the remaining size of the Mifare 1k or 4k card */ + uint16_t remainingSize; + /* To update the remaining size when writing to the Mifare 1k or 4k card */ + uint8_t remSizeUpdFlag; + /* The flag is to know that there is a different AID apart from NFC forum sector AID */ + uint16_t aidCompleteFlag; + /* The flag is to know that there is a a NFC forum sector exists in the card */ + uint16_t NFCforumSectFlag; + /* The flag is to know that the particular sector is a proprietary NFC forum sector */ + uint16_t ProprforumSectFlag; + /* The flag is set after reading the MAD sectors */ + uint16_t ChkNdefCompleteFlag; + /* Flag to store the current block */ + uint8_t TempBlockNo; + /* Completion routine index */ + uint8_t CRIndex; + /* Bytes remaining to write for one write procedure */ + uint16_t WrLength; + /* Flag to read after write */ + uint8_t RdAfterWrFlag; + /* Flag to say that poll is required before write ndef (authentication) */ + uint8_t PollFlag; + /* Flag is to know that this is first time the read has been called. This + is required when read is called after write (especially for the card formatted + with the 2nd configuration) */ + uint8_t FirstReadFlag; + /* Flag is to know that this is first time the write has been called. This + is required when the card formatted with the 3rd configuration */ + uint8_t FirstWriteFlag; + /* Indicates the sector trailor id for which the convert + to read only is currently in progress*/ + uint8_t ReadOnlySectorIndex; + /* Indicates the total number of sectors on the card */ + uint8_t TotalNoSectors; + /* Indicates the block number of the sector trailor on the card */ + uint8_t SectorTrailerBlockNo; + /* Secret key B to given by the application */ + uint8_t UserScrtKeyB[6]; +}phFriNfc_MifareStdCont_t; + +/* + * NDEF TLV structure which details the different variables used for TLV. + * + */ +typedef struct phFriNfc_NDEFTLVCont +{ + /* Flag is to know that the TLV Type Found */ + uint8_t NdefTLVFoundFlag; + /* Sector number of the next/present available TLV */ + uint8_t NdefTLVSector; + /* Following two variables are used to store the + T byte and the Block number in which the T is + found in Tag */ + /* Byte number of the next/present available TLV */ + uint16_t NdefTLVByte; + /* Block number of the next/present available TLV */ + uint8_t NdefTLVBlock; + /* Authentication flag for NDEF TLV Block */ + uint8_t NdefTLVAuthFlag; + /* if the 16th byte of the last read is type (T) of TLV + and next read contains length (L) bytes of TLV. This flag + is set when the type (T) of TLV is found in the last read */ + uint8_t TcheckedinTLVFlag; + /* if the 16th byte of the last read is Length (L) of TLV + and next read contains length (L) bytes of TLV. This flag + is set when the Length (L) of TLV is found in the last read */ + uint8_t LcheckedinTLVFlag; + /* This flag is set, if Terminator TLV is already written + and next read contains value (V) bytes of TLV. This flag + is set when the value (V) of TLV is found in the last read */ + uint8_t SetTermTLVFlag; + /* To know the number of Length (L) field is present in the + next block */ + uint8_t NoLbytesinTLV; + /* The value of 3 bytes length(L) field in TLV. In 3 bytes + length field, 2 bytes are in one block and other 1 byte + is in the next block. To store the former block length + field value, this variable is used */ + uint16_t prevLenByteValue; + /* The value of length(L) field in TLV. */ + uint16_t BytesRemainLinTLV; + /* Actual size to read and write. This will be always equal to the + length (L) of TLV as there is only one NDEF TLV . */ + uint16_t ActualSize; + /* Flag is to write the length (L) field of the TLV */ + uint8_t WrLenFlag; + /* Flag is to write the length (L) field of the TLV */ + uint16_t NULLTLVCount; + /* Buffer to store 4 bytes of data which is written to a block */ + uint8_t NdefTLVBuffer[PH_FRINFC_NDEFMAP_MFUL_4BYTES_BUF]; + /* Buffer to store 4 bytes of data which is written to a next block */ + uint8_t NdefTLVBuffer1[PH_FRINFC_NDEFMAP_MFUL_4BYTES_BUF]; +}phFriNfc_NDEFTLVCont_t; + +/* + * Lock Control TLV structure which stores the Position, Size and PageCntrl details. + */ + +typedef struct phFriNfc_LockCntrlTLVCont +{ + /* Specifies the Byte Position of the lock cntrl tlv + in the card memory*/ + uint16_t ByteAddr; + + /* Specifies the Size of the lock area in terms of + bits/bytes*/ + uint16_t Size; + + /* Specifies the Bytes per Page*/ + uint8_t BytesPerPage; + + /* Specifies the BytesLockedPerLockBit */ + uint8_t BytesLockedPerLockBit; + + /* Specifies the index of Lock cntrl TLV*/ + uint8_t LockTlvBuffIdx; + + /* Store the content of Lock cntrl TLV*/ + uint8_t LockTlvBuff[8]; + + /* Specifies the Block number Lock cntrl TLV*/ + uint16_t BlkNum; + + /* Specifies the Byte Number position of Lock cntrl TLV*/ + uint16_t ByteNum; + + +}phFriNfc_LockCntrlTLVCont_t; + + +/* + * Memory Control TLV structure which stores the Position, Size and PageCntrl details of the reserved byte area. + */ + +typedef struct phFriNfc_ResMemCntrlTLVCont +{ + /* Specifies the Byte Position of the lock cntrl tlv + in the card memory */ + uint16_t ByteAddr; + + /* Specifies the Size of the lock area in terms of + bits/bytes*/ + uint16_t Size; + + /* Store the content of Memory cntrl TLV*/ + uint8_t MemCntrlTlvBuff[8]; + + /* Specifies the Bytes per Page*/ + uint8_t BytesPerPage; + + /* Specifies the index of Mem cntrl TLV*/ + uint8_t MemTlvBuffIdx; + + /* Specifies the Block number Lock cntrl TLV*/ + uint16_t BlkNum; + + /* Specifies the Byte Number position of Lock cntrl TLV*/ + uint16_t ByteNum; + + + +}phFriNfc_ResMemCntrlTLVCont_t; + +/* + * NFC NDEF Mapping Component Context Structure + * + * This structure is used to store the current context information of the instance. + * + */ +typedef struct phFriNfc_NdefMap +{ + /* The state of the operation. */ + uint8_t State; + + /* Completion Routine Context. */ + phFriNfc_CplRt_t CompletionRoutine[PH_FRINFC_NDEFMAP_CR]; + + phNfc_sTransceiveInfo_t *pTransceiveInfo; + + /*Holds the completion routine informations of the Map Layer*/ + phFriNfc_CplRt_t MapCompletionInfo; + + /* Pointer to the Remote Device Information */ + phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo; + + /*Holds the Command Type(read/write)*/ + phNfc_uCmdList_t Cmd; + + /* Pointer to a temporary buffer. Could be + used for read/write purposes */ + uint8_t *ApduBuffer; + + /* Size allocated to the ApduBuffer. */ + uint32_t ApduBufferSize; + + /* Index to the APDU Buffer. Used for internal calculations */ + uint16_t ApduBuffIndex; + + /* Pointer to the user-provided Data Size to be written trough WrNdef function. */ + uint32_t *WrNdefPacketLength; + + + /* Holds the length of the received data. */ + uint16_t *SendRecvLength; + + /*Holds the ack of some initial commands*/ + uint8_t *SendRecvBuf; + + /* Holds the length of the data to be sent. */ + uint16_t SendLength; + + /* Data Byte Count, which gives the offset to the integration.*/ + uint16_t *DataCount; + + /* Holds the previous operation on the card*/ + uint8_t PrevOperation; + + /* Holds the previous read mode*/ + uint8_t bPrevReadMode; + + /* Holds the current read mode*/ + uint8_t bCurrReadMode; + + /* Holds the previous state on the card*/ + uint8_t PrevState; + + /* Stores the type of the smart card. */ + uint8_t CardType; + + /* Stores the card state. */ + uint8_t CardState; + + /* Stores the memory size of the card */ + uint16_t CardMemSize; + + /*to Store the page offset on the mifare ul card*/ + uint8_t Offset; + + /* specifies the desired operation to be performed*/ + uint8_t DespOpFlag; + + /* Used to remember how many bytes were written, to update + the dataCount and the BufferIndex */ + uint16_t NumOfBytesWritten; + + /*used to remember number of L byte Remaining to be written */ + uint16_t NumOfLReminWrite; + + /* Pointer Used to remember and return how many bytes were read, + to update the PacketDataLength in case of Read operation */ + /* Fix for 0000238: [gk] MAP: Number of bytes actually read out is + not returned. */ + uint32_t *NumOfBytesRead; + + /* Flag used to tell the process function that WRITE has + requested for an internal READ.*/ + uint8_t ReadingForWriteOperation; + + /* Buffer of 5 bytes used for the write operation for the + Mifare UL card.*/ + uint8_t BufferForWriteOp[5]; + + /* Temporary Receive Length to update the Receive Length + when every time the Overlapped HAL is called. */ + uint16_t TempReceiveLength; + + uint8_t NoOfDevices ; + + /* stores operating mode type of the felica smart tag */ + /* phHal_eOpModes_t OpModeType[2]; */ + + /* stores the type of the TLV found */ + uint8_t TLVFoundFlag; + + /* stores the TLV structure related informations */ + phFriNfc_NDEFTLVCont_t TLVStruct; + + /* stores the Lock Contrl Tlv related informations */ + phFriNfc_LockCntrlTLVCont_t LockTlv; + + /* stores the Mem Contrl Tlv related informations */ + phFriNfc_ResMemCntrlTLVCont_t MemTlv; + + /* Pointer to the Mifare Standard capability Container Structure. */ + phFriNfc_MifareStdCont_t StdMifareContainer; + +} phFriNfc_NdefMap_t; + +/* + * States of the FSM. + */ +#define PH_FRINFC_NDEFMAP_STATE_RESET_INIT 0 /* Initial state */ +#define PH_FRINFC_NDEFMAP_STATE_CR_REGISTERED 1 /* CR has been registered */ +#define PH_FRINFC_NDEFMAP_STATE_EOF_CARD 2 /* EOF card reached */ + +/* Following values specify the previous operation on the card. This value is assigned to + the context structure variable: PrevOperation. */ + +/* Previous operation is check */ +#define PH_FRINFC_NDEFMAP_CHECK_OPE 1 +/* Previous operation is read */ +#define PH_FRINFC_NDEFMAP_READ_OPE 2 +/* Previous operation is write */ +#define PH_FRINFC_NDEFMAP_WRITE_OPE 3 +/* Previous operation is Actual size */ +#define PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE 4 + +/* This flag is set when there is a need of write operation on the odd positions + ex: 35,5 etc. This is used with MfUlOp Flag */ +#define PH_FRINFC_MFUL_INTERNAL_READ 3 /* Read/Write control*/ + + +#endif /* PHFRINFC_NDEFMAP_H */ diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_SmtCrdFmt.c b/nci/jni/extns/pn54x/src/mifare/phFriNfc_SmtCrdFmt.c new file mode 100755 index 00000000..46f2ccc2 --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_SmtCrdFmt.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * Smart Card Completion Routing component + */ + +#include <phNfcTypes.h> +#include<phFriNfc.h> +#include <phFriNfc_SmtCrdFmt.h> +#include <phNfcCompId.h> +#include <phFriNfc_MifStdFormat.h> + + +/******************************************************************************* +** +** Function phFriNfc_SmtCrdFmt_HCrHandler +** +** Description This function is called to complete Completion Routine when gets error. +** +** Returns none. +** +*******************************************************************************/ +void phFriNfc_SmtCrdFmt_HCrHandler(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, NFCSTATUS Status) +{ + /* set the state back to the Reset_Init state*/ + NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; + + /* set the completion routine*/ + NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_FORMAT]. + CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context, Status); + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_NdefSmtCrd_Reset +** +** Description Resets the component instance to the initial state and initializes the +** internal variables. +** This function has to be called at the beginning, after creating an instance of +** phFriNfc_sNdefSmtCrdFmt_t. Use this function to reset the instance and/or to switch +** to a different underlying card types. +** +** Returns NFCSTATUS_SUCCESS if operation successful. +** NFCSTATUS_INVALID_PARAMETER if at least one parameter of the function is invalid. +** +*******************************************************************************/ +NFCSTATUS phFriNfc_NdefSmtCrd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, + void *LowerDevice, + phHal_sRemoteDevInformation_t *psRemoteDevInfo, + uint8_t *SendRecvBuffer, + uint16_t *SendRecvBuffLen) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + uint8_t index; + if ( (SendRecvBuffLen == NULL) || (NdefSmtCrdFmt == NULL) || (psRemoteDevInfo == NULL) || + (SendRecvBuffer == NULL) || (LowerDevice == NULL) || + (*SendRecvBuffLen == 0) || + (*SendRecvBuffLen < PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE) ) + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); + } + else + { + /* Initialize the state to Init */ + NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; + + for(index = 0;index<PH_FRINFC_SMTCRDFMT_CR;index++) + { + /* Initialize the NdefMap Completion Routine to Null */ + NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL; + /* Initialize the NdefMap Completion Routine context to Null */ + NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL; + } + + /* Lower Device(Always Overlapped HAL Struct initialized in application + * is registered in NdefMap Lower Device) + */ + NdefSmtCrdFmt->pTransceiveInfo = LowerDevice; + + /* Remote Device info received from Manual Device Discovery is registered here */ + NdefSmtCrdFmt->psRemoteDevInfo = psRemoteDevInfo; + + /* Trx Buffer registered */ + NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer; + + /* Trx Buffer Size */ + NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen; + + /* Register Transfer Buffer Length */ + NdefSmtCrdFmt->SendLength = 0; + + /* Initialize the Format status flag*/ + NdefSmtCrdFmt->FmtProcStatus = 0; + + /* Reset the Card Type */ + NdefSmtCrdFmt->CardType = 0; + + /* Reset MapCompletion Info*/ + NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL; + NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL; + + /* Reset Mifare Standard Container elements*/ + phFriNfc_MfStd_Reset(NdefSmtCrdFmt); + } + + return (result); +} + +/******************************************************************************* +** +** Function phFriNfc_NdefSmtCrd_SetCR +** +** Description This function allows the caller to set a Completion Routine (notifier). +** +** Returns NFCSTATUS_SUCCESS if operation successful. +** NFCSTATUS_INVALID_PARAMETER if at least one parameter of the function is invalid. +** +*******************************************************************************/ +NFCSTATUS phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, + uint8_t FunctionID, + pphFriNfc_Cr_t CompletionRoutine, + void *CompletionRoutineContext) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + if ((NdefSmtCrdFmt == NULL) || (FunctionID >= PH_FRINFC_SMTCRDFMT_CR) || + (CompletionRoutine == NULL) || (CompletionRoutineContext == NULL)) + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); + } + else + { + /* Register the application callback with the NdefMap Completion Routine */ + NdefSmtCrdFmt->CompletionRoutine[FunctionID].CompletionRoutine = CompletionRoutine; + + /* Register the application context with the NdefMap Completion Routine context */ + NdefSmtCrdFmt->CompletionRoutine[FunctionID].Context = CompletionRoutineContext; + } + return status; +} + +/******************************************************************************* +** +** Function phFriNfc_NdefSmtCrd_Process +** +** Description This function is called by the lower layer (OVR HAL) +** when an I/O operation has finished. The internal state machine decides +** whether to call into the lower device again or to complete the process +** by calling into the upper layer's completion routine, stored within this +** component's context (phFriNfc_sNdefSmtCrdFmt_t). +** +** Returns none. +** +*******************************************************************************/ +void phFriNfc_NdefSmtCrd_Process(void *Context, NFCSTATUS Status) +{ + if ( Context != NULL ) + { + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context; + + switch ( NdefSmtCrdFmt->psRemoteDevInfo->RemDevType ) + { + case phNfc_eMifare_PICC : + case phNfc_eISO14443_3A_PICC: + if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) || + (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD) || + (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD)) + { + /* Remote device is Mifare Standard card */ + phFriNfc_MfStd_Process(NdefSmtCrdFmt,Status); + + } + else + { + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_INVALID_REMOTE_DEVICE); + } + break; + default : + /* Remote device opmode not recognized. + * Probably not NDEF compliant + */ + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_INVALID_REMOTE_DEVICE); + /* set the state back to the Reset_Init state*/ + NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; + + /* set the completion routine*/ + NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_INVALID_OPE]. + CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context, Status); + break; + } + } + else + { + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,\ + NFCSTATUS_INVALID_PARAMETER); + /* The control should not come here. As Context itself is NULL , + * Can't call the CR + */ + } + + return; +} diff --git a/nci/jni/extns/pn54x/src/mifare/phFriNfc_SmtCrdFmt.h b/nci/jni/extns/pn54x/src/mifare/phFriNfc_SmtCrdFmt.h new file mode 100755 index 00000000..ac10dee7 --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phFriNfc_SmtCrdFmt.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * Smart Card Completion Routing component + */ + +#ifndef PHFRINFC_SMTCRDFMT_H +#define PHFRINFC_SMTCRDFMT_H + +#include <phNfcTypes_Mapping.h> + +/********************* Definitions and structures *****************************/ + +#define DESFIRE_FMT_EV1 + +#define PH_FRI_NFC_SMTCRDFMT_NFCSTATUS_FORMAT_ERROR 9 /* Format error */ +#define PH_FRINFC_SMTCRDFMT_MSTD_DEFAULT_KEYA_OR_KEYB {0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF} /* Default Key */ +#define PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA {0xA0, 0xA1,0xA2,0xA3,0xA4,0xA5} /* Key A */ +#define PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA {0xD3, 0xF7,0xD3,0xF7,0xD3,0xF7} /* NFC Forum Key */ +#define PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_ACCESSBITS {0x78,0x77,0x88} /* Access bits */ +#define PH_FRINFC_SMTCRDFMT_MSTD_NFCFORUM_ACCESSBITS {0x7F,0x07,0x88} /* NFC Forum access bits */ +#define PH_FRINFC_SMTCRDFMT_MAX_TLV_TYPE_SUPPORTED 1 /* TLV support */ +#define PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE 252 /* Buffer size */ +#define PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT 1 /* Format state */ + +/* + * Enum definition contains Tag Types + */ +enum +{ + PH_FRINFC_SMTCRDFMT_MIFARE_UL_CARD, + PH_FRINFC_SMTCRDFMT_ISO14443_4A_CARD, + PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD, + PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD, + PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD, + PH_FRINFC_SMTCRDFMT_TOPAZ_CARD +}; + +#define PH_FRINFC_SMTCRDFMT_CR_FORMAT 0 /* Index for phFriNfc_SmtCrd_Format */ +#define PH_FRINFC_SMTCRDFMT_CR_INVALID_OPE 1 /* Index for Unknown States/Operations */ +#define PH_FRINFC_SMTCRDFMT_CR 2 /* Number of completion routines */ + + /* + * Mifare Std Additional Information Structure + */ + typedef struct phFriNfc_MfStd_AddInfo +{ + uint8_t Default_KeyA_OR_B[6]; /* Stores the Default KeyA and KeyB values */ + uint8_t MADSect_KeyA[6]; /* Key A of MAD sector */ + uint8_t NFCForumSect_KeyA[6]; /* Key A of NFC Forum Sector sector */ + uint8_t MADSect_AccessBits[3]; /* Access Bits of MAD sector */ + uint8_t NFCForumSect_AccessBits[3]; /* Access Bits of NFC Forum sector */ + uint8_t ScrtKeyB[6]; /* Secret key B to given by the application */ + uint8_t AuthState; /* Status of the different authentication */ + uint16_t CurrentBlock; /* Stores the current block */ + uint8_t NoOfDevices; /* Stores the current block */ + uint8_t SectCompl[40]; /* Store the compliant sectors */ + uint8_t WrMADBlkFlag; /* Flag to know that MAD sector */ + uint8_t MADSectBlk[80]; /* Fill the MAD sector blocks */ + uint8_t UpdMADBlk; /* Fill the MAD sector blocks */ +} phFriNfc_MfStd_AddInfo_t; + +/* + * Ndef Mifare Std Additional Information Structure + */ +typedef struct phFriNfc_sNdefSmtCrdFmt_AddInfo +{ + phFriNfc_MfStd_AddInfo_t MfStdInfo; /* Mifare Std Additional Information Structure */ + +}phFriNfc_sNdefSmtCrdFmt_AddInfo_t; + +/* + * Context information Structure + */ +typedef struct phFriNfc_sNdefSmtCrdFmt +{ + phNfc_sTransceiveInfo_t *pTransceiveInfo; /* Pointer to the Transceive information */ + phHal_sRemoteDevInformation_t *psRemoteDevInfo; /* Pointer to the Remote Device Information */ + uint8_t CardType; /* Stores the type of the smart card */ + uint8_t State; /* The state of the operation */ + uint8_t CardState; /* Stores the card state */ + phFriNfc_CplRt_t CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR]; /* Completion Routine Context */ + phFriNfc_CplRt_t SmtCrdFmtCompletionInfo; /* Holds the completion routine informations of the Smart Card Formatting Layer */ + phHal_uCmdList_t Cmd; /* Holds the Command Type(read/write) */ + uint16_t *SendRecvLength; /* Holds the length of the received data */ + uint8_t *SendRecvBuf; /* Holds the ack of some intial commands */ + uint16_t SendLength; /* Holds the length of the data to be sent */ + NFCSTATUS FmtProcStatus; /* Stores the output/result of the format procedure */ + phFriNfc_sNdefSmtCrdFmt_AddInfo_t AddInfo; /* Stores Additional Information needed to format the different types of tags*/ + uint8_t TLVMsg[PH_FRINFC_SMTCRDFMT_MAX_TLV_TYPE_SUPPORTED][8]; /* Stores NDEF message TLV */ +} phFriNfc_sNdefSmtCrdFmt_t; + +NFCSTATUS phFriNfc_NdefSmtCrd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, + void *LowerDevice, + phHal_sRemoteDevInformation_t *psRemoteDevInfo, + uint8_t *SendRecvBuffer, + uint16_t *SendRecvBuffLen); + +NFCSTATUS phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, + uint8_t FunctionID, + pphFriNfc_Cr_t CompletionRoutine, + void *CompletionRoutineContext); + +void phFriNfc_NdefSmtCrd_Process(void *Context, NFCSTATUS Status); + +void phFriNfc_SmtCrdFmt_HCrHandler(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, NFCSTATUS Status); + +#endif /* PHFRINFC_SMTCRDFMT_H */ diff --git a/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.c b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.c new file mode 100755 index 00000000..c0c3bc1f --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.c @@ -0,0 +1,2154 @@ +/* + * Copyright (C) 2015 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. + */ + +#include <nfc_api.h> +#include <rw_api.h> +#include <phNfcCompId.h> +#include <phNxpLog.h> +#include <phNxpExtns_MifareStd.h> + +phNxpExtns_Context_t gphNxpExtns_Context; +phNciNfc_TransceiveInfo_t tNciTranscvInfo; +phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = NULL; +phFriNfc_NdefMap_t *NdefMap = NULL; +phLibNfc_NdefInfo_t NdefInfo; +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) +pthread_mutex_t SharedDataMutex = PTHREAD_MUTEX_INITIALIZER; +#endif +UINT8 current_key[6]={0}; +phNci_mfc_auth_cmd_t gAuthCmdBuf; +STATIC NFCSTATUS phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo, + uint8_t *buff, uint16_t *buffSz); +STATIC NFCSTATUS phLibNfc_SendRawCmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf); +STATIC NFCSTATUS phLibNfc_SendWrt16Cmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf); +STATIC NFCSTATUS phLibNfc_SendAuthCmd(phNfc_sTransceiveInfo_t *pTransceiveInfo, + phNciNfc_TransceiveInfo_t *tNciTranscvInfo) __attribute__((unused)); +STATIC NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t RemDevType, + phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf); +STATIC NFCSTATUS phLibNfc_MifareMap(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf); +STATIC NFCSTATUS phLibNfc_ChkAuthCmdMFC(phNfc_sTransceiveInfo_t* pTransceiveInfo, + uint8_t *bKey); +STATIC NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t *buffer,uint8_t *bKey); +STATIC void phLibNfc_CalSectorAddress(uint8_t *Sector_Address); +STATIC NFCSTATUS phNciNfc_MfCreateAuthCmdHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, + uint8_t bBlockAddr, + uint8_t *buff, + uint16_t *buffSz); +STATIC NFCSTATUS phNciNfc_MfCreateXchgDataHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, + uint8_t *buff, uint16_t *buffSz); +STATIC NFCSTATUS phLibNfc_SendWrt16CmdPayload(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf); +STATIC NFCSTATUS phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo, NFCSTATUS wStatus); +STATIC NFCSTATUS nativeNfcExtns_doTransceive(uint8_t *buff, uint16_t buffSz); +STATIC NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, + uint8_t *SendRecvBuffer, + uint16_t *SendRecvBuffLen); +STATIC NFCSTATUS phFriNfc_ValidateParams(uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset, + phFriNfc_NdefMap_t *pNdefMap, + uint8_t bNdefReq); +STATIC void Mfc_FormatNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); +STATIC void Mfc_WriteNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); +STATIC void Mfc_ReadNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); +STATIC void Mfc_CheckNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); + +/******************************************************************************* +** +** Function phNxpExtns_MfcModuleDeInit +** +** Description It Deinitializes the Mifare module. +** +** Frees all the memory occupied by Mifare module +** +** Returns: +** NFCSTATUS_SUCCESS - if successfully deinitialize +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS phNxpExtns_MfcModuleDeInit(void) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + + if(NdefMap != NULL) + { + if( NdefMap->psRemoteDevInfo != NULL ) + { + free(NdefMap->psRemoteDevInfo); + NdefMap->psRemoteDevInfo = NULL; + } + if( NdefMap->SendRecvBuf != NULL ) + { + free(NdefMap->SendRecvBuf); + NdefMap->SendRecvBuf = NULL; + } + if( NdefMap->SendRecvLength != NULL ) + { + free(NdefMap->SendRecvLength); + NdefMap->SendRecvLength = NULL; + } + if( NdefMap->DataCount != NULL ) + { + free(NdefMap->DataCount); + NdefMap->DataCount = NULL; + } + if( NdefMap->pTransceiveInfo != NULL ) + { + if( NdefMap->pTransceiveInfo->sSendData.buffer != NULL ) + { + free(NdefMap->pTransceiveInfo->sSendData.buffer); + NdefMap->pTransceiveInfo->sSendData.buffer = NULL; + } + if( NdefMap->pTransceiveInfo->sRecvData.buffer != NULL ) + { + free(NdefMap->pTransceiveInfo->sRecvData.buffer); + NdefMap->pTransceiveInfo->sRecvData.buffer = NULL; + } + free(NdefMap->pTransceiveInfo); + NdefMap->pTransceiveInfo = NULL; + } + + free(NdefMap); + NdefMap = NULL; + } + + if( tNciTranscvInfo.tSendData.pBuff != NULL ) + { + free(tNciTranscvInfo.tSendData.pBuff); + tNciTranscvInfo.tSendData.pBuff = NULL; + } + + if( NdefSmtCrdFmt != NULL ) + { + free(NdefSmtCrdFmt); + NdefSmtCrdFmt = NULL; + } +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_lock(&SharedDataMutex); +#endif + if ( NULL != NdefInfo.psUpperNdefMsg ) + { + if ( NdefInfo.psUpperNdefMsg->buffer != NULL ) + { + free(NdefInfo.psUpperNdefMsg->buffer); + NdefInfo.psUpperNdefMsg->buffer = NULL; + } + free(NdefInfo.psUpperNdefMsg); + NdefInfo.psUpperNdefMsg = NULL; + } +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_unlock(&SharedDataMutex); +#endif + if (NULL != gAuthCmdBuf.pauth_cmd) + { + if (NULL != gAuthCmdBuf.pauth_cmd->buffer) + { + free(gAuthCmdBuf.pauth_cmd->buffer); + gAuthCmdBuf.pauth_cmd->buffer = NULL; + } + free(gAuthCmdBuf.pauth_cmd); + gAuthCmdBuf.pauth_cmd = NULL; + } + status = NFCSTATUS_SUCCESS; + return status; +} + +/******************************************************************************* +** +** Function phNxpExtns_MfcModuleInit +** +** Description It Initializes the memroy and global variables related +** to Mifare module. +** +** Reset all the global variables and allocate memory for Mifare module +** +** Returns: +** NFCSTATUS_SUCCESS - if successfully deinitialize +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS phNxpExtns_MfcModuleInit(void) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + gphNxpExtns_Context.writecmdFlag = FALSE; + gphNxpExtns_Context.RawWriteCallBack = FALSE; + gphNxpExtns_Context.CallBackCtxt = NULL; + gphNxpExtns_Context.CallBackMifare = NULL; + gphNxpExtns_Context.ExtnsConnect = FALSE; + gphNxpExtns_Context.ExtnsDeactivate = FALSE; + gphNxpExtns_Context.ExtnsCallBack = FALSE; + + NdefMap = malloc(sizeof(phFriNfc_NdefMap_t)); + if( NULL == NdefMap ) + { + goto clean_and_return; + } + memset(NdefMap,0,sizeof(phFriNfc_NdefMap_t)); + + NdefMap->psRemoteDevInfo = malloc(sizeof(phLibNfc_sRemoteDevInformation_t)); + if( NULL == NdefMap->psRemoteDevInfo ) + { + goto clean_and_return; + } + memset(NdefMap->psRemoteDevInfo, 0, sizeof(phLibNfc_sRemoteDevInformation_t)); + + NdefMap->SendRecvBuf = malloc((uint32_t)(MAX_BUFF_SIZE * 2)); + if( NULL == NdefMap->SendRecvBuf ) + { + goto clean_and_return; + } + memset(NdefMap->SendRecvBuf, 0, (MAX_BUFF_SIZE * 2)); + + NdefMap->SendRecvLength = malloc(sizeof(uint16_t)); + if( NULL == NdefMap->SendRecvLength ) + { + goto clean_and_return; + } + memset(NdefMap->SendRecvLength, 0, sizeof(uint16_t)); + + NdefMap->DataCount = malloc(sizeof(uint16_t)); + if( NULL == NdefMap->DataCount ) + { + goto clean_and_return; + } + memset(NdefMap->DataCount, 0, sizeof(uint16_t)); + + NdefMap->pTransceiveInfo = malloc(sizeof(phNfc_sTransceiveInfo_t)); + if(NULL == NdefMap->pTransceiveInfo) + { + goto clean_and_return; + } + memset(NdefMap->pTransceiveInfo, 0, sizeof(phNfc_sTransceiveInfo_t)); + + tNciTranscvInfo.tSendData.pBuff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); + if(NULL == tNciTranscvInfo.tSendData.pBuff) + { + goto clean_and_return; + } + memset(tNciTranscvInfo.tSendData.pBuff, 0, MAX_BUFF_SIZE); + + NdefMap->pTransceiveInfo->sSendData.buffer = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); + if( NdefMap->pTransceiveInfo->sSendData.buffer == NULL ) + { + goto clean_and_return; + } + memset( NdefMap->pTransceiveInfo->sSendData.buffer, 0, MAX_BUFF_SIZE ); + NdefMap->pTransceiveInfo->sSendData.length = MAX_BUFF_SIZE; + + NdefMap->pTransceiveInfo->sRecvData.buffer = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); /* size should be same as sRecvData */ + if( NdefMap->pTransceiveInfo->sRecvData.buffer == NULL ) + { + goto clean_and_return; + } + memset( NdefMap->pTransceiveInfo->sRecvData.buffer, 0, MAX_BUFF_SIZE ); + NdefMap->pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; + + NdefSmtCrdFmt = malloc( sizeof(phFriNfc_sNdefSmtCrdFmt_t) ); + if( NdefSmtCrdFmt == NULL ) + { + goto clean_and_return; + } + memset( NdefSmtCrdFmt , 0, sizeof(phFriNfc_sNdefSmtCrdFmt_t) ); +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_lock(&SharedDataMutex); +#endif + NdefInfo.psUpperNdefMsg = malloc(sizeof(phNfc_sData_t)); + if ( NULL == NdefInfo.psUpperNdefMsg ) + { + goto clean_and_return; + } + memset( NdefInfo.psUpperNdefMsg, 0, sizeof(phNfc_sData_t) ); + memset (&gAuthCmdBuf, 0, sizeof(phNci_mfc_auth_cmd_t)); + gAuthCmdBuf.pauth_cmd = malloc(sizeof(phNfc_sData_t)); + if (NULL == gAuthCmdBuf.pauth_cmd) + { + goto clean_and_return; + } + gAuthCmdBuf.pauth_cmd->buffer = malloc((uint32_t)NCI_MAX_DATA_LEN); + if (NULL == gAuthCmdBuf.pauth_cmd->buffer) + { + goto clean_and_return; + } + status = NFCSTATUS_SUCCESS; + +clean_and_return: +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_unlock(&SharedDataMutex); +#endif + if(status != NFCSTATUS_SUCCESS) + { + NXPLOG_EXTNS_E("CRIT: Memory Allocation failed for MFC!"); + phNxpExtns_MfcModuleDeInit(); + } + return status; +} + +/******************************************************************************* +** +** Function Mfc_CheckNdef +** +** Description It triggers NDEF detection for Mifare Classic Tag. +** +** +** Returns NFCSTATUS_SUCCESS - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_CheckNdef(void) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + + EXTNS_SetCallBackFlag(FALSE); + /* Set Completion Routine for CheckNdef */ + NdefMap->CompletionRoutine[0].CompletionRoutine = Mfc_CheckNdef_Completion_Routine; + + gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; + gphNxpExtns_Context.CallBackCtxt = NdefMap; + status = phFriNfc_MifareStdMap_H_Reset(NdefMap); + if ( NFCSTATUS_SUCCESS == status) + { + status = phFriNfc_MifareStdMap_ChkNdef(NdefMap); + if ( status == NFCSTATUS_PENDING ) + { + status = NFCSTATUS_SUCCESS; + } + } + if( status != NFCSTATUS_SUCCESS ) + { + status = NFCSTATUS_FAILED; + } + + return status; +} + +/******************************************************************************* +** +** Function Mfc_CheckNdef_Completion_Routine +** +** Description Notify NDEF detection for Mifare Classic Tag to JNI +** +** Upon completion of NDEF detection, a +** NFA_NDEF_DETECT_EVT will be sent, to notify the application +** of the NDEF attributes (NDEF total memory size, current +** size, etc.). +** +** Returns: void +** +*******************************************************************************/ +STATIC void Mfc_CheckNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) +{ + (void)NdefCtxt; + tNFA_CONN_EVT_DATA conn_evt_data; + + conn_evt_data.ndef_detect.status = status; + if(NFCSTATUS_SUCCESS == status) + { + /* NDef Tag Detected */ + conn_evt_data.ndef_detect.protocol = NFA_PROTOCOL_MIFARE; + phFrinfc_MifareClassic_GetContainerSize(NdefMap, + (uint32_t *)&(conn_evt_data.ndef_detect.max_size), + (uint32_t *)&(conn_evt_data.ndef_detect.cur_size)); + NdefInfo.NdefLength = conn_evt_data.ndef_detect.max_size; + /* update local flags */ + NdefInfo.is_ndef = 1; + NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size; + if ( PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState ) + { + NXPLOG_EXTNS_D("Mfc_CheckNdef_Completion_Routine : READ_ONLY_CARD"); + conn_evt_data.ndef_detect.flags = RW_NDEF_FL_READ_ONLY; + } + else + { + conn_evt_data.ndef_detect.flags = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED; + } + } + else + { + /* NDEF Detection failed for other reasons */ + conn_evt_data.ndef_detect.cur_size = 0; + conn_evt_data.ndef_detect.max_size = 0; + conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; + + /* update local flags */ + NdefInfo.is_ndef = 0; + NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size; + } + (*gphNxpExtns_Context.p_conn_cback) (NFA_NDEF_DETECT_EVT, &conn_evt_data); + + return; +} +/******************************************************************************* +** +** Function Mfc_ReadNdef_Completion_Routine +** +** Description Notify NDEF read completion for Mifare Classic Tag to JNI +** +** Upon completion of NDEF read, a +** NFA_READ_CPLT_EVT will be sent, to notify the application +** with the NDEF data and status +** +** Returns: void +** +*******************************************************************************/ +STATIC void Mfc_ReadNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) +{ + (void)NdefCtxt; + tNFA_CONN_EVT_DATA conn_evt_data; + tNFA_NDEF_EVT_DATA p_data; + + conn_evt_data.status = status; +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_lock(&SharedDataMutex); +#endif + if(NFCSTATUS_SUCCESS == status) + { + p_data.ndef_data.len = NdefInfo.psUpperNdefMsg->length; + p_data.ndef_data.p_data = NdefInfo.psUpperNdefMsg->buffer; + (*gphNxpExtns_Context.p_ndef_cback) (NFA_NDEF_DATA_EVT, &p_data); + } + else + { + } + + (*gphNxpExtns_Context.p_conn_cback) (NFA_READ_CPLT_EVT, &conn_evt_data); + + if( NdefInfo.psUpperNdefMsg->buffer != NULL) + { + free (NdefInfo.psUpperNdefMsg->buffer); + NdefInfo.psUpperNdefMsg->buffer = NULL; + } +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_unlock(&SharedDataMutex); +#endif + return; +} + +/******************************************************************************* +** +** Function Mfc_WriteNdef_Completion_Routine +** +** Description Notify NDEF write completion for Mifare Classic Tag to JNI +** +** Upon completion of NDEF write, a +** NFA_WRITE_CPLT_EVT will be sent along with status +** +** Returns: void +** +*******************************************************************************/ +STATIC void Mfc_WriteNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) +{ + (void)NdefCtxt; + tNFA_CONN_EVT_DATA conn_evt_data; + + conn_evt_data.status = status; + (*gphNxpExtns_Context.p_conn_cback) (NFA_WRITE_CPLT_EVT, &conn_evt_data); + + return; +} + +/******************************************************************************* +** +** Function Mfc_FormatNdef_Completion_Routine +** +** Description Notify NDEF format completion for Mifare Classic Tag to JNI +** +** Upon completion of NDEF format, a +** NFA_FORMAT_CPLT_EVT will be sent along with status +** +** Returns: void +** +*******************************************************************************/ +STATIC void Mfc_FormatNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) +{ + (void)NdefCtxt; + tNFA_CONN_EVT_DATA conn_evt_data; + + conn_evt_data.status = status; + (*gphNxpExtns_Context.p_conn_cback) (NFA_FORMAT_CPLT_EVT, &conn_evt_data); + + return; +} + +/******************************************************************************* +** +** Function phFriNfc_ValidateParams +** +** Description This function is a common function which validates NdefRd +** and NdefWr parameters. +** +** Returns NFCSTATUS_SUCCESS - All the params are valid +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phFriNfc_ValidateParams(uint8_t *PacketData, + uint32_t *PacketDataLength, + uint8_t Offset, + phFriNfc_NdefMap_t *pNdefMap, + uint8_t bNdefReq) +{ + + if( (pNdefMap == NULL) || (PacketData == NULL) + || (PacketDataLength == NULL) ) + { + return NFCSTATUS_FAILED; + } + + if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID ) + { + return NFCSTATUS_FAILED; + } + + if( bNdefReq == PH_FRINFC_NDEF_READ_REQ ) + { + if( (Offset != PH_FRINFC_NDEFMAP_SEEK_CUR) && (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) ) + { + return NFCSTATUS_FAILED; + } + if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED ) + { + pNdefMap->NumOfBytesRead = PacketDataLength; + *pNdefMap->NumOfBytesRead = 0; + return NFCSTATUS_EOF_NDEF_CONTAINER_REACHED; + } + if( (pNdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) && + (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) ) + { + return NFCSTATUS_FAILED; /* return INVALID_DEVICE_REQUEST */ + } + if( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN ) + { + pNdefMap->ApduBuffIndex = 0; + *pNdefMap->DataCount = 0; + } + else if ( (pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || + (pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_CUR) ) + { + + } + else + { + return NFCSTATUS_FAILED; + } + } + else if( bNdefReq == PH_FRINFC_NDEF_WRITE_REQ ) + { + if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY ) + { + pNdefMap->WrNdefPacketLength = PacketDataLength; + *pNdefMap->WrNdefPacketLength = 0x00; + return NFCSTATUS_NOT_ALLOWED; + } + } + + return NFCSTATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function Mfc_SetRdOnly_Completion_Routine +** +** Description Notify NDEF read only completion for Mifare Classic Tag to JNI +** +** Upon completion of NDEF format, a +** NFA_SET_TAG_RO_EVT will be sent along with status +** +** Returns: void +** +*******************************************************************************/ +STATIC void Mfc_SetRdOnly_Completion_Routine(void *NdefCtxt, NFCSTATUS status) +{ + (void)NdefCtxt; + tNFA_CONN_EVT_DATA conn_evt_data; + ALOGE("Mfc_SetRdOnly_Completion_Routine status = 0x%x", status); + conn_evt_data.status = status; + (*gphNxpExtns_Context.p_conn_cback) (NFA_SET_TAG_RO_EVT, &conn_evt_data); + + return; +} + +/******************************************************************************* +** +** Function Mfc_SetReadOnly +** +** +** Description: It triggers ConvertToReadOnly for Mifare Classic Tag. +** +** Returns: +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_SetReadOnly(uint8_t *secrtkey, uint8_t len) +{ + NXPLOG_EXTNS_D("%s Entering ", __FUNCTION__); + NFCSTATUS status = NFCSTATUS_FAILED; + uint8_t mif_secrete_key[6] = {0}; + uint8_t id = 0; + EXTNS_SetCallBackFlag(FALSE); + memcpy(mif_secrete_key,secrtkey,len); + gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; + gphNxpExtns_Context.CallBackCtxt = NdefMap; + for (id = 0; id < len; id++) + { + ALOGD("secrtkey[%d] = 0x%x", id, secrtkey[id]); + ALOGD("mif_secrete_key[%d] = 0x%x", id, mif_secrete_key[id]); + } + /* Set Completion Routine for ReadNdef */ + NdefMap->CompletionRoutine[0].CompletionRoutine = Mfc_SetRdOnly_Completion_Routine; + if(NdefInfo.is_ndef == 0) + { + status = NFCSTATUS_NON_NDEF_COMPLIANT; + goto Mfc_SetRdOnly; + } + else if( (NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0) ) + { +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_lock(&SharedDataMutex); +#endif + NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize; +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_unlock(&SharedDataMutex); +#endif + status = NFCSTATUS_SUCCESS; + goto Mfc_SetRdOnly; + } + else + { + status = phFriNfc_MifareStdMap_ConvertToReadOnly(NdefMap, mif_secrete_key); + } + if ( NFCSTATUS_PENDING == status ) + { + status = NFCSTATUS_SUCCESS; + } + +Mfc_SetRdOnly: + return status; +} + +/******************************************************************************* +** +** Function Mfc_ReadNdef +** +** Description It triggers receiving of the NDEF message from Mifare Classic Tag. +** +** +** Returns: +** NFCSTATUS_SUCCESS - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_ReadNdef(void) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + uint8_t *PacketData = NULL; + uint32_t *PacketDataLength = NULL; + phLibNfc_Ndef_EOffset_t Offset; + + EXTNS_SetCallBackFlag(FALSE); + + Offset = phLibNfc_Ndef_EBegin; + + gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; + gphNxpExtns_Context.CallBackCtxt = NdefMap; +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_lock(&SharedDataMutex); +#endif + if(NdefInfo.is_ndef == 0) + { + status = NFCSTATUS_NON_NDEF_COMPLIANT; + goto Mfc_RdNdefEnd; + } + else if( (NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0) ) + { + NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize; + status = NFCSTATUS_SUCCESS; + goto Mfc_RdNdefEnd; + } + else + { + NdefInfo.psUpperNdefMsg->buffer = malloc(NdefInfo.NdefActualSize); + if ( NULL == NdefInfo.psUpperNdefMsg->buffer) + { + goto Mfc_RdNdefEnd; + } + NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize; + + /* Set Completion Routine for ReadNdef */ + NdefMap->CompletionRoutine[1].CompletionRoutine = Mfc_ReadNdef_Completion_Routine; + NdefInfo.NdefContinueRead = (uint8_t) ((phLibNfc_Ndef_EBegin==Offset) ? + PH_FRINFC_NDEFMAP_SEEK_BEGIN : + PH_FRINFC_NDEFMAP_SEEK_CUR); + } + + PacketData = NdefInfo.psUpperNdefMsg->buffer; + PacketDataLength = (uint32_t*)&(NdefInfo.psUpperNdefMsg->length); + NdefMap->bCurrReadMode = Offset; + status = phFriNfc_ValidateParams (PacketData, PacketDataLength, Offset, NdefMap, PH_FRINFC_NDEF_READ_REQ); + if( status != NFCSTATUS_SUCCESS ) + { + goto Mfc_RdNdefEnd; + } + + status = phFriNfc_MifareStdMap_RdNdef(NdefMap, PacketData, PacketDataLength, Offset); + + if(NFCSTATUS_INSUFFICIENT_STORAGE == status) + { + NdefInfo.psUpperNdefMsg->length = 0x00; + status = NFCSTATUS_SUCCESS; + } + + if ( NFCSTATUS_PENDING == status ) + { + status = NFCSTATUS_SUCCESS; + } + +Mfc_RdNdefEnd: + if( status != NFCSTATUS_SUCCESS ) + { + if ( NULL != NdefInfo.psUpperNdefMsg->buffer ) + { + free(NdefInfo.psUpperNdefMsg->buffer); + NdefInfo.psUpperNdefMsg->buffer = NULL; + } + status = NFCSTATUS_FAILED; + } +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_unlock(&SharedDataMutex); +#endif + return status; + +} +/******************************************************************************* +** +** Function Mfc_PresenceCheck +** +** Description It triggers receiving of the NDEF message from Mifare Classic Tag. +** +** +** Returns: +** NFCSTATUS_SUCCESS - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_PresenceCheck(void) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + if (gAuthCmdBuf.auth_status == TRUE) + { + EXTNS_SetCallBackFlag(FALSE); + status = nativeNfcExtns_doTransceive(gAuthCmdBuf.pauth_cmd->buffer, + gAuthCmdBuf.pauth_cmd->length); + if (status != NFCSTATUS_PENDING) + { + gAuthCmdBuf.auth_sent = FALSE; + status = NFCSTATUS_FAILED; + } + else + { + gAuthCmdBuf.auth_sent = TRUE; + status = NFCSTATUS_SUCCESS; + } + } + else + { + status = NFCSTATUS_NOT_ALLOWED; + } + NXPLOG_EXTNS_D("%s status = 0x%x", __FUNCTION__, status); + return status; +} +/******************************************************************************* +** +** Function Mfc_WriteNdef +** +** Description It triggers the NDEF data write to Mifare Classic Tag. +** +** +** Returns: +** NFCSTATUS_SUCCESS - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_WriteNdef(uint8_t *p_data, uint32_t len) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint8_t *PacketData = NULL; + uint32_t *PacketDataLength = NULL; + + if( p_data == NULL || len == 0 ) + { + NXPLOG_EXTNS_E("MFC Error: Invalid Parameters to Ndef Write"); + status = NFCSTATUS_FAILED; + goto Mfc_WrNdefEnd; + } + + EXTNS_SetCallBackFlag(FALSE); + gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; + gphNxpExtns_Context.CallBackCtxt = NdefMap; +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_lock(&SharedDataMutex); +#endif + if( NdefInfo.is_ndef == PH_LIBNFC_INTERNAL_CHK_NDEF_NOT_DONE ) + { + status = NFCSTATUS_REJECTED; + goto Mfc_WrNdefEnd; + } + else if( NdefInfo.is_ndef == 0 ) + { + status = NFCSTATUS_NON_NDEF_COMPLIANT; + goto Mfc_WrNdefEnd; + } + else if( len > NdefInfo.NdefLength ) + { + status = NFCSTATUS_NOT_ENOUGH_MEMORY; + goto Mfc_WrNdefEnd; + } + else + { + NdefInfo.psUpperNdefMsg->buffer = p_data; + NdefInfo.psUpperNdefMsg->length = len; + + NdefInfo.AppWrLength = len; + NdefMap->CompletionRoutine[2].CompletionRoutine = Mfc_WriteNdef_Completion_Routine; + if( 0 == len ) + { + /* TODO: Erase the Tag */ + } + else + { + NdefMap->ApduBuffIndex = 0x00; + *NdefMap->DataCount = 0x00; + PacketData = NdefInfo.psUpperNdefMsg->buffer; + PacketDataLength = &(NdefInfo.dwWrLength); + NdefMap->WrNdefPacketLength = PacketDataLength; + NdefInfo.dwWrLength = len; + + status = phFriNfc_ValidateParams (PacketData, PacketDataLength, 0, NdefMap, PH_FRINFC_NDEF_WRITE_REQ); + if( status != NFCSTATUS_SUCCESS ) + { + goto Mfc_WrNdefEnd; + } + + status = phFriNfc_MifareStdMap_WrNdef(NdefMap, PacketData, PacketDataLength, PH_FRINFC_NDEFMAP_SEEK_BEGIN); + + if ( status == NFCSTATUS_PENDING ) + { + status = NFCSTATUS_SUCCESS; + } + } + } + +Mfc_WrNdefEnd: +#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) + pthread_mutex_unlock(&SharedDataMutex); +#endif + if( status != NFCSTATUS_SUCCESS ) + { + status = NFCSTATUS_FAILED; + } + return status; +} +/******************************************************************************* +** +** Function phFriNfc_NdefSmtCrd_Reset__ +** +** Description This function Resets the component instance to the initial +** state and initializes the internal variables. +** +** Returns NFCSTATUS_SUCCESS +** +*******************************************************************************/ +STATIC NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, + uint8_t *SendRecvBuffer, + uint16_t *SendRecvBuffLen) +{ +// NFCSTATUS status = NFCSTATUS_FAILED; /*commented to eliminate unused variable warning*/ + uint8_t index; + + /* Initialize the state to Init */ + NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; + + for(index = 0;index<PH_FRINFC_SMTCRDFMT_CR;index++) + { + /* Initialize the NdefMap Completion Routine to Null */ + NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL; + /* Initialize the NdefMap Completion Routine context to Null */ + NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL; + } + + /* Trx Buffer registered */ + NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer; + + /* Trx Buffer Size */ + NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen; + + /* Register Transfer Buffer Length */ + NdefSmtCrdFmt->SendLength = 0; + + /* Initialize the Format status flag*/ + NdefSmtCrdFmt->FmtProcStatus = 0; + + /* Reset the Card Type */ + NdefSmtCrdFmt->CardType = 0; + + /* Reset MapCompletion Info*/ + NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL; + NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL; + + phFriNfc_MfStd_Reset(NdefSmtCrdFmt); + + return NFCSTATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function Mfc_FormatNdef +** +** Description It triggers the NDEF format of Mifare Classic Tag. +** +** +** Returns: +** NFCSTATUS_SUCCESS - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_FormatNdef(uint8_t *secretkey, uint8_t len) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + uint8_t mif_std_key[6] = {0}; +// static uint8_t Index; /*commented to eliminate unused variable warning*/ + uint8_t sak = 0; + + EXTNS_SetCallBackFlag(FALSE); + + memcpy(mif_std_key,secretkey,len); + memcpy(current_key,secretkey,len); + + if( NULL == NdefSmtCrdFmt || + NULL == NdefMap || NULL == NdefMap->SendRecvBuf ) + { + goto Mfc_FormatEnd; + } + NdefSmtCrdFmt->pTransceiveInfo = NdefMap->pTransceiveInfo; + + gphNxpExtns_Context.CallBackMifare = phFriNfc_MfStd_Process; + gphNxpExtns_Context.CallBackCtxt = NdefSmtCrdFmt; + + NdefInfo.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN; + phFriNfc_NdefSmtCrd_Reset__(NdefSmtCrdFmt, NdefMap->SendRecvBuf, &(NdefInfo.NdefSendRecvLen)); + + /* Register Callbacks */ + NdefSmtCrdFmt->CompletionRoutine[0].CompletionRoutine = Mfc_FormatNdef_Completion_Routine; + NdefSmtCrdFmt->CompletionRoutine[1].CompletionRoutine = Mfc_FormatNdef_Completion_Routine; + NdefSmtCrdFmt->psRemoteDevInfo = NdefMap->psRemoteDevInfo; + sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; + + if((0x08 == (sak & 0x18)) || (0x18 == (sak & 0x18)) || + (0x01 == sak)) + { + NdefSmtCrdFmt->CardType = (uint8_t) (((sak & 0x18) == 0x08)? + PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD:(((sak & 0x19) == 0x19)? + PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD: + PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)); + status = phFriNfc_MfStd_Format( NdefSmtCrdFmt, mif_std_key); + } + + if( NFCSTATUS_PENDING == status ) + { + status = NFCSTATUS_SUCCESS; + } + +Mfc_FormatEnd: + if( status != NFCSTATUS_SUCCESS ) + { + status = NFCSTATUS_FAILED; + } + + return status; +} + +/******************************************************************************* +** +** Function phNxNciExtns_MifareStd_Reconnect +** +** Description This function sends the deactivate command to NFCC for Mifare +** +** +** Returns: +** NFCSTATUS_PENDING - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS phNxNciExtns_MifareStd_Reconnect(void) +{ + tNFA_STATUS status; + + EXTNS_SetDeactivateFlag(TRUE); + if (NFA_STATUS_OK != (status = NFA_Deactivate (TRUE))) /* deactivate to sleep state */ + { + NXPLOG_EXTNS_E ("%s: deactivate failed, status = %d", __FUNCTION__, status); + return NFCSTATUS_FAILED; + } + + return NFCSTATUS_PENDING; + +} + +/******************************************************************************* +** +** Function Mfc_DeactivateCbackSelect +** +** Description This function select the Mifare tag +** +** +** Returns: void +** +*******************************************************************************/ +void Mfc_DeactivateCbackSelect(void) +{ + tNFA_STATUS status; + + EXTNS_SetConnectFlag(TRUE); + if (NFA_STATUS_OK != (status = NFA_Select (0x01, phNciNfc_e_RfProtocolsMifCProtocol, + phNciNfc_e_RfInterfacesTagCmd_RF))) + { + NXPLOG_EXTNS_E ("%s: NFA_Select failed, status = %d", __FUNCTION__, status); + } + + return; +} + +/******************************************************************************* +** +** Function Mfc_ActivateCback +** +** Description This function invoke the callback when receive the response +** +** +** Returns: void +** +** +*******************************************************************************/ +void Mfc_ActivateCback(void) +{ + gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt, NFCSTATUS_SUCCESS); + return; +} + +/******************************************************************************* +** +** Function Mfc_Transceive +** +** Description Sends raw frame to Mifare Classic Tag. +** +** Returns NFCSTATUS_SUCCESS - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_Transceive(uint8_t *p_data, uint32_t len) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + uint8_t i = 0x00; + + gphNxpExtns_Context.RawWriteCallBack = FALSE; + gphNxpExtns_Context.CallBackMifare = NULL; + gphNxpExtns_Context.CallBackCtxt = NdefMap; + + EXTNS_SetCallBackFlag(TRUE); + if( p_data[0] == 0x60 || p_data[0] == 0x61 ) + { + + NdefMap->Cmd.MfCmd = p_data[0]; + + NdefMap->SendRecvBuf[i++] = p_data[1]; + + NdefMap->SendRecvBuf[i++] = p_data[6]; /* TODO, handle 7 byte UID */ + NdefMap->SendRecvBuf[i++] = p_data[7]; + NdefMap->SendRecvBuf[i++] = p_data[8]; + NdefMap->SendRecvBuf[i++] = p_data[9]; + NdefMap->SendRecvBuf[i++] = p_data[10]; + NdefMap->SendRecvBuf[i++] = p_data[11]; + + status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + else if( p_data[0] == 0xA0 ) + { + EXTNS_SetCallBackFlag(FALSE); + NdefMap->Cmd.MfCmd = phNfc_eMifareWrite16; + gphNxpExtns_Context.RawWriteCallBack = TRUE; + + memcpy(NdefMap->SendRecvBuf, &p_data[1], len-1); + NdefMap->SendLength = len-1; + status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + else if( (p_data[0] == phNfc_eMifareInc) || (p_data[0] == phNfc_eMifareDec) ) + { + + EXTNS_SetCallBackFlag(FALSE); + NdefMap->Cmd.MfCmd = p_data[0]; + gphNxpExtns_Context.RawWriteCallBack = TRUE; + + memcpy(NdefMap->SendRecvBuf, &p_data[1], len-1); + NdefMap->SendLength = len - 1; + status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + else if( ((p_data[0] == phNfc_eMifareTransfer) || (p_data[0] == phNfc_eMifareRestore)) && (len == 2) ) + { + NdefMap->Cmd.MfCmd = p_data[0]; + if ((p_data[0] == phNfc_eMifareRestore)) + { + EXTNS_SetCallBackFlag(FALSE); + gphNxpExtns_Context.RawWriteCallBack = TRUE; + memcpy(NdefMap->SendRecvBuf, &p_data[1], len -1); + NdefMap->SendLength = len - 1; + } + else + { + memcpy(NdefMap->SendRecvBuf, p_data, len); + NdefMap->SendLength = len; + } + status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + + } + else + { + NdefMap->Cmd.MfCmd = phNfc_eMifareRaw; + + memcpy(NdefMap->SendRecvBuf, p_data, len); + NdefMap->SendLength = len; + status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, + NdefMap->Cmd, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvLength); + } + if (NFCSTATUS_PENDING == status) + { + status = NFCSTATUS_SUCCESS; + } + else + { + NXPLOG_EXTNS_E("ERROR: Mfc_Transceive = 0x%x", status); + } + + return status; +} + +/******************************************************************************* +** +** Function nativeNfcExtns_doTransceive +** +** Description Sends raw frame to BCM stack. +** +** Returns NFCSTATUS_PENDING - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS nativeNfcExtns_doTransceive(uint8_t *buff, uint16_t buffSz) +{ + NFCSTATUS wStatus = NFCSTATUS_PENDING; + tNFA_STATUS status = NFA_SendRawFrame (buff, buffSz, NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY); + + if (status != NFA_STATUS_OK) + { + NXPLOG_EXTNS_E ("%s: fail send; error=%d", __FUNCTION__, status); + wStatus = NFCSTATUS_FAILED; + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phNciNfc_RecvMfResp +** +** Description This function shall be invoked as part of ReaderMgmt data +** exchange sequence handler on receiving response/data from NFCC +** +** Returns NFCSTATUS_SUCCESS - Data Reception is successful +** NFCSTATUS_FAILED - Data Reception failed +** +*******************************************************************************/ +STATIC NFCSTATUS +phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo, + NFCSTATUS wStatus + ) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint16_t wPldDataSize = 0; + phNciNfc_ExtnRespId_t RecvdExtnRspId = phNciNfc_e_InvalidRsp; + uint16_t wRecvDataSz = 0; + + if(NULL == RspBuffInfo) + { + status = NFCSTATUS_FAILED; + } + else + { + if((0 == (RspBuffInfo->wLen)) + || (PH_NCINFC_STATUS_OK != wStatus) + || (NULL == (RspBuffInfo->pBuff)) + ) + { + status = NFCSTATUS_FAILED; + } + else + { + RecvdExtnRspId = (phNciNfc_ExtnRespId_t)RspBuffInfo->pBuff[0]; + + switch(RecvdExtnRspId) + { + case phNciNfc_e_MfXchgDataRsp: + { + /* check the status byte */ + if( PH_NCINFC_STATUS_OK == RspBuffInfo->pBuff[RspBuffInfo->wLen-1] ) + { + status = NFCSTATUS_SUCCESS; + + /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */ + wPldDataSize = ((RspBuffInfo->wLen) - + (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE)); + wRecvDataSz = NCI_MAX_DATA_LEN; + + /* wPldDataSize = wPldDataSize-1; ==> ignoring the last status byte appended with data */ + if((wPldDataSize) <= wRecvDataSz) + { + /* Extract the data part from pBuff[2] & fill it to be sent to upper layer */ + memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[1]),(wPldDataSize)); + /* update the number of bytes received from lower layer,excluding the status byte */ + *(NdefMap->SendRecvLength) = wPldDataSize; + } + else + { + //TODO:- Map some status for remaining extra data received to be sent back to caller?? + status = NFCSTATUS_FAILED; + } + } + else + { + status = NFCSTATUS_FAILED; + } + } + break; + + case phNciNfc_e_MfcAuthRsp: + { + /* check the status byte */ + if(PH_NCINFC_STATUS_OK == RspBuffInfo->pBuff[1]) + { + if (gAuthCmdBuf.auth_sent == TRUE) + { + MfcPresenceCheckResult(NFCSTATUS_SUCCESS); + return NFCSTATUS_SUCCESS; + } + gAuthCmdBuf.auth_status = TRUE; + status = NFCSTATUS_SUCCESS; + + /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */ + wPldDataSize = ((RspBuffInfo->wLen) - + (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE)); + + /* Extract the data part from pBuff[2] & fill it to be sent to upper layer */ + memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[2]),wPldDataSize); + /* update the number of bytes received from lower layer,excluding the status byte */ + *(NdefMap->SendRecvLength) = wPldDataSize; + } + else + { + if (gAuthCmdBuf.auth_sent == TRUE) + { + gAuthCmdBuf.auth_status = FALSE; + MfcPresenceCheckResult(NFCSTATUS_FAILED); + return NFCSTATUS_SUCCESS; + } + else + { + /* Reset the stored auth command buffer */ + memset(gAuthCmdBuf.pauth_cmd->buffer, 0 , NCI_MAX_DATA_LEN); + gAuthCmdBuf.pauth_cmd->length = 0; + gAuthCmdBuf.auth_status = FALSE; + } + status = NFCSTATUS_FAILED; + } + } + break; + + default: + { + status = NFCSTATUS_FAILED; + } + break; + } + } + } + + return status; +} + +/******************************************************************************* +** +** Function phLibNfc_SendWrt16CmdPayload +** +** Description This function map the raw write cmd +** +** Returns NFCSTATUS_SUCCESS - Command framing done +** NFCSTATUS_INVALID_PARAMETER - Otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_SendWrt16CmdPayload(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf) +{ + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if( (NULL != pTransceiveInfo->sSendData.buffer) && + (0 != (pTransceiveInfo->sSendData.length))) + { + memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer, + (pTransceiveInfo->sSendData.length)); + pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; + } + else + { + wStatus = NFCSTATUS_INVALID_PARAMETER; + } + + if ( gphNxpExtns_Context.RawWriteCallBack == TRUE ) + { + EXTNS_SetCallBackFlag(TRUE); + gphNxpExtns_Context.RawWriteCallBack = FALSE; + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phLibNfc_SendIncDecCmdPayload +** +** Description This function prepares the Increment/Decrement Value to be +** sent. This is called after sending the Increment/Decrement +** command is already sent and successfull +** +** Returns NFCSTATUS_SUCCESS - Payload framing done +** NFCSTATUS_INVALID_PARAMETER - Otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_SendIncDecCmdPayload(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf) +{ + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if( (NULL != pTransceiveInfo->sSendData.buffer) && + (0 != (pTransceiveInfo->sSendData.length))) + { + memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer, + (pTransceiveInfo->sSendData.length)); + pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; + } + else + { + wStatus = NFCSTATUS_INVALID_PARAMETER; + } + + if ( gphNxpExtns_Context.RawWriteCallBack == TRUE ) + { + EXTNS_SetCallBackFlag(TRUE); + gphNxpExtns_Context.RawWriteCallBack = FALSE; + } + + return wStatus; +} + +/******************************************************************************* +** +** Function Mfc_RecvPacket +** +** Description Decodes Mifare Classic Tag Response +** This is called from NFA_SendRaw Callback +** +** Returns: +** NFCSTATUS_SUCCESS - if successfully initiated +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +NFCSTATUS Mfc_RecvPacket(uint8_t *buff, uint8_t buffSz) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + phNciNfc_Buff_t RspBuff; + uint8_t *pcmd_buff; + uint16_t buffSize; + + RspBuff.pBuff = buff; + RspBuff.wLen = buffSz; + status = phNciNfc_RecvMfResp(&RspBuff, status); + if (TRUE == gAuthCmdBuf.auth_sent) + { + ALOGD("%s Mfc Check Presnece in progress", __FUNCTION__); + gAuthCmdBuf.auth_sent = FALSE; + return status; + } + if( TRUE == gphNxpExtns_Context.writecmdFlag && (NFCSTATUS_SUCCESS == status )) + { + pcmd_buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); + if( NULL == pcmd_buff ) + { + return NFCSTATUS_FAILED; + } + buffSize = MAX_BUFF_SIZE; + gphNxpExtns_Context.writecmdFlag = FALSE; + phLibNfc_SendWrt16CmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo); + status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize); + if ( NFCSTATUS_PENDING != status ) + { + NXPLOG_EXTNS_E("ERROR : Mfc_RecvPacket: 0x%x", status); + } + else + { + status = NFCSTATUS_SUCCESS; + } + if( pcmd_buff != NULL ) + { + free(pcmd_buff); + pcmd_buff = NULL; + } + } + else if( TRUE == gphNxpExtns_Context.incrdecflag && (NFCSTATUS_SUCCESS == status )) + { + pcmd_buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); + if( NULL == pcmd_buff ) + { + return NFCSTATUS_FAILED; + } + buffSize = MAX_BUFF_SIZE; + gphNxpExtns_Context.incrdecflag = FALSE; + phLibNfc_SendIncDecCmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo); + status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize); + if ( NFCSTATUS_PENDING != status ) + { + NXPLOG_EXTNS_E("ERROR : Mfc_RecvPacket: 0x%x", status); + } + else + { + status = NFCSTATUS_SUCCESS; + } + gphNxpExtns_Context.incrdecstatusflag = TRUE; + if( pcmd_buff != NULL ) + { + free(pcmd_buff); + pcmd_buff = NULL; + } + + } + else + { + if( gphNxpExtns_Context.CallBackMifare != NULL ) + { + if( (gphNxpExtns_Context.incrdecstatusflag == TRUE) && status == 0xB2 ) + { + gphNxpExtns_Context.incrdecstatusflag = FALSE; + status = NFCSTATUS_SUCCESS; + } + gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt, status); + } + } + + return status; +} + +/******************************************************************************* +** +** Function phNciNfc_MfCreateXchgDataHdr +** +** Description This function builds the payload header for mifare XchgData +** request to be sent to NFCC. +** +** Returns NFCSTATUS_PENDING - Command framing done +** NFCSTATUS_FAILED - Otherwise +** +*******************************************************************************/ +STATIC +NFCSTATUS +phNciNfc_MfCreateXchgDataHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, + uint8_t *buff, uint16_t *buffSz) + +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint8_t i = 0; + + buff[i++] = phNciNfc_e_MfRawDataXchgHdr; + memcpy(&buff[i],tTranscvInfo.tSendData.pBuff,tTranscvInfo.tSendData.wLen); + *buffSz = i + tTranscvInfo.tSendData.wLen; + + status = nativeNfcExtns_doTransceive(buff, (uint16_t) *buffSz); + + return status; +} + +/******************************************************************************* +** +** Function phNciNfc_MfCreateAuthCmdHdr +** +** Description This function builds the payload header for mifare +** classic Authenticate command to be sent to NFCC. +** +** Returns NFCSTATUS_PENDING - Command framing done +** NFCSTATUS_FAILED - Otherwise +** +*******************************************************************************/ +STATIC +NFCSTATUS +phNciNfc_MfCreateAuthCmdHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, + uint8_t bBlockAddr, + uint8_t *buff, + uint16_t *buffSz) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; +// pphNciNfc_RemoteDevInformation_t pActivDev = NULL; /*commented to eliminate unused variable warning*/ + uint8_t bKey = 0x00; + + /*No need to check range of block address*/ + /*To check for Authenticate A or Authenticate B type command*/ + if(PHNCINFC_AUTHENTICATION_KEYB == + tTranscvInfo.tSendData.pBuff[0] ) + { + bKey = bKey | PHNCINFC_ENABLE_KEY_B; + } + + /*TO Do last 4 bits of Key to be set based of firmware implementation*/ + /*this value is hardcoded but based on firmware implementation change this value*/ + bKey = (bKey | PHNCINFC_AUTHENTICATION_KEY); + + bKey |= tTranscvInfo.tSendData.pBuff[2]; + + /*For authentication extension no need to copy tSendData buffer of tTranscvInfo */ + tTranscvInfo.tSendData.wLen = 0x00; + + buff[0] = phNciNfc_e_MfcAuthReq; + buff[1] = bBlockAddr; + buff[2] = bKey; + + *buffSz = 0x03; + if (bKey & PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY) + { + memcpy(&buff[3],&tTranscvInfo.tSendData.pBuff[3], PHLIBNFC_MFC_AUTHKEYLEN); + *buffSz += PHLIBNFC_MFC_AUTHKEYLEN; + } + /* Store the auth command buffer to use further for presence check */ + if (gAuthCmdBuf.pauth_cmd != NULL) + { + memset(gAuthCmdBuf.pauth_cmd->buffer, 0, NCI_MAX_DATA_LEN); + gAuthCmdBuf.pauth_cmd->length = *buffSz; + memcpy(gAuthCmdBuf.pauth_cmd->buffer, buff, *buffSz); + } + status = nativeNfcExtns_doTransceive(buff,(uint16_t) *buffSz); + + return status; +} + +/******************************************************************************* +** +** Function phNciNfc_SendMfReq +** +** Description This function shall be invoked as part of ReaderMgmt data +** exchange sequence handler. +** It shall send the request packet to NFCC. +** +** Returns NFCSTATUS_PENDING - Send request is Pending +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS +phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo, uint8_t *buff, uint16_t *buffSz) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + switch(tTranscvInfo.uCmd.T2TCmd) + { + case phNciNfc_eT2TRaw: + { + status = phNciNfc_MfCreateXchgDataHdr(tTranscvInfo, buff, buffSz); + } + break; + case phNciNfc_eT2TAuth: + { + status = phNciNfc_MfCreateAuthCmdHdr(tTranscvInfo, + (tTranscvInfo.bAddr), buff, buffSz); + } + break; + default: + { + status = NFCSTATUS_FAILED; + break; + } + } + + return status; +} + +/******************************************************************************* +** +** Function phLibNfc_CalSectorAddress +** +** Description This function update the sector address for Mifare classic +** +** Returns none +** +*******************************************************************************/ +STATIC void phLibNfc_CalSectorAddress(uint8_t *Sector_Address) +{ + uint8_t BlockNumber = 0x00; + + if(NULL != Sector_Address) + { + BlockNumber = *Sector_Address; + if(BlockNumber >= PHLIBNFC_MIFARESTD4K_BLK128) + { + *Sector_Address = (uint8_t)(PHLIBNFC_MIFARESTD_SECTOR_NO32 + + ((BlockNumber - PHLIBNFC_MIFARESTD4K_BLK128)/ + PHLIBNFC_MIFARESTD_BLOCK_BYTES)); + } + else + { + *Sector_Address = BlockNumber/PHLIBNFC_NO_OF_BLKPERSECTOR; + } + } + else + { + } + + return; +} + +/******************************************************************************* +** +** Function phLibNfc_GetKeyNumberMFC +** +** Description This function find key number based on authentication command +** +** Returns NFCSTATUS_SUCCESS - If found the key number +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t *buffer,uint8_t *bKey) +{ + int32_t sdwStat = 0X00; + NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER; + + /*Key Configuration + uint8_t NdefKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xD3,0XF7,0xD3,0XF7,0xD3,0XF7}; + uint8_t RawKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xFF,0XFF,0xFF,0XFF,0xFF,0XFF}; + uint8_t MadKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xA0,0XA1,0xA2,0XA3,0xA4,0XA5}; + uint8_t Key[PHLIBNFC_MFC_AUTHKEYLEN] = {0x00,0x00,0x00,0x00,0x00,0x00}; */ /*Key used during ndef format*/ + + uint8_t bIndex = 0x00; + uint8_t bNoOfKeys = 0x00; + +#if PHLIBNFC_NXPETENSION_CONFIGURE_MFKEYS + uint8_t aMfc_keys[NXP_NUMBER_OF_MFC_KEYS][NXP_MFC_KEY_SIZE] = NXP_MFC_KEYS; +#else + uint8_t aMfc_keys[1][1] = {{0x00}}; +#endif + + if(NULL != bKey && + NULL != buffer ) + { + bNoOfKeys = sizeof(aMfc_keys)/NXP_MFC_KEY_SIZE; + /* Traverse through the keys stored to determine whether keys is preloaded key */ + for(bIndex = 0; bIndex < bNoOfKeys; bIndex++) + { + /* Check passed key is NDEF key */ + sdwStat = memcmp(&buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD], + aMfc_keys[bIndex], PHLIBNFC_MFC_AUTHKEYLEN); + if(!sdwStat) + { + NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC Key found"); + *bKey = bIndex; + wStatus = NFCSTATUS_SUCCESS; + break; + } + } + NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x Key = 0x%x", wStatus, *bKey); + } + else + { + wStatus = NFCSTATUS_FAILED; + NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x", wStatus); + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phLibNfc_ChkAuthCmdMFC +** +** Description This function Check Authentication command send is proper or not +** +** Returns NFCSTATUS_SUCCESS - Authenticate command is proper +** NFCSTATUS_FAILED - otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_ChkAuthCmdMFC(phNfc_sTransceiveInfo_t* pTransceiveInfo, + uint8_t *bKey) +{ + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + if(NULL != pTransceiveInfo && + NULL != pTransceiveInfo->sSendData.buffer && + 0 != pTransceiveInfo->sSendData.length && + NULL != bKey) + { + if((pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentA || + pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentB )) + { + wStatus = phLibNfc_GetKeyNumberMFC(pTransceiveInfo->sSendData.buffer,bKey); + } + else + { + wStatus = NFCSTATUS_FAILED; + } + }else + { + wStatus = NFCSTATUS_FAILED; + } + return wStatus; +} + +/******************************************************************************* +** +** Function phLibNfc_MifareMap +** +** Description Mifare Mapping Utility function +** +** Returns NFCSTATUS_SUCCESS - Mapping is proper +** NFCSTATUS_INVALID_PARAMETER - otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_MifareMap(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + uint8_t bBuffIdx = 0; + uint8_t bSectorNumber; + uint8_t bKey = 0; + + switch(pTransceiveInfo->cmd.MfCmd) + { + case phNfc_eMifareRead16: + { + if( (NULL != pTransceiveInfo->sRecvData.buffer) && + (0 != (pTransceiveInfo->sRecvData.length))) + { + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareRead16; + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; + pMappedTranscvIf->tSendData.wLen = bBuffIdx; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; + } + else + { + status = NFCSTATUS_INVALID_PARAMETER; + } + } + break; + + case phNfc_eMifareWrite16: + { + if( (NULL != pTransceiveInfo->sSendData.buffer) && + (0 != (pTransceiveInfo->sSendData.length))) + { + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16; + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; + memcpy(&(pMappedTranscvIf->tSendData.pBuff[bBuffIdx]),pTransceiveInfo->sSendData.buffer, + (pTransceiveInfo->sSendData.length)); + pMappedTranscvIf->tSendData.wLen = bBuffIdx + pTransceiveInfo->sSendData.length; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; + } + else + { + status = NFCSTATUS_INVALID_PARAMETER; + } + } + break; + + case phNfc_eMifareAuthentA: + case phNfc_eMifareAuthentB: + { + if( (NULL != pTransceiveInfo->sSendData.buffer) && + (0 != (pTransceiveInfo->sSendData.length)) && + (NULL != pTransceiveInfo->sRecvData.buffer) && + (0 != (pTransceiveInfo->sRecvData.length)) + ) + { + status = phLibNfc_ChkAuthCmdMFC(pTransceiveInfo, &bKey); + if(NFCSTATUS_FAILED != status ) + { + bSectorNumber = pTransceiveInfo->addr; + phLibNfc_CalSectorAddress(&bSectorNumber); + /*For creating extension command header pTransceiveInfo's MfCmd get used*/ + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->cmd.MfCmd; + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bSectorNumber; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TAuth; + pMappedTranscvIf->bAddr = bSectorNumber; + pMappedTranscvIf->bNumBlock = pTransceiveInfo->NumBlock; + if(NFCSTATUS_SUCCESS == status) + { + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey; + (pMappedTranscvIf->tSendData.wLen) = (uint16_t)(bBuffIdx); + + } + else if(NFCSTATUS_INVALID_PARAMETER == status) + { + bKey = bKey | PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY; + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey; + memcpy(&pMappedTranscvIf->tSendData.pBuff[bBuffIdx], + &pTransceiveInfo->sSendData.buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD], PHLIBNFC_MFC_AUTHKEYLEN); + + (pMappedTranscvIf->tSendData.wLen) = (uint16_t)(bBuffIdx + PHLIBNFC_MFC_AUTHKEYLEN); + status = NFCSTATUS_SUCCESS; + } + else + { + /* do nothing */ + } + } + } + else + { + status = NFCSTATUS_INVALID_PARAMETER; + } + } + break; + + case phNfc_eMifareRaw: + { + + } + break; + + default: + { + status = NFCSTATUS_INVALID_PARAMETER; + break; + } + } + + return status; +} + +/******************************************************************************* +** +** Function phLibNfc_MapCmds +** +** Description This function maps the command request from libnfc level to nci level +** +** Returns NFCSTATUS_SUCCESS - Mapping of command is successful +** NFCSTATUS_INVALID_PARAMETER - One or more of the supplied +** parameters could not be interpreted properly +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t RemDevType, + phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf) +{ + + NFCSTATUS status = NFCSTATUS_SUCCESS; + + if((NULL == pTransceiveInfo) || (NULL == pMappedTranscvIf)) + { + return NFCSTATUS_FAILED; + } + switch(RemDevType) + { + case phNciNfc_eMifare1k_PICC: + case phNciNfc_eMifare4k_PICC: + { + status = phLibNfc_MifareMap(pTransceiveInfo,pMappedTranscvIf); + break; + } + default: + { + break; + } + } + + return status; +} + +/******************************************************************************* +** +** Function phLibNfc_SendAuthCmd +** +** Description This function Send authentication command to NFCC +** +** Returns NFCSTATUS_SUCCESS - Parameters are proper +** NFCSTATUS_INVALID_PARAMETER - Otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_SendAuthCmd(phNfc_sTransceiveInfo_t *pTransceiveInfo, + phNciNfc_TransceiveInfo_t *tNciTranscvInfo) +{ + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + + wStatus = phLibNfc_MapCmds(phNciNfc_eMifare1k_PICC, pTransceiveInfo, tNciTranscvInfo); + + return wStatus; +} + +/******************************************************************************* +** +** Function phLibNfc_SendWrt16Cmd +** +** Description This function maps Mifarewirte16 commands +** +** Returns NFCSTATUS_SUCCESS - Parameters are mapped +** NFCSTATUS_INVALID_PARAMETER - Otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_SendWrt16Cmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf) +{ + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t bBuffIdx = 0x00; + + if( (NULL != pTransceiveInfo->sSendData.buffer) && + (0 != (pTransceiveInfo->sSendData.length))) + { + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16; + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; + pMappedTranscvIf->tSendData.wLen = bBuffIdx; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; + } + else + { + wStatus = NFCSTATUS_INVALID_PARAMETER; + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phLibNfc_SendIncDecCmd +** +** Description This function prepares the Increment/Decrement command +** to be sent, increment/decrement value is sent separately +** +** Returns NFCSTATUS_SUCCESS - Params are mapped +** NFCSTATUS_INVALID_PARAMETER - Otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_SendIncDecCmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf, + uint8_t IncDecCmd) +{ + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; + uint8_t bBuffIdx = 0x00; + + if( (NULL != pTransceiveInfo->sSendData.buffer) && + (0 != (pTransceiveInfo->sSendData.length))) + { + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = IncDecCmd; + pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; + pMappedTranscvIf->tSendData.wLen = bBuffIdx; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; + } + else + { + wStatus = NFCSTATUS_INVALID_PARAMETER; + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phLibNfc_SendRawCmd +** +** Description This function maps Mifare raw command +** +** Returns NFCSTATUS_SUCCESS - Parameters are mapped +** NFCSTATUS_INVALID_PARAMETER - Otherwise +** +*******************************************************************************/ +STATIC NFCSTATUS phLibNfc_SendRawCmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, + pphNciNfc_TransceiveInfo_t pMappedTranscvIf) +{ + NFCSTATUS wStatus = NFCSTATUS_SUCCESS; +// uint8_t bBuffIdx = 0x00; /*commented to eliminate unused variable warning*/ + + if( (NULL != pTransceiveInfo->sSendData.buffer) && + (0 != (pTransceiveInfo->sSendData.length))) + { + memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer, + (pTransceiveInfo->sSendData.length)); + pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length; + pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; + } + else + { + wStatus = NFCSTATUS_INVALID_PARAMETER; + } + + return wStatus; +} + +/******************************************************************************* +** +** Function phFriNfc_ExtnsTransceive +** +** Description This function maps Mifare raw command and send it to NFCC +** +** Returns NFCSTATUS_PENDING - Operation successful +** NFCSTATUS_INVALID_PARAMETER - Otherwise +** +*******************************************************************************/ +NFCSTATUS phFriNfc_ExtnsTransceive(phNfc_sTransceiveInfo_t *pTransceiveInfo, + phNfc_uCmdList_t Cmd, + uint8_t *SendRecvBuf, + uint16_t SendLength, + uint16_t *SendRecvLength) +{ + (void)SendRecvLength; + NFCSTATUS status = NFCSTATUS_FAILED; + uint8_t *buff=NULL; + uint16_t buffSz=0; + uint8_t i = 0; + uint32_t length = SendLength; + uint8_t restore_payload[]={0x00, 0x00, 0x00, 0x00,}; + + buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); + if( NULL == buff ) + { + return status; + } + + pTransceiveInfo->cmd = Cmd; + + if( (Cmd.MfCmd == phNfc_eMifareAuthentA) || + (Cmd.MfCmd == phNfc_eMifareAuthentB) ) + { + pTransceiveInfo->addr = SendRecvBuf[i++]; + pTransceiveInfo->sSendData.buffer[4] = SendRecvBuf[i++]; + pTransceiveInfo->sSendData.buffer[5] = SendRecvBuf[i++]; + pTransceiveInfo->sSendData.buffer[6] = SendRecvBuf[i++]; + pTransceiveInfo->sSendData.buffer[7] = SendRecvBuf[i++]; + pTransceiveInfo->sSendData.buffer[8] = SendRecvBuf[i++]; + pTransceiveInfo->sSendData.buffer[9] = SendRecvBuf[i++]; + + pTransceiveInfo->cmd.MfCmd = Cmd.MfCmd; + + pTransceiveInfo->sSendData.length = length; + pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; + status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo); + } + else if( Cmd.MfCmd == phNfc_eMifareWrite16 ) + { + pTransceiveInfo->addr = SendRecvBuf[i++]; + length = SendLength - i; + memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length); + pTransceiveInfo->sSendData.length = length; + pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; + + gphNxpExtns_Context.writecmdFlag = TRUE; + + status = phLibNfc_SendWrt16Cmd(pTransceiveInfo, &tNciTranscvInfo); + } + else if( (Cmd.MfCmd == phNfc_eMifareInc) || (Cmd.MfCmd == phNfc_eMifareDec) ) + { + pTransceiveInfo->addr = SendRecvBuf[i++]; + length = SendLength - i; + memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length); + pTransceiveInfo->sSendData.length = length; + pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; + + gphNxpExtns_Context.incrdecflag = TRUE; + + status = phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd); + + } + else if( (Cmd.MfCmd == phNfc_eMifareRestore ) ) + { + pTransceiveInfo->addr = SendRecvBuf[i++]; + length = SendLength - i; + memcpy(pTransceiveInfo->sSendData.buffer, &restore_payload[0], sizeof(restore_payload)); + pTransceiveInfo->sSendData.length = length + sizeof(restore_payload); + pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; + + gphNxpExtns_Context.incrdecflag = TRUE; + + status = phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd); + + } + else if ((Cmd.MfCmd == phNfc_eMifareRaw) || (Cmd.MfCmd == phNfc_eMifareTransfer )) + { + pTransceiveInfo->cmd.MfCmd = phNciNfc_eT2TRaw; + memcpy(pTransceiveInfo->sSendData.buffer, SendRecvBuf, length); + pTransceiveInfo->sSendData.length = length; + pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; + status = phLibNfc_SendRawCmd(pTransceiveInfo, &tNciTranscvInfo); + } + else + { + pTransceiveInfo->addr = SendRecvBuf[i++]; + length = SendLength - i; + memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length); + pTransceiveInfo->sSendData.length = length; + pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; + status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo); + } + + if (NFCSTATUS_SUCCESS == status ) + { + status = phNciNfc_SendMfReq(tNciTranscvInfo, buff, &buffSz); + if (NFCSTATUS_PENDING != status) + { + NXPLOG_EXTNS_E("ERROR : phNciNfc_SendMfReq()"); + } + } + else + { + NXPLOG_EXTNS_E (" ERROR : Sending phNciNfc_SendMfReq"); + } + if( buff != NULL ) + { + free(buff); + buff = NULL; + } + + return status; +} diff --git a/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.h b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.h new file mode 100755 index 00000000..0ed0fe96 --- /dev/null +++ b/nci/jni/extns/pn54x/src/mifare/phNxpExtns_MifareStd.h @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef _PHNXPEXTNS_MFCRF_H_ +#define _PHNXPEXTNS_MFCRF_H_ + +#include <phNfcTypes.h> +#include <phNciNfcTypes.h> +#include <phFriNfc_MifareStdMap.h> +#include <phFriNfc_MifStdFormat.h> +#include <phNxpExtns.h> +#include <semaphore.h> +#include <pthread.h> + +extern UINT8 current_key[]; +/* Enable this macro to set key configuration for mifare classic Tag */ +#define PHLIBNFC_NXPETENSION_CONFIGURE_MFKEYS 1 + +#define MAX_BUFF_SIZE (512) + +#define PHLIBNFC_MIFARESTD4K_BLK128 128 /*Block number 128 for Mifare 4k */ +#define PHLIBNFC_MIFARESTD_SECTOR_NO32 32 /* Sector 32 for Mifare 4K*/ +#define PHLIBNFC_MIFARESTD_BLOCK_BYTES 16 /* Bytes per block after block 32 for Mifare 4K*/ + +#define PHLIBNFC_NO_OF_BLKPERSECTOR (0x04) /* Number of blocks per sector for \ + * Mifare Clsssic Tag*/ + +#define PHLIBNFC_MFCUIDLEN_INAUTHCMD 0x04 /* UID length in Authentication command */ +#define PHLIBNFC_MFC_AUTHKEYLEN 0x06 /* Authentication key length */ + +#define PHNCINFC_AUTHENTICATION_KEY (0x00U) /* Authentication key passed in extension \ + command header of authentication command */ +#define PHNCINFC_AUTHENTICATION_KEYB (0x61U) /* Authentication Key B */ +#define PHNCINFC_ENABLE_KEY_B (0x80U) /* Enable Key B */ +#define PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY (0x10) /* MIFARE Classic use Embedded Key*/ + +#define PH_NCINFC_STATUS_OK (0x0000) /* Status OK */ +#define PHNCINFC_EXTNID_SIZE (0x01U) /* Size of Mifare Extension Req/Rsp Id */ +#define PHNCINFC_EXTNSTATUS_SIZE (0x01U) /* Size of Mifare Extension Resp Status Byte */ + +#define PH_NCINFC_EXTN_INVALID_PARAM_VAL (0xFFU) /* Initial value of Req/Resp Param/Status */ + +#define PH_FRINFC_NDEF_READ_REQ (0x00U) /* NDEF Read Request */ +#define PH_FRINFC_NDEF_WRITE_REQ (0x01U) /* NDEF Write Request */ + +#define PH_LIBNFC_INTERNAL_CHK_NDEF_NOT_DONE (0x02U) /* Status for check NDEF not done */ + +#define NDEF_SENDRCV_BUF_LEN 252U /* Send receive buffer length */ + +#define NXP_NUMBER_OF_MFC_KEYS (0x04U) +#define NXP_MFC_KEY_SIZE (0x06U) + +#define NXP_MFC_KEYS {\ + {0xA0,0XA1,0xA2,0XA3,0xA4,0XA5},\ + {0xD3,0XF7,0xD3,0XF7,0xD3,0XF7},\ + {0xFF,0XFF,0xFF,0XFF,0xFF,0XFF},\ + {0x00,0x00,0x00,0x00,0x00,0x00}} /* Key used during NDEF format */ + + +#ifndef NCI_MAX_DATA_LEN +#define NCI_MAX_DATA_LEN 300 +#endif + +/* + * Request Id for different commands + */ +typedef enum phNciNfc_ExtnReqId +{ + phNciNfc_e_T1TXchgDataReq = 0x10, /* T1T Raw Data Request from DH */ + phNciNfc_e_T1TWriteNReq = 0x20, /* T1T N bytes write request from DH */ + phNciNfc_e_MfRawDataXchgHdr = 0x10, /* MF Raw Data Request from DH */ + phNciNfc_e_MfWriteNReq = 0x31, /* MF N bytes write request from DH */ + phNciNfc_e_MfReadNReq = 0x32, /* MF N bytes read request from DH */ + phNciNfc_e_MfSectorSelReq = 0x33, /* MF Block select request from DH */ + phNciNfc_e_MfPlusProxCheckReq = 0x28, /* MF + Prox check request for NFCC from DH */ + phNciNfc_e_MfcAuthReq = 0x40, /* MFC Authentication request for NFCC from DH */ + phNciNfc_e_InvalidReq /* Invalid ReqId */ +} phNciNfc_ExtnReqId_t ; + +/* + * Response Ids for different command response + */ +typedef enum phNciNfc_ExtnRespId +{ + phNciNfc_e_T1TXchgDataRsp = 0x10, /* DH gets Raw data from T1T on successful req */ + phNciNfc_e_T1TWriteNRsp = 0x20, /* DH gets write status */ + phNciNfc_e_MfXchgDataRsp = 0x10, /* DH gets Raw data from MF on successful req */ + phNciNfc_e_MfWriteNRsp = 0x31, /* DH gets write status */ + phNciNfc_e_MfReadNRsp = 0x32, /* DH gets N Bytes read from MF, if successful */ + phNciNfc_e_MfSectorSelRsp = 0x33, /* DH gets the Sector Select cmd status */ + phNciNfc_e_MfPlusProxCheckRsp = 0x29, /* DH gets the MF+ Prox Check cmd status */ + phNciNfc_e_MfcAuthRsp = 0x40, /* DH gets the authenticate cmd status */ + phNciNfc_e_InvalidRsp /* Invalid RspId */ +}phNciNfc_ExtnRespId_t ; + +/* Data buffer */ +typedef struct phNciNfc_Buff +{ + uint8_t *pBuff; /* pointer to the buffer where received payload shall be stored*/ + uint16_t wLen; /* Buffer length*/ +}phNciNfc_Buff_t, *pphNciNfc_Buff_t; + +/* + * Structure for NCI Extension information + */ +typedef struct phNciNfc_ExtnInfo +{ + union + { + phNciNfc_ExtnReqId_t ExtnReqId; /* NCI extension reqid sent */ + phNciNfc_ExtnRespId_t ExtnRspId; /* NCI extension respid received */ + }ActivExtnId; /* Active Req/Rsp Id */ + uint8_t bParamsNumsPresent; /* Holds number of params available for this Req/Rsp Id */ + uint8_t bParam[2]; /* Req/Res: Param[0] = Param1, Param[1] = Param2 */ +}phNciNfc_ExtnInfo_t; + +/* + * NDEF related data structures + */ +typedef struct phLibNfc_NdefInfo +{ + + uint8_t NdefContinueRead; + uint32_t NdefActualSize; + uint32_t AppWrLength; + phFriNfc_NdefMap_t *psNdefMap; + uint16_t NdefSendRecvLen; + phNfc_sData_t *psUpperNdefMsg; + uint32_t dwWrLength; + uint32_t NdefLength; + uint8_t is_ndef; + phFriNfc_sNdefSmtCrdFmt_t *ndef_fmt; +}phLibNfc_NdefInfo_t; + +/* + * NDEF offsets + */ +typedef enum +{ + phLibNfc_Ndef_EBegin = 0x01, /**< Start from the beginning position */ + phLibNfc_Ndef_ECurrent /**< Start from the current position */ +} phLibNfc_Ndef_EOffset_t; + +/* + * Extns module status + */ +typedef enum +{ + EXTNS_STATUS_OPEN = 0, + EXTNS_STATUS_CLOSE +} phNxpExtns_Status; + +/* + * NCI Data + */ +typedef struct nci_data_package +{ + uint16_t len; + uint8_t p_data[NCI_MAX_DATA_LEN]; +} nci_rsp_data_t; + +/* + * Mifare Callback function definition + */ +typedef void (*CallBackMifare_t)(void*, uint16_t); + +/* + * Auth Cmd Data + */ +typedef struct nci_mfc_package +{ + bool_t auth_status; + bool_t auth_sent; + sem_t semPresenceCheck; + pthread_mutex_t syncmutex; + NFCSTATUS status; + phNfc_sData_t *pauth_cmd; +} phNci_mfc_auth_cmd_t; +/* + * Structure of callback functions from different module. + * It includes the status also. + */ +typedef struct phNxpExtns_Context +{ + phNxpExtns_Status Extns_status; + tNFA_DM_CBACK *p_dm_cback; + tNFA_CONN_CBACK *p_conn_cback; + tNFA_NDEF_CBACK *p_ndef_cback; + uint8_t writecmdFlag; + uint8_t RawWriteCallBack; + void *CallBackCtxt; + CallBackMifare_t CallBackMifare; + bool_t ExtnsConnect; + bool_t ExtnsDeactivate; + bool_t ExtnsCallBack; + uint8_t incrdecflag; + uint8_t incrdecstatusflag; +} phNxpExtns_Context_t; + +NFCSTATUS phFriNfc_ExtnsTransceive(phNfc_sTransceiveInfo_t *pTransceiveInfo, + phNfc_uCmdList_t Cmd, + uint8_t *SendRecvBuf, + uint16_t SendLength, + uint16_t* SendRecvLength); +NFCSTATUS phNxpExtns_MfcModuleInit(void); +NFCSTATUS phNxpExtns_MfcModuleDeInit(void); +NFCSTATUS Mfc_WriteNdef(uint8_t *p_data, uint32_t len); +NFCSTATUS Mfc_CheckNdef(void); +NFCSTATUS Mfc_ReadNdef(void); +NFCSTATUS Mfc_FormatNdef(uint8_t *secretkey, uint8_t len); +NFCSTATUS Mfc_Transceive(uint8_t *p_data, uint32_t len); +NFCSTATUS Mfc_SetReadOnly(uint8_t *secrtkey, uint8_t len); +void Mfc_DeactivateCbackSelect(void); +void Mfc_ActivateCback(void); +NFCSTATUS Mfc_RecvPacket(uint8_t *buff, uint8_t buffSz); +NFCSTATUS phNxNciExtns_MifareStd_Reconnect(void); +NFCSTATUS Mfc_PresenceCheck (void); + +#endif /* _PHNXPEXTNS_MFCRF_H_ */ diff --git a/nci/jni/extns/pn54x/src/phNxpExtns.c b/nci/jni/extns/pn54x/src/phNxpExtns.c new file mode 100755 index 00000000..f39342cc --- /dev/null +++ b/nci/jni/extns/pn54x/src/phNxpExtns.c @@ -0,0 +1,693 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifdef ESE_NFC_SYNCHRONIZATION +#include <linux/ese-nfc-sync.h> +#endif +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/time.h> + +#include <phNxpExtns_MifareStd.h> +#include <phNxpLog.h> +#include <phNxpConfig.h> + +phNxpExtns_Context_t gphNxpExtns_Context; +extern phFriNfc_NdefMap_t *NdefMap; +extern phNci_mfc_auth_cmd_t gAuthCmdBuf; + +static NFCSTATUS phNxpExtns_ProcessSysMessage (phLibNfc_Message_t *msg); +static NFCSTATUS phNxpExtns_SendMsg (phLibNfc_Message_t *sysmsg); + +#ifdef ESE_NFC_SYNCHRONIZATION +/* timing calculation structure*/ +typedef struct time_cal +{ + struct timeval tv1; + struct timeval tv2; +} TimeCal; +static int fd_ese_nfc_sync; /*file descriptor to hold sync driver handle*/ +#endif + +/******************************************************************************* +** +** Function EXTNS_Init +** +** Description This function Initializes Mifare Classic Extns. Allocates +** required memory and initializes the Mifare Classic Vars +** +** Returns NFCSTATUS_SUCCESS if successfully initialized +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_Init (tNFA_DM_CBACK *p_nfa_dm_cback, + tNFA_CONN_CBACK *p_nfa_conn_cback) +{ + NFCSTATUS status = NFCSTATUS_FAILED; + + /* reset config cache */ + resetNxpConfig (); + + /* Initialize Log level */ + phNxpLog_InitializeLogLevel (); + + /* Validate parameters */ + if ((!p_nfa_dm_cback) || (!p_nfa_conn_cback)) + { + NXPLOG_EXTNS_E ("EXTNS_Init(): error null callback"); + goto clean_and_return; + } + + gphNxpExtns_Context.p_dm_cback = p_nfa_dm_cback; + gphNxpExtns_Context.p_conn_cback = p_nfa_conn_cback; + + if (NFCSTATUS_SUCCESS != phNxpExtns_MfcModuleInit ()) + { + NXPLOG_EXTNS_E ("ERROR: MFC Module Init Failed"); + goto clean_and_return; + } + gphNxpExtns_Context.Extns_status = EXTNS_STATUS_OPEN; + + status = NFCSTATUS_SUCCESS; + return status; + +clean_and_return: + gphNxpExtns_Context.Extns_status = EXTNS_STATUS_CLOSE; + return status; +} + +/******************************************************************************* +** +** Function EXTNS_Close +** +** Description This function de-initializes Mifare Classic Extns. +** De-allocates memory +** +** Returns None +** +*******************************************************************************/ +void EXTNS_Close (void) +{ + gphNxpExtns_Context.Extns_status = EXTNS_STATUS_CLOSE; + phNxpExtns_MfcModuleDeInit (); + return; +} + +/******************************************************************************* +** +** Function EXTNS_MfcCallBack +** +** Description Decodes Mifare Classic Tag Response +** This is called from NFA_SendRaw Callback +** +** Returns: +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcCallBack (uint8_t *buf, uint32_t buflen) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_RX_DATA; + msg.pMsgData = buf; + msg.Size = buflen; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + return status; +} + +/******************************************************************************* +** +** Function EXTNS_MfcCheckNDef +** +** Description Performs NDEF detection for Mifare Classic Tag +** +** Upon successful completion of NDEF detection, a +** NFA_NDEF_DETECT_EVT will be sent, to notify the application +** of the NDEF attributes (NDEF total memory size, current +** size, etc.). +** +** Returns: +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcCheckNDef (void) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_MIFARE_CHECK_NDEF; + msg.pMsgData = NULL; + msg.Size = 0; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + + return status; +} + +/******************************************************************************* +** +** Function EXTNS_MfcReadNDef +** +** Description Reads NDEF message from Mifare Classic Tag. +** +** Upon receiving the NDEF message, the message will be sent to +** the handler registered with EXTNS_MfcRegisterNDefTypeHandler. +** +** Returns: +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcReadNDef (void) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_MIFARE_READ_NDEF; + msg.pMsgData = NULL; + msg.Size = 0; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E("Error Sending msg to Extension Thread"); + } + + return status; +} +/******************************************************************************* +** +** Function EXTNS_MfcPresenceCheck +** +** Description Do the check presence for Mifare Classic Tag. +** +** +** Returns: +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcPresenceCheck (void) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_MIFARE_PRESENCE_CHECK; + msg.pMsgData = NULL; + msg.Size = 0; + + gAuthCmdBuf.status = NFCSTATUS_FAILED; + if (sem_init (&gAuthCmdBuf.semPresenceCheck, 0, 0) == -1) + { + ALOGE ("%s: semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno); + return NFCSTATUS_FAILED; + } + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + sem_destroy (&gAuthCmdBuf.semPresenceCheck); + } + + return status; +} + +/******************************************************************************* +** +** Function EXTNS_MfcSetReadOnly +** +** +** Description: +** Sets tag as read only. +** +** When tag is set as read only, or if an error occurs, the app will be +** notified with NFA_SET_TAG_RO_EVT. +** +** Returns: +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcSetReadOnly (uint8_t *key, uint8_t len) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_MIFARE_READ_ONLY; + msg.pMsgData = key; + msg.Size = len; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + + return status; +} + +/******************************************************************************* +** +** Function EXTNS_MfcWriteNDef +** +** Description Writes NDEF data to Mifare Classic Tag. +** +** When the entire message has been written, or if an error +** occurs, the app will be notified with NFA_WRITE_CPLT_EVT. +** +** p_data needs to be persistent until NFA_WRITE_CPLT_EVT +** +** Returns: +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcWriteNDef (uint8_t *p_data, uint32_t len) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_MIFARE_WRITE_NDEF; + msg.pMsgData = p_data; + msg.Size = len; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + + return status; +} + +/***************************************************************************** +** +** Function EXTNS_MfcFormatTag +** +** Description Formats Mifare Classic Tag. +** +** The NFA_RW_FORMAT_CPLT_EVT, status is used to +** indicate if tag is successfully formated or not +** +** Returns +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*****************************************************************************/ +NFCSTATUS EXTNS_MfcFormatTag (uint8_t *key, uint8_t len) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_MIFARE_FORMAT_NDEF; + msg.pMsgData = key; + msg.Size = len; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + + return status; +} + +/***************************************************************************** +** +** Function EXTNS_MfcDisconnect +** +** Description Disconnects Mifare Classic Tag. +** +** Returns +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*****************************************************************************/ +NFCSTATUS EXTNS_MfcDisconnect (void) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_DISCONNECT; + msg.pMsgData = NULL; + msg.Size = 0; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + + return status; +} + +/***************************************************************************** +** +** Function EXTNS_MfcActivated +** +** Description Activates Mifare Classic Tag. +** +** Returns +** NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*****************************************************************************/ +NFCSTATUS EXTNS_MfcActivated (void) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_ACTIVATED; + msg.pMsgData = NULL; + msg.Size = 0; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + + return status; +} + +/******************************************************************************* +** +** Function EXTNS_MfcTransceive +** +** Description Sends raw frame to Mifare Classic Tag. +** +** Returns NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcTransceive (uint8_t *p_data, uint32_t len) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + phLibNfc_Message_t msg; + + msg.eMsgType = PH_NXPEXTNS_MIFARE_TRANSCEIVE; + msg.pMsgData = p_data; + msg.Size = len; + + status = phNxpExtns_SendMsg (&msg); + if (NFCSTATUS_SUCCESS != status) + { + NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); + } + + return status; +} + +/******************************************************************************* +** +** Function EXTNS_MfcInit +** +** Description This function is used to Init Mifare Classic Extns. +** This function should be called when the tag detected is +** Mifare Classic. +** +** Returns NFCSTATUS_SUCCESS +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcInit (tNFA_ACTIVATED activationData) +{ + tNFC_ACTIVATE_DEVT rfDetail = activationData.activate_ntf; + + NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak = rfDetail.rf_tech_param.param.pa.sel_rsp; + NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA [0] = rfDetail.rf_tech_param.param.pa.sens_res[0]; + NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA [1] = rfDetail.rf_tech_param.param.pa.sens_res[1]; + + return NFCSTATUS_SUCCESS; +} + +/******************************************************************************* +** +** Function phNxpExtns_ProcessSysMessage +** +** Description Internal function to route the request from JNI and Callback +** from NFA_SendRawFrame to right function +** +** Returns NFCSTATUS_SUCCESS if valid request +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +static NFCSTATUS phNxpExtns_ProcessSysMessage (phLibNfc_Message_t *msg) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + if (gphNxpExtns_Context.Extns_status == EXTNS_STATUS_CLOSE) + { + return NFCSTATUS_FAILED; + } + + switch (msg->eMsgType) + { + case PH_NXPEXTNS_RX_DATA: + status = Mfc_RecvPacket (msg->pMsgData, msg->Size); + break; + + case PH_NXPEXTNS_MIFARE_CHECK_NDEF: + pthread_mutex_init (&gAuthCmdBuf.syncmutex, NULL); + pthread_mutex_lock (&gAuthCmdBuf.syncmutex); + status = Mfc_CheckNdef (); + pthread_mutex_unlock (&gAuthCmdBuf.syncmutex); + pthread_mutex_destroy (&gAuthCmdBuf.syncmutex); + break; + + case PH_NXPEXTNS_MIFARE_READ_NDEF: + status = Mfc_ReadNdef (); + break; + + case PH_NXPEXTNS_MIFARE_WRITE_NDEF: + status = Mfc_WriteNdef (msg->pMsgData, msg->Size); + break; + + case PH_NXPEXTNS_MIFARE_FORMAT_NDEF: + status = Mfc_FormatNdef (msg->pMsgData, msg->Size); + break; + + case PH_NXPEXTNS_DISCONNECT: + Mfc_DeactivateCbackSelect (); + break; + + case PH_NXPEXTNS_ACTIVATED: + Mfc_ActivateCback (); + break; + + case PH_NXPEXTNS_MIFARE_TRANSCEIVE: + status = Mfc_Transceive (msg->pMsgData, msg->Size); + break; + + case PH_NXPEXTNS_MIFARE_READ_ONLY: + status = Mfc_SetReadOnly (msg->pMsgData, msg->Size); + break; + case PH_NXPEXTNS_MIFARE_PRESENCE_CHECK: + pthread_mutex_init (&gAuthCmdBuf.syncmutex, NULL); + pthread_mutex_lock (&gAuthCmdBuf.syncmutex); + status = Mfc_PresenceCheck (); + pthread_mutex_unlock (&gAuthCmdBuf.syncmutex); + pthread_mutex_destroy (&gAuthCmdBuf.syncmutex); + break; + default: + status = NFCSTATUS_FAILED; + NXPLOG_EXTNS_E ("Illegal Command for Extension"); + break; + } + + return status; +} + +/******************************************************************************* +** +** Function phNxpExtns_SendMsg +** +** Description unlocks phNxpExtns_ProcessSysMessage with a valid message +** +** Returns NFCSTATUS_SUCCESS if successfully initiated +** NFCSTATUS_FAILED otherwise +** +*******************************************************************************/ +static NFCSTATUS phNxpExtns_SendMsg (phLibNfc_Message_t *sysmsg) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + status = phNxpExtns_ProcessSysMessage (sysmsg); + + return status; +} + +/******************************************************************************* +** +** Function EXTNS_MfcRegisterNDefTypeHandler +** +** Description This function allows the applications to register for +** specific types of NDEF records. +** +** For records types which were not registered, the record will +** be sent to the default handler. +** +** Returns NFCSTATUS_SUCCESS +** +*******************************************************************************/ +NFCSTATUS EXTNS_MfcRegisterNDefTypeHandler (tNFA_NDEF_CBACK *ndefHandlerCallback) +{ + + NFCSTATUS status = NFCSTATUS_FAILED; + if (NULL != ndefHandlerCallback) + { + gphNxpExtns_Context.p_ndef_cback = ndefHandlerCallback; + status = NFCSTATUS_SUCCESS; + } + + return status; +} + +/******************************************************************************* +** Synchronizing Functions ** +** Synchronizes Callback in JNI and MFC Extns ** +*******************************************************************************/ + +bool_t EXTNS_GetConnectFlag (void) +{ + return (gphNxpExtns_Context.ExtnsConnect); +} + +void EXTNS_SetConnectFlag (bool_t flagval) +{ + gphNxpExtns_Context.ExtnsConnect = flagval; +} + +bool_t EXTNS_GetDeactivateFlag (void) +{ + return (gphNxpExtns_Context.ExtnsDeactivate); +} + +void EXTNS_SetDeactivateFlag (bool_t flagval) +{ + gphNxpExtns_Context.ExtnsDeactivate = flagval; +} + +bool_t EXTNS_GetCallBackFlag (void) +{ + return (gphNxpExtns_Context.ExtnsCallBack); +} + +void EXTNS_SetCallBackFlag (bool_t flagval) +{ + gphNxpExtns_Context.ExtnsCallBack = flagval; + +} +NFCSTATUS EXTNS_GetPresenceCheckStatus (void) +{ + struct timespec ts; + + clock_gettime (CLOCK_REALTIME, &ts); + ts.tv_sec += 0; + ts.tv_nsec += 100*1000*1000; // 100 milisec + if (ts.tv_nsec >= 1000 * 1000 * 1000) + { + ts.tv_sec += 1; + ts.tv_nsec = ts.tv_nsec - (1000 * 1000 * 1000); + } + + if (sem_timedwait (&gAuthCmdBuf.semPresenceCheck, &ts)) + { + ALOGE ("%s: failed to wait (errno=0x%08x)", __FUNCTION__, errno); + return NFCSTATUS_FAILED; + } + if (sem_destroy (&gAuthCmdBuf.semPresenceCheck)) + { + ALOGE ("Failed to destroy check Presence semaphore (errno=0x%08x)", errno); + } + return gAuthCmdBuf.status; +} + +void MfcPresenceCheckResult (NFCSTATUS status) +{ + gAuthCmdBuf.status = status; + EXTNS_SetCallBackFlag (TRUE); + sem_post (&gAuthCmdBuf.semPresenceCheck); +} +void MfcResetPresenceCheckStatus (void) +{ + gAuthCmdBuf.auth_sent = FALSE; +} +/******************************************************************************* +** +** Function EXTNS_CheckMfcResponse +** +** Description This function is called from JNI Transceive for Mifare +** Classic Tag status interpretation and to send the required +** status to application +** +** Returns NFCSTATUS_SUCCESS +** NFCSTATUS_FAILED +** +*******************************************************************************/ +NFCSTATUS EXTNS_CheckMfcResponse (uint8_t** sTransceiveData, uint32_t *sTransceiveDataLen) +{ + NFCSTATUS status = NFCSTATUS_SUCCESS; + + if (*sTransceiveDataLen == 3) + { + if((*sTransceiveData) [0] == 0x10 && (*sTransceiveData) [1] != 0x0A) + { + NXPLOG_EXTNS_E ("Mifare Error in payload response"); + *sTransceiveDataLen = 0x1; + *sTransceiveData += 1; + return NFCSTATUS_FAILED; + } + } + if ((*sTransceiveData) [0] == 0x40) + { + *sTransceiveData += 1; + *sTransceiveDataLen = 0x01; + if((*sTransceiveData) [0] == 0x03) + { + *sTransceiveDataLen = 0x00; + status = NFCSTATUS_FAILED; + } + } + else if ((*sTransceiveData) [0] == 0x10) + { + *sTransceiveData += 1; + *sTransceiveDataLen = 0x10; + } + + return status; +} + diff --git a/nci/jni/extns/pn54x/src/utils/phNxpConfig.cpp b/nci/jni/extns/pn54x/src/utils/phNxpConfig.cpp new file mode 100755 index 00000000..e4b95b5f --- /dev/null +++ b/nci/jni/extns/pn54x/src/utils/phNxpConfig.cpp @@ -0,0 +1,918 @@ +/* + * Copyright (C) 2015 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. + */ + +#include <phNxpConfig.h> +#include <stdio.h> +#include <string> +#include <vector> +#include <list> +#include <sys/stat.h> + +#include <phNxpLog.h> + +#if GENERIC_TARGET +const char alternative_config_path[] = "/data/nfc/"; +#else +const char alternative_config_path[] = ""; +#endif + +#if 1 +const char transport_config_path[] = "/etc/"; +#else +const char transport_config_path[] = "res/"; +#endif + +#define config_name "libnfc-nxp.conf" +#define extra_config_base "libnfc-nxp-" +#define extra_config_ext ".conf" +#define IsStringValue 0x80000000 + +const char config_timestamp_path[] = "/data/nfc/libnfc-nxpConfigState.bin"; + +using namespace::std; + +class CNxpNfcParam : public string +{ +public: + CNxpNfcParam (); + CNxpNfcParam (const char* name, const string& value); + CNxpNfcParam (const char* name, unsigned long value); + virtual ~CNxpNfcParam (); + unsigned long numValue () const {return m_numValue;} + const char* str_value () const {return m_str_value.c_str();} + size_t str_len () const {return m_str_value.length();} +private: + string m_str_value; + unsigned long m_numValue; +}; + +class CNxpNfcConfig : public vector<const CNxpNfcParam*> +{ +public: + virtual ~CNxpNfcConfig (); + static CNxpNfcConfig& GetInstance (); + friend void readOptionalConfig (const char* optional); + int checkTimestamp (); + + bool getValue (const char* name, char* pValue, size_t len) const; + bool getValue (const char* name, unsigned long& rValue) const; + bool getValue (const char* name, unsigned short & rValue) const; + bool getValue (const char* name, char* pValue, long len, long* readlen) const; + const CNxpNfcParam* find (const char* p_name) const; + void clean (); +private: + CNxpNfcConfig (); + bool readConfig (const char* name, bool bResetContent); + void moveFromList (); + void moveToList (); + void add (const CNxpNfcParam* pParam); + list<const CNxpNfcParam*> m_list; + bool mValidFile; + unsigned long m_timeStamp; + + unsigned long state; + + inline bool Is (unsigned long f) {return (state & f) == f;} + inline void Set (unsigned long f) {state |= f;} + inline void Reset (unsigned long f) {state &= ~f;} +}; + +/******************************************************************************* +** +** Function: isPrintable() +** +** Description: determine if 'c' is printable +** +** Returns: 1, if printable, otherwise 0 +** +*******************************************************************************/ +inline bool isPrintable (char c) +{ + return (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + c == '/' || c == '_' || c == '-' || c == '.'; +} + +/******************************************************************************* +** +** Function: isDigit() +** +** Description: determine if 'c' is numeral digit +** +** Returns: true, if numerical digit +** +*******************************************************************************/ +inline bool isDigit (char c, int base) +{ + if ('0' <= c && c <= '9') + return true; + if (base == 16) + { + if (('A' <= c && c <= 'F') || + ('a' <= c && c <= 'f')) + return true; + } + return false; +} + +/******************************************************************************* +** +** Function: getDigitValue() +** +** Description: return numerical value of a decimal or hex char +** +** Returns: numerical value if decimal or hex char, otherwise 0 +** +*******************************************************************************/ +inline int getDigitValue (char c, int base) +{ + if ('0' <= c && c <= '9') + return c - '0'; + if (base == 16) + { + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + else if ('a' <= c && c <= 'f') + return c - 'a' + 10; + } + return 0; +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::readConfig() +** +** Description: read Config settings and parse them into a linked list +** move the element from linked list to a array at the end +** +** Returns: 1, if there are any config data, 0 otherwise +** +*******************************************************************************/ +bool CNxpNfcConfig::readConfig (const char* name, bool bResetContent) +{ + enum { + BEGIN_LINE = 1, + TOKEN, + STR_VALUE, + NUM_VALUE, + BEGIN_HEX, + BEGIN_QUOTE, + END_LINE + }; + + FILE* fd; + struct stat buf; + string token; + string strValue; + unsigned long numValue = 0; + CNxpNfcParam* pParam = NULL; + int i = 0; + int base = 0; + char c; + int bflag = 0; + state = BEGIN_LINE; + /* open config file, read it into a buffer */ + if ((fd = fopen (name, "rb")) == NULL) + { + ALOGE ("%s Cannot open config file %s\n", __func__, name); + if (bResetContent) + { + ALOGE ("%s Using default value for all settings\n", __func__); + mValidFile = false; + } + return false; + } + stat (name, &buf); + m_timeStamp = (unsigned long) buf.st_mtime; + + mValidFile = true; + if (size() > 0) + { + if (bResetContent) + clean (); + else + moveToList (); + } + + while (!feof (fd) && fread (&c, 1, 1, fd) == 1) + { + switch (state & 0xff) + { + case BEGIN_LINE: + if (c == '#') + { + state = END_LINE; + } + else if (isPrintable (c)) + { + i = 0; + token.erase (); + strValue.erase (); + state = TOKEN; + token.push_back (c); + } + break; + case TOKEN: + if (c == '=') + { + token.push_back ('\0'); + state = BEGIN_QUOTE; + } + else if (isPrintable (c)) + { + token.push_back (c); + } + else + { + state = END_LINE; + } + break; + case BEGIN_QUOTE: + if (c == '"') + { + state = STR_VALUE; + base = 0; + } + else if (c == '0') + { + state = BEGIN_HEX; + } + else if (isDigit (c, 10)) + { + state = NUM_VALUE; + base = 10; + numValue = getDigitValue (c, base); + i = 0; + } + else if (c == '{') + { + state = NUM_VALUE; + bflag = 1; + base = 16; + i = 0; + Set (IsStringValue); + } + else + state = END_LINE; + + break; + case BEGIN_HEX: + if (c == 'x' || c == 'X') + { + state = NUM_VALUE; + base = 16; + numValue = 0; + i = 0; + break; + } + else if (isDigit (c, 10)) + { + state = NUM_VALUE; + base = 10; + numValue = getDigitValue (c, base); + break; + } + else if (c != '\n' && c != '\r') + { + state = END_LINE; + break; + } + // fall through to numValue to handle numValue + + case NUM_VALUE: + if (isDigit (c, base)) + { + numValue *= base; + numValue += getDigitValue (c, base); + ++i; + } + else if(bflag == 1 && (c == ' ' || c == '\r' || c=='\n' || c=='\t')) + { + break; + } + else if (base == 16 && (c== ','|| c == ':' || c == '-' || c == ' ' || c == '}')) + { + + if( c=='}' ) + { + bflag = 0; + } + if (i > 0) + { + int n = (i+1) / 2; + while (n-- > 0) + { + numValue = numValue >> (n * 8); + unsigned char c = (numValue) & 0xFF; + strValue.push_back (c); + } + } + + Set (IsStringValue); + numValue = 0; + i = 0; + } + else + { + if (c == '\n' || c == '\r') + { + if (bflag == 0) + { + state = BEGIN_LINE; + } + } + else + { + if (bflag == 0) + { + state = END_LINE; + } + } + if (Is (IsStringValue) && base == 16 && i > 0) + { + int n = (i+1) / 2; + while (n-- > 0) + strValue.push_back (((numValue >> (n * 8)) & 0xFF)); + } + if (strValue.length() > 0) + pParam = new CNxpNfcParam (token.c_str (), strValue); + else + pParam = new CNxpNfcParam (token.c_str (), numValue); + + add (pParam); + strValue.erase (); + numValue = 0; + } + break; + case STR_VALUE: + if (c == '"') + { + strValue.push_back('\0'); + state = END_LINE; + pParam = new CNxpNfcParam(token.c_str(), strValue); + add(pParam); + } + else if (isPrintable(c)) + { + strValue.push_back(c); + } + break; + case END_LINE: + if (c == '\n' || c == '\r') + { + state = BEGIN_LINE; + } + break; + default: + break; + } + } + + fclose (fd); + + moveFromList (); + return size () > 0; +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::CNxpNfcConfig() +** +** Description: class constructor +** +** Returns: none +** +*******************************************************************************/ +CNxpNfcConfig::CNxpNfcConfig () : + mValidFile (true), + m_timeStamp (0), + state (0) +{ +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::~CNxpNfcConfig() +** +** Description: class destructor +** +** Returns: none +** +*******************************************************************************/ +CNxpNfcConfig::~CNxpNfcConfig () +{ +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::GetInstance() +** +** Description: get class singleton object +** +** Returns: none +** +*******************************************************************************/ +CNxpNfcConfig& CNxpNfcConfig::GetInstance () +{ + static CNxpNfcConfig theInstance; + + if (theInstance.size () == 0 && theInstance.mValidFile) + { + string strPath; + if (alternative_config_path [0] != '\0') + { + strPath.assign (alternative_config_path); + strPath += config_name; + theInstance.readConfig (strPath.c_str (), true); + if (!theInstance.empty ()) + { + return theInstance; + } + } + strPath.assign (transport_config_path); + strPath += config_name; + theInstance.readConfig (strPath.c_str (), true); + } + + return theInstance; +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::getValue() +** +** Description: get a string value of a setting +** +** Returns: true if setting exists +** false if setting does not exist +** +*******************************************************************************/ +bool CNxpNfcConfig::getValue (const char* name, char* pValue, size_t len) const +{ + const CNxpNfcParam* pParam = find (name); + if (pParam == NULL) + return false; + + if (pParam->str_len () > 0) + { + memset (pValue, 0, len); + memcpy (pValue, pParam->str_value (), pParam->str_len ()); + return true; + } + return false; +} + +bool CNxpNfcConfig::getValue (const char* name, char* pValue, long len,long* readlen) const +{ + const CNxpNfcParam* pParam = find (name); + if (pParam == NULL) + return false; + + if (pParam->str_len () > 0) + { + if(pParam->str_len () <= (unsigned long) len) + { + memset (pValue, 0, len); + memcpy (pValue, pParam->str_value (), pParam->str_len ()); + *readlen = pParam->str_len (); + } + else + { + *readlen = -1; + } + + return true; + } + return false; +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::getValue() +** +** Description: get a long numerical value of a setting +** +** Returns: true if setting exists +** false if setting does not exist +** +*******************************************************************************/ +bool CNxpNfcConfig::getValue (const char* name, unsigned long& rValue) const +{ + const CNxpNfcParam* pParam = find (name); + if (pParam == NULL) + return false; + + if (pParam->str_len () == 0) + { + rValue = static_cast<unsigned long> (pParam->numValue ()); + return true; + } + return false; +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::getValue() +** +** Description: get a short numerical value of a setting +** +** Returns: true if setting exists +** false if setting does not exist +** +*******************************************************************************/ +bool CNxpNfcConfig::getValue (const char* name, unsigned short& rValue) const +{ + const CNxpNfcParam* pParam = find (name); + if (pParam == NULL) + return false; + + if (pParam->str_len () == 0) + { + rValue = static_cast<unsigned short> (pParam->numValue ()); + return true; + } + return false; +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::find() +** +** Description: search if a setting exist in the setting array +** +** Returns: pointer to the setting object +** +*******************************************************************************/ +const CNxpNfcParam* CNxpNfcConfig::find (const char* p_name) const +{ + if (size () == 0) + return NULL; + + for (const_iterator it = begin (), itEnd = end (); it != itEnd; ++it) + { + if (**it < p_name) + { + continue; + } + else if (**it == p_name) + { + if ((*it)->str_len () > 0) + { + NXPLOG_EXTNS_D ("%s found %s=%s\n", __func__, p_name, (*it)->str_value()); + } + else + { + NXPLOG_EXTNS_D ("%s found %s=(0x%lx)\n", __func__, p_name, (*it)->numValue()); + } + return *it; + } + else + break; + } + return NULL; +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::clean() +** +** Description: reset the setting array +** +** Returns: none +** +*******************************************************************************/ +void CNxpNfcConfig::clean () +{ + if (size () == 0) + return; + + for (iterator it = begin (), itEnd = end (); it != itEnd; ++it) + delete *it; + + clear (); +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::Add() +** +** Description: add a setting object to the list +** +** Returns: none +** +*******************************************************************************/ +void CNxpNfcConfig::add (const CNxpNfcParam* pParam) +{ + if (m_list.size () == 0) + { + m_list.push_back (pParam); + return; + } + for (list<const CNxpNfcParam*>::iterator it = m_list.begin (), itEnd = m_list.end (); it != itEnd; ++it) + { + if (**it < pParam->c_str ()) + continue; + + m_list.insert (it, pParam); + return; + } + m_list.push_back (pParam); +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::moveFromList() +** +** Description: move the setting object from list to array +** +** Returns: none +** +*******************************************************************************/ +void CNxpNfcConfig::moveFromList () +{ + if (m_list.size () == 0) + return; + + for (list<const CNxpNfcParam*>::iterator it = m_list.begin (), itEnd = m_list.end (); it != itEnd; ++it) + push_back (*it); + + m_list.clear (); +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::moveToList() +** +** Description: move the setting object from array to list +** +** Returns: none +** +*******************************************************************************/ +void CNxpNfcConfig::moveToList () +{ + if (m_list.size () != 0) + m_list.clear (); + + for (iterator it = begin (), itEnd = end (); it != itEnd; ++it) + m_list.push_back (*it); + + clear(); +} + +/******************************************************************************* +** +** Function: CNxpNfcConfig::checkTimestamp() +** +** Description: check if config file has modified +** +** Returns: 0 if not modified, 1 otherwise. +** +*******************************************************************************/ +int CNxpNfcConfig::checkTimestamp () +{ + FILE* fd; + struct stat st; + unsigned long value = 0; + int ret = 0; + + if (stat(config_timestamp_path, &st) != 0) + { + ALOGD ("%s file %s not exist, creat it.\n", __func__, config_timestamp_path); + if ((fd = fopen (config_timestamp_path, "w+")) != NULL) + { + fwrite (&m_timeStamp, sizeof(unsigned long), 1, fd); + fclose (fd); + } + return 1; + } + else + { + fd = fopen (config_timestamp_path, "r+"); + if (fd == NULL) + { + ALOGE ("%s Cannot open file %s\n", __func__, config_timestamp_path); + return 1; + } + + fread (&value, sizeof(unsigned long), 1, fd); + ret = (value != m_timeStamp); + if (ret) + { + fseek (fd, 0, SEEK_SET); + fwrite (&m_timeStamp, sizeof(unsigned long), 1, fd); + } + fclose (fd); + } + return ret; +} + +/******************************************************************************* +** +** Function: CNxpNfcParam::CNxpNfcParam() +** +** Description: class constructor +** +** Returns: none +** +*******************************************************************************/ +CNxpNfcParam::CNxpNfcParam () : + m_numValue (0) +{ +} + +/******************************************************************************* +** +** Function: CNxpNfcParam::~CNxpNfcParam() +** +** Description: class destructor +** +** Returns: none +** +*******************************************************************************/ +CNxpNfcParam::~CNxpNfcParam () +{ +} + +/******************************************************************************* +** +** Function: CNxpNfcParam::CNxpNfcParam() +** +** Description: class copy constructor +** +** Returns: none +** +*******************************************************************************/ +CNxpNfcParam::CNxpNfcParam (const char* name, const string& value) : + string (name), + m_str_value (value), + m_numValue (0) +{ +} + +/******************************************************************************* +** +** Function: CNxpNfcParam::CNxpNfcParam() +** +** Description: class copy constructor +** +** Returns: none +** +*******************************************************************************/ +CNxpNfcParam::CNxpNfcParam (const char* name, unsigned long value) : + string (name), + m_numValue (value) +{ +} + +/******************************************************************************* +** +** Function: GetStrValue +** +** Description: API function for getting a string value of a setting +** +** Returns: True if found, otherwise False. +** +*******************************************************************************/ +extern "C" int GetNxpStrValue (const char* name, char* pValue, unsigned long len) +{ + CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance (); + + return rConfig.getValue (name, pValue, len); +} + +/******************************************************************************* +** +** Function: GetByteArrayValue() +** +** Description: Read byte array value from the config file. +** +** Parameters: +** name - name of the config param to read. +** pValue - pointer to input buffer. +** bufflen - input buffer length. +** len - out parameter to return the number of bytes read from config file, +** return -1 in case bufflen is not enough. +** +** Returns: TRUE[1] if config param name is found in the config file, else FALSE[0] +** +*******************************************************************************/ +extern "C" int GetNxpByteArrayValue (const char* name, char* pValue, long bufflen, long *len) +{ + CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance (); + + return rConfig.getValue (name, pValue, bufflen,len); +} + +/******************************************************************************* +** +** Function: GetNumValue +** +** Description: API function for getting a numerical value of a setting +** +** Returns: true, if successful +** +*******************************************************************************/ +extern "C" int GetNxpNumValue (const char* name, void* pValue, unsigned long len) +{ + if (!pValue) + return false; + + CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance (); + const CNxpNfcParam* pParam = rConfig.find (name); + + if (pParam == NULL) + return false; + + unsigned long v = pParam->numValue (); + if (v == 0 && pParam->str_len () > 0 && pParam->str_len () < 4) + { + const unsigned char* p = (const unsigned char*) pParam->str_value (); + for (unsigned int i = 0 ; i < pParam->str_len (); ++i) + { + v *= 256; + v += *p++; + } + } + switch (len) + { + case sizeof(unsigned long): + *(static_cast<unsigned long*>(pValue)) = (unsigned long) v; + break; + case sizeof(unsigned short): + *(static_cast<unsigned short*>(pValue)) = (unsigned short) v; + break; + case sizeof(unsigned char): + *(static_cast<unsigned char*> (pValue)) = (unsigned char) v; + break; + default: + return false; + } + return true; +} + +/******************************************************************************* +** +** Function: resetConfig +** +** Description: reset settings array +** +** Returns: none +** +*******************************************************************************/ +extern "C" void resetNxpConfig () +{ + CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance (); + + rConfig.clean (); +} + +/******************************************************************************* +** +** Function: readOptionalConfig() +** +** Description: read Config settings from an optional conf file +** +** Returns: none +** +*******************************************************************************/ +void readOptionalConfig (const char* extra) +{ + string strPath; + strPath.assign (transport_config_path); + if (alternative_config_path [0] != '\0') + strPath.assign (alternative_config_path); + + strPath += extra_config_base; + strPath += extra; + strPath += extra_config_ext; + CNxpNfcConfig::GetInstance ().readConfig (strPath.c_str (), false); +} + +/******************************************************************************* +** +** Function: isNxpConfigModified() +** +** Description: check if config file has modified +** +** Returns: 0 if not modified, 1 otherwise. +** +*******************************************************************************/ +extern "C" int isNxpConfigModified () +{ + CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance (); + return rConfig.checkTimestamp (); +} diff --git a/nci/jni/extns/pn54x/src/utils/phNxpConfig.h b/nci/jni/extns/pn54x/src/utils/phNxpConfig.h new file mode 100755 index 00000000..bec16a22 --- /dev/null +++ b/nci/jni/extns/pn54x/src/utils/phNxpConfig.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015 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. + */ + +#ifndef _NXP_CONFIG_H +#define _NXP_CONFIG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +int GetNxpStrValue (const char* name, char* p_value, unsigned long len); +int GetNxpNumValue (const char* name, void* p_value, unsigned long len); +int GetNxpByteArrayValue (const char* name, char* pValue, long bufflen, long *len); +void resetNxpConfig (void); +int isNxpConfigModified (); + +#ifdef __cplusplus +} +#endif + +#define NAME_NXPLOG_EXTNS_LOGLEVEL "NXPLOG_EXTNS_LOGLEVEL" +#define NAME_NXPLOG_NCIHAL_LOGLEVEL "NXPLOG_NCIHAL_LOGLEVEL" +#define NAME_NXPLOG_NCIX_LOGLEVEL "NXPLOG_NCIX_LOGLEVEL" +#define NAME_NXPLOG_NCIR_LOGLEVEL "NXPLOG_NCIR_LOGLEVEL" +#define NAME_NXPLOG_FWDNLD_LOGLEVEL "NXPLOG_FWDNLD_LOGLEVEL" +#define NAME_NXPLOG_TML_LOGLEVEL "NXPLOG_TML_LOGLEVEL" + +#define NAME_MIFARE_READER_ENABLE "MIFARE_READER_ENABLE" +#define NAME_FW_STORAGE "FW_STORAGE" +#define NAME_NXP_ACT_PROP_EXTN "NXP_ACT_PROP_EXTN" +#define NAME_NXP_RF_CONF_BLK_1 "NXP_RF_CONF_BLK_1" +#define NAME_NXP_RF_CONF_BLK_2 "NXP_RF_CONF_BLK_2" +#define NAME_NXP_RF_CONF_BLK_3 "NXP_RF_CONF_BLK_3" +#define NAME_NXP_RF_CONF_BLK_4 "NXP_RF_CONF_BLK_4" +#define NAME_NXP_CORE_CONF_EXTN "NXP_CORE_CONF_EXTN" +#define NAME_NXP_CORE_CONF "NXP_CORE_CONF" +#define NAME_NXP_CORE_MFCKEY_SETTING "NXP_CORE_MFCKEY_SETTING" +#define NAME_NXP_CORE_STANDBY "NXP_CORE_STANDBY" +#define NAME_NXP_DEFAULT_SE "NXP_DEFAULT_SE" +#define NAME_NXP_NFC_CHIP "NXP_NFC_CHIP" +#define NAME_NXP_SWP_RD_START_TIMEOUT "NXP_SWP_RD_START_TIMEOUT" +#define NAME_NXP_SWP_RD_TAG_OP_TIMEOUT "NXP_SWP_RD_TAG_OP_TIMEOUT" +#define NAME_NXP_DEFAULT_NFCEE_TIMEOUT "NXP_DEFAULT_NFCEE_TIMEOUT" +#define NAME_NXP_DEFAULT_NFCEE_DISC_TIMEOUT "NXP_DEFAULT_NFCEE_DISC_TIMEOUT" +#define NAME_NXP_CE_ROUTE_STRICT_DISABLE "NXP_CE_ROUTE_STRICT_DISABLE" +#define NAME_NXP_P61_LS_DEFAULT_INTERFACE "NXP_P61_LS_DEFAULT_INTERFACE" +#define NAME_NXP_P61_JCOP_DEFAULT_INTERFACE "NXP_P61_JCOP_DEFAULT_INTERFACE" +#define NAME_NXP_JCOPDL_AT_BOOT_ENABLE "NXP_JCOPDL_AT_BOOT_ENABLE" +#define NAME_NXP_P61_LTSM_DEFAULT_INTERFACE "NXP_P61_LTSM_DEFAULT_INTERFACE" +#define NAME_NXP_LOADER_SERICE_VERSION "NXP_LOADER_SERVICE_VERSION" +/* default configuration */ +#define default_storage_location "/data/nfc" + +#endif // _NXP_CONFIG_H |