diff options
author | Martijn Coenen <martijn.coenen@nxp.com> | 2010-12-16 23:24:55 +0100 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-12-16 16:49:43 -0800 |
commit | 80ee29b88ec489e2bbf6ae446692229d36755429 (patch) | |
tree | 9592b7c752c315b6474f72b76b9dc220991290cc | |
parent | d75796b759f9baac8facf22f1b6c6bcfbc51161e (diff) | |
download | external_libnfc-nxp-80ee29b88ec489e2bbf6ae446692229d36755429.zip external_libnfc-nxp-80ee29b88ec489e2bbf6ae446692229d36755429.tar.gz external_libnfc-nxp-80ee29b88ec489e2bbf6ae446692229d36755429.tar.bz2 |
Add support for makeLowLevelReadonly() in libnfc.
Implemented for T1T and T2T.
There's also added code for formatting Desfire EV1, but it will not be used
by the current implementation (DesFIRE doesn't have NdefFormatable tech).
Change-Id: Iec1b85b560fbf800291fd307b56ab84328737635
-rw-r--r-- | src/phFriNfc.h | 6 | ||||
-rw-r--r-- | src/phFriNfc_DesfireFormat.c | 376 | ||||
-rw-r--r-- | src/phFriNfc_DesfireFormat.h | 52 | ||||
-rw-r--r-- | src/phFriNfc_MifULFormat.c | 92 | ||||
-rw-r--r-- | src/phFriNfc_MifULFormat.h | 29 | ||||
-rw-r--r-- | src/phFriNfc_NdefMap.c | 41 | ||||
-rw-r--r-- | src/phFriNfc_NdefMap.h | 23 | ||||
-rw-r--r-- | src/phFriNfc_SmtCrdFmt.c | 53 | ||||
-rw-r--r-- | src/phFriNfc_SmtCrdFmt.h | 27 | ||||
-rw-r--r-- | src/phFriNfc_TopazMap.c | 55 | ||||
-rw-r--r-- | src/phFriNfc_TopazMap.h | 46 | ||||
-rw-r--r-- | src/phLibNfc.h | 71 | ||||
-rw-r--r-- | src/phLibNfc_ndef_raw.c | 239 | ||||
-rw-r--r-- | src/phLibNfc_ndef_raw.h | 3 |
14 files changed, 1093 insertions, 20 deletions
diff --git a/src/phFriNfc.h b/src/phFriNfc.h index 1437a05..989871b 100644 --- a/src/phFriNfc.h +++ b/src/phFriNfc.h @@ -23,7 +23,7 @@ * $Date: Thu Feb 11 18:45:30 2010 $ * $Author: ing04880 $ * $Revision: 1.19 $ - * $Aliases: NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $ + * $Aliases: NFC_FRI1.1_WK1007_R33_1 $ * */ @@ -39,6 +39,8 @@ #define LOCK_BITS_CHECK_ENABLE #endif +#define FRINFC_READONLY_NDEF + #ifdef DISABLE_MIFARE_MAPPING #define PH_FRINFC_MAP_MIFAREUL_DISABLED #define PH_FRINFC_MAP_MIFARESTD_DISABLED @@ -74,7 +76,7 @@ /*@{*/ #define PH_FRINFC_FILEREVISION "$Revision: 1.19 $" /**< \ingroup grp_file_attributes */ -#define PH_FRINFC_FILEALIASES "$Aliases: NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $" /**< \ingroup grp_file_attributes */ +#define PH_FRINFC_FILEALIASES "$Aliases: NFC_FRI1.1_WK1007_R33_1 $" /**< \ingroup grp_file_attributes */ /*@}*/ diff --git a/src/phFriNfc_DesfireFormat.c b/src/phFriNfc_DesfireFormat.c index a53d5d9..4f3bbdd 100644 --- a/src/phFriNfc_DesfireFormat.c +++ b/src/phFriNfc_DesfireFormat.c @@ -21,9 +21,9 @@ * * Project: NFC-FRI * -* $Date: Fri Oct 15 13:50:54 2010 $ +* $Date: Thu Oct 28 17:44:00 2010 $ * $Author: ing02260 $ -* $Revision: 1.6 $ +* $Revision: 1.8 $ * $Aliases: $ * */ @@ -52,6 +52,15 @@ CLA INS P1 P2 Lc Data Le /* This settings can be changed, depending on the requirement*/ #define PH_FRINFC_DESF_PICC_NFC_KEY_SETTING 0x0FU +#ifdef FRINFC_READONLY_NDEF + + #define READ_ONLY_NDEF_DESFIRE 0xFFU + #define CC_BYTES_SIZE 0x0FU + #define PH_FRINFC_DESF_READ_DATA_CMD 0xBDU + #define NATIVE_WRAPPER_READ_DATA_LC_VALUE 0x07U + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + #ifdef DESFIRE_FMT_EV1 #define DESFIRE_CARD_TYPE_EV1 0x01U @@ -72,7 +81,7 @@ CLA INS P1 P2 Lc Data Le #define DESFIRE_4K_CARD 4096U #define DESFIRE_8K_CARD 7680U -#define DESFIRE_EV1_KEY_SETTINGS_2 0x27U +#define DESFIRE_EV1_KEY_SETTINGS_2 0x21U #define DESFIRE_EV1_FIRST_AID_BYTE 0x01U #define DESFIRE_EV1_SECOND_AID_BYTE 0x00U @@ -133,6 +142,40 @@ static NFCSTATUS phFriNfc_Desf_HWrNDEFData(phFriNfc_sNdefSmtCrdFmt_t *NdefSmt /* Transceive Cmd initiation*/ static NFCSTATUS phFriNfc_Desf_HSendTransCmd(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +#ifdef FRINFC_READONLY_NDEF + +#if 0 +static +NFCSTATUS +phFriNfc_Desf_HReadOnlySelectCCFile ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +#endif /* #if 0 */ + +static +NFCSTATUS +phFriNfc_Desf_HReadOnlyReadCCFile ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); + +static +NFCSTATUS +phFriNfc_Desf_HReadOnlyWriteCCFile ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); + +static +NFCSTATUS +phFriNfc_Desf_HReadOnlySelectApp ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); + +#ifdef DESFIRE_FMT_EV1 + +static +NFCSTATUS +phFriNfc_Desf_HReadOnlySelectAppEV1 ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); + +#endif /* #ifdef DESFIRE_FMT_EV1 */ + +#endif /* #ifdef FRINFC_READONLY_NDEF */ void phFriNfc_Desfire_Reset( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { @@ -672,8 +715,9 @@ static NFCSTATUS phFriNfc_Desf_HUpdateVersionDetails(phFriNfc_sNdefSmtCrdFmt_t * { NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion = NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL3]; NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion = NdefSmtCrdFmt->SendRecvBuf[PH_SMTCRDFMT_DESF_VAL4]; - if ( ( NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion == PH_FRINFC_DESF4_MAJOR_VERSION )&& - ( NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion == PH_FRINFC_DESF4_MINOR_VERSION )) + + if ((PH_FRINFC_DESF4_MAJOR_VERSION == NdefSmtCrdFmt->AddInfo.Type4Info.MajorVersion) && + (PH_FRINFC_DESF4_MINOR_VERSION == NdefSmtCrdFmt->AddInfo.Type4Info.MinorVersion)) { /* card size of DESFire4 type */ NdefSmtCrdFmt->AddInfo.Type4Info.CardSize = PH_FRINFC_DESF4_MEMORY_SIZE; @@ -930,6 +974,265 @@ NFCSTATUS phFriNfc_Desfire_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) return (status); } +#ifdef FRINFC_READONLY_NDEF + +#if 0 +static +NFCSTATUS +phFriNfc_Desf_HReadOnlySelectCCFile ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + return result; +} +#endif /* #if 0 */ + +static +NFCSTATUS +phFriNfc_Desf_HReadOnlyReadCCFile ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + uint16_t i = 0; + + if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) + && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) + { + NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_READ_CC_FILE; + + /* Class Byte */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CLASS_BYTE; + i++; + + /* let the place to store the cmd byte type, point to next index + Instruction Cmd code */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_READ_DATA_CMD; + i++; + + + /* P1/P2 offsets always set to zero */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P1; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P2; + i++; + + /* Lc: Length of wrapped data */ + NdefSmtCrdFmt->SendRecvBuf[i] = NATIVE_WRAPPER_READ_DATA_LC_VALUE; + i++; + +#ifdef DESFIRE_FMT_EV1 + if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) + { + /* set the file id*/ + NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_CC_FILE_ID; + i++; + } + else +#endif /* #ifdef DESFIRE_FMT_EV1 */ + { + /* set the file id*/ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID; + i++; + } + + /* set the offset to zero*/ + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + + /* Set the length of data available to read */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + + /* Le Value is set 0 */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; + i++; + + NdefSmtCrdFmt->SendLength = i; + + result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); + } + else + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_FORMAT_ERROR); + } + + return result; +} + +static +NFCSTATUS +phFriNfc_Desf_HReadOnlyWriteCCFile ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + uint8_t read_cc_btyes[CC_BYTES_SIZE] = {0}; + uint16_t i = 0; + + if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) + && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) + { + NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_UPDATE_CC_FILE; + + memcpy ((void *)read_cc_btyes, (void *)NdefSmtCrdFmt->SendRecvBuf, + sizeof (read_cc_btyes)); + read_cc_btyes[(sizeof (read_cc_btyes) - 1)] = READ_ONLY_NDEF_DESFIRE; + + /* Class Byte */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_CLASS_BYTE; + i++; + + /* let the place to store the cmd byte type, point to next index + Instruction Cmd code */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_WRITE_CMD; + i++; + + + /* P1/P2 offsets always set to zero */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P1; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_OFFSET_P2; + i++; + + /* Lc: Length of wrapped data */ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_WRCC_WRDT_LEN; + i++; + +#ifdef DESFIRE_FMT_EV1 + if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) + { + /* set the file id*/ + NdefSmtCrdFmt->SendRecvBuf[i] = DESFIRE_EV1_CC_FILE_ID; + i++; + } + else +#endif /* #ifdef DESFIRE_FMT_EV1 */ + { + /* set the file id*/ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_ID; + i++; + } + + /* set the offset to zero*/ + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + + /* Set the length of data available to write*/ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_CC_FILE_SIZE; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + NdefSmtCrdFmt->SendRecvBuf[i] = 0x00; + i++; + + /*set the data to be written to the CC file*/ + (void)memcpy ((void *)&NdefSmtCrdFmt->SendRecvBuf[i], + (void *)read_cc_btyes, sizeof (read_cc_btyes)); +#ifdef DESFIRE_FMT_EV1 +#else + i++; +#endif /* #ifdef DESFIRE_FMT_EV1 */ + + i = (uint16_t)(i + sizeof (read_cc_btyes)); + + /* Le bytes*/ + NdefSmtCrdFmt->SendRecvBuf[i] = PH_FRINFC_DESF_NATIVE_LE_BYTE; + i++; +#ifdef DESFIRE_FMT_EV1 + if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) + { + NdefSmtCrdFmt->SendLength = i; + } + else +#endif /* #ifdef DESFIRE_FMT_EV1 */ + { + NdefSmtCrdFmt->SendLength = PH_FRINFC_DESF_WRITECC_CMD_SNLEN; + } + + result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); + } + else + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_FORMAT_ERROR); + } + + return result; +} + +static +NFCSTATUS +phFriNfc_Desf_HReadOnlySelectApp ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + + NdefSmtCrdFmt->CardType = 0; + + NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_SELECT_APP; + + /* Helper routine to wrap the native DESFire cmds */ + phFriNfc_Desf_HWrapISONativeCmds (NdefSmtCrdFmt, PH_FRINFC_DESF_SELECTAPP_CMD); + + result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); + + return result; +} + +#ifdef DESFIRE_FMT_EV1 +static +NFCSTATUS +phFriNfc_Desf_HReadOnlySelectAppEV1 ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + + NdefSmtCrdFmt->CardType = DESFIRE_CARD_TYPE_EV1; + + NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_RO_SELECT_APP_EV1; + + /* Helper routine to wrap the native DESFire cmds */ + phFriNfc_Desf_HWrapISONativeCmds (NdefSmtCrdFmt, PH_FRINFC_DESF_SELECTAPP_CMD); + + result = phFriNfc_Desf_HSendTransCmd (NdefSmtCrdFmt); + + return result; +} +#endif /* #ifdef DESFIRE_FMT_EV1 */ + +NFCSTATUS +phFriNfc_Desfire_ConvertToReadOnly ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + +#ifdef DESFIRE_FMT_EV1 + result = phFriNfc_Desf_HReadOnlySelectAppEV1 (NdefSmtCrdFmt); +#else + result = phFriNfc_Desf_HReadOnlySelectApp (NdefSmtCrdFmt); +#endif /* #ifdef DESFIRE_FMT_EV1 */ + + return result; +} + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + void phFriNfc_Desf_Process( void *Context, NFCSTATUS Status) { @@ -942,6 +1245,69 @@ void phFriNfc_Desf_Process( void *Context, { switch(NdefSmtCrdFmt->State) { +#ifdef FRINFC_READONLY_NDEF +#ifdef DESFIRE_FMT_EV1 + case PH_FRINFC_DESF_STATE_RO_SELECT_APP_EV1: + { + if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) + && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) + { + Status = phFriNfc_Desf_HReadOnlyReadCCFile (NdefSmtCrdFmt); + } + else + { + Status = phFriNfc_Desf_HReadOnlySelectApp (NdefSmtCrdFmt); + } + break; + } +#endif /* #ifdef DESFIRE_FMT_EV1 */ + + case PH_FRINFC_DESF_STATE_RO_SELECT_APP: + { + Status = phFriNfc_Desf_HReadOnlyReadCCFile (NdefSmtCrdFmt); + break; + } + + case PH_FRINFC_DESF_STATE_RO_READ_CC_FILE: + { + Status = phFriNfc_Desf_HReadOnlyWriteCCFile (NdefSmtCrdFmt); + break; + } + + case PH_FRINFC_DESF_STATE_RO_UPDATE_CC_FILE: + { + if ((PH_FRINFC_DESF_NATIVE_RESP_BYTE1 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 2)]) + && (PH_FRINFC_DESF_NATIVE_RESP_BYTE2 == + NdefSmtCrdFmt->SendRecvBuf[(*NdefSmtCrdFmt->SendRecvLength - 1)])) + { + /* SUCCESSFULL Formatting */ +#ifdef DESFIRE_FMT_EV1 + if (DESFIRE_CARD_TYPE_EV1 == NdefSmtCrdFmt->CardType) + { + Status = phFriNfc_OvrHal_Reconnect ( + NdefSmtCrdFmt->LowerDevice, + &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo, + NdefSmtCrdFmt->psRemoteDevInfo); + + if (NFCSTATUS_PENDING == Status) + { + NdefSmtCrdFmt->State = PH_FRINFC_DESF_STATE_REACTIVATE; + } + } +#endif /* #ifdef DESFIRE_FMT_EV1 */ + } + else + { + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_FORMAT_ERROR); + } + break; + } + +#endif /* #ifdef FRINFC_READONLY_NDEF */ case PH_FRINFC_DESF_STATE_GET_HW_VERSION: { /* Check and store the h/w and s/w specific details. diff --git a/src/phFriNfc_DesfireFormat.h b/src/phFriNfc_DesfireFormat.h index ed829e2..cabb9b0 100644 --- a/src/phFriNfc_DesfireFormat.h +++ b/src/phFriNfc_DesfireFormat.h @@ -57,6 +57,18 @@ enum{ PH_FRINFC_DESF_STATE_GET_UID = 9, PH_FRINFC_DESF_STATE_GET_SW_VERSION = 10, PH_FRINFC_DESF_STATE_GET_HW_VERSION = 11, +#ifdef FRINFC_READONLY_NDEF + +#ifdef DESFIRE_FMT_EV1 + PH_FRINFC_DESF_STATE_RO_SELECT_APP_EV1 = 100, +#endif /* #ifdef DESFIRE_FMT_EV1 */ + + PH_FRINFC_DESF_STATE_RO_SELECT_APP = 101, + PH_FRINFC_DESF_STATE_RO_SELECT_CC_FILE = 102, + PH_FRINFC_DESF_STATE_RO_READ_CC_FILE = 103, + PH_FRINFC_DESF_STATE_RO_UPDATE_CC_FILE = 104, + +#endif /* #ifdef FRINFC_READONLY_NDEF */ /* following are used in the ISO wrapper commands*/ PH_FRINFC_DESF_CREATEAPP_CMD = 0, @@ -64,6 +76,9 @@ enum{ PH_FRINFC_DESF_CREATECC_CMD = 2, PH_FRINFC_DESF_CREATENDEF_CMD = 3, PH_FRINFC_DESF_WRITECC_CMD = 4, +#ifdef FRINFC_READONLY_NDEF + PH_FRINFC_DESF_WRITECC_CMD_READ_ONLY = 20, +#endif /* #ifdef FRINFC_READONLY_NDEF */ PH_FRINFC_DESF_WRITENDEF_CMD = 5, PH_FRINFC_DESF_GET_HW_VERSION_CMD = 6, PH_FRINFC_DESF_GET_SW_VERSION_CMD = 7, @@ -195,6 +210,43 @@ void phFriNfc_Desfire_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); */ NFCSTATUS phFriNfc_Desfire_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +/*! +* \brief \copydoc page_reg 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. +* +* \param[in] NdefSmtCrdFmt Pointer to a valid or uninitialized instance of \ref phFriNfc_sNdefSmtCrdFmt_t. +* +* \note This function has to be called at the beginning, after creating an instance of +* \ref phFriNfc_sNdefSmtCrdFmt_t. Use this function to reset the instance of smart card +formatting context variables. +*/ +void phFriNfc_Desfire_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); + +#ifdef FRINFC_READONLY_NDEF +/*! + * \ingroup grp_fri_smart_card_formatting + * + * \brief Initiates the conversion of the already NDEF formatted tag to READ ONLY. + * + * \copydoc page_ovr The function initiates the conversion of the already NDEF formatted + * tag to READ ONLY. After this formation, remote card would be properly Ndef Compliant and READ ONLY. + * Depending upon the different card type, this function handles formatting procedure. + * + * \param[in] phFriNfc_sNdefSmartCardFmt_t Pointer to a valid instance of the \ref phFriNfc_sNdefSmartCardFmt_t + * structure describing the component context. + * + * \retval NFCSTATUS_SUCCESS Card formatting has been successfully completed. + * \retval NFCSTATUS_PENDING The action has been successfully triggered. + * \retval NFCSTATUS_FORMAT_ERROR Error occured during the formatting procedure. + * \retval NFCSTATUS_INVALID_REMOTE_DEVICE Card Type is unsupported. + * \retval NFCSTATUS_INVALID_DEVICE_REQUEST Command or Operation types are mismatching. + * + */ +NFCSTATUS +phFriNfc_Desfire_ConvertToReadOnly ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +#endif /* #ifdef FRINFC_READONLY_NDEF */ + /** *\ingroup grp_fri_smart_card_formatting * diff --git a/src/phFriNfc_MifULFormat.c b/src/phFriNfc_MifULFormat.c index 894d455..8f3de28 100644 --- a/src/phFriNfc_MifULFormat.c +++ b/src/phFriNfc_MifULFormat.c @@ -40,6 +40,15 @@ #define PHFRINFCMIFULFORMAT_FILEREVISION "$Revision: 1.8 $" #define PHFRINFCMIFULFORMAT_FILEALIASES "$Aliases: NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $" /*@}*/ + +#ifdef FRINFC_READONLY_NDEF + /* Mifare UL OTP block number is 3 */ + #define OTP_BLOCK_NUMBER 0x03U + /* READ ONLY value that shall be written in the OTP to make the card read only */ + #define READ_ONLY_VALUE_IN_OTP 0x0FU + /* Mifare UL OTP block number is 3 */ + #define MIFARE_UL_READ_MAX_SIZE 16U +#endif /* #ifdef FRINFC_READONLY_NDEF */ /*! * \brief \copydoc page_ovr Helper function for Mifare UL. This function calls the * transceive function @@ -123,6 +132,23 @@ NFCSTATUS phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) return Result; } +#ifdef FRINFC_READONLY_NDEF + +NFCSTATUS +phFriNfc_MfUL_ConvertToReadOnly ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + + NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_RD_16BYTES; + + result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt); + + return result; +} + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + void phFriNfc_MfUL_Process(void *Context, NFCSTATUS Status) { @@ -156,6 +182,36 @@ void phFriNfc_MfUL_Process(void *Context, break; +#ifdef FRINFC_READONLY_NDEF + + case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES: + { + if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength) + { + uint8_t otp_page_size = 0; + + otp_page_size = sizeof (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes); + (void)memcpy (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, + NdefSmtCrdFmt->SendRecvBuf, + sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); + + NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[(otp_page_size - 1)] = + READ_ONLY_VALUE_IN_OTP; + + NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES; + Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); + } + break; + } + + case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES: + { + /* Do nothing */ + break; + } + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + #ifdef PH_NDEF_MIFARE_ULC case PH_FRINFC_MFUL_FMT_WR_TLV1: @@ -233,6 +289,42 @@ static void phFriNfc_MfUL_H_fillSendBuf( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFm NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_0] = (uint8_t)BlockNo; switch(NdefSmtCrdFmt->State) { +#ifdef FRINFC_READONLY_NDEF + + case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES: + { +#ifdef PH_HAL4_ENABLE + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; +#else + /* Read command */ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; +#endif /* #ifdef PH_HAL4_ENABLE */ + *NdefSmtCrdFmt->SendRecvBuf = OTP_BLOCK_NUMBER; + /* Send length for read command is always one */ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; + break; + } + + case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES: + { +#ifdef PH_HAL4_ENABLE + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; +#else + /* Read command */ + NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4; +#endif /* #ifdef PH_HAL4_ENABLE */ + + /* Send length for read command is always one */ + NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; + *NdefSmtCrdFmt->SendRecvBuf = OTP_BLOCK_NUMBER; + (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], + NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, + PH_FRINFC_MFUL_FMT_VAL_4); + break; + } + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + case PH_FRINFC_MFUL_FMT_RD_16BYTES: #ifdef PH_HAL4_ENABLE NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; diff --git a/src/phFriNfc_MifULFormat.h b/src/phFriNfc_MifULFormat.h index f3acd89..527dcc4 100644 --- a/src/phFriNfc_MifULFormat.h +++ b/src/phFriNfc_MifULFormat.h @@ -59,7 +59,11 @@ #define PH_FRINFC_MFUL_FMT_WR_TLV 3 /*!< Write TLV */ #ifdef PH_NDEF_MIFARE_ULC #define PH_FRINFC_MFUL_FMT_WR_TLV1 4 /*!< Write TLV (second part) */ -#endif /* #ifdef PH_NDEF_MIFARE_ULC */ +#endif /* #ifdef PH_NDEF_MIFARE_ULC */ +#ifdef FRINFC_READONLY_NDEF +#define PH_FRINFC_MFUL_FMT_RO_RD_16BYTES 5 /*!< Read only the tag */ +#define PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES 6 /*!< Write OTP bytes to make the tag Read only */ +#endif /* #ifdef FRINFC_READONLY_NDEF */ /*@}*/ @@ -160,6 +164,29 @@ void phFriNfc_MfUL_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); */ NFCSTATUS phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); +#ifdef FRINFC_READONLY_NDEF + +/*! + * \ingroup grp_fri_smart_card_formatting + * + * \brief Initiates the conversion of the already NDEF formatted tag to READ ONLY. + * + * \copydoc page_ovr The function initiates the conversion of the already NDEF formatted + * tag to READ ONLY.After this formation, remote card would be properly Ndef Compliant and READ ONLY. + * Depending upon the different card type, this function handles formatting procedure. + * + * \param[in] phFriNfc_sNdefSmartCardFmt_t Pointer to a valid instance of the \ref phFriNfc_sNdefSmartCardFmt_t + * structure describing the component context. + * \retval NFCSTATUS_PENDING The action has been successfully triggered. + * \retval Other values An error has occurred. + * + */ +NFCSTATUS +phFriNfc_MfUL_ConvertToReadOnly ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + /** *\ingroup grp_fri_smart_card_formatting * diff --git a/src/phFriNfc_NdefMap.c b/src/phFriNfc_NdefMap.c index a0389e4..89fc4b3 100644 --- a/src/phFriNfc_NdefMap.c +++ b/src/phFriNfc_NdefMap.c @@ -617,6 +617,47 @@ NFCSTATUS phFriNfc_NdefMap_WrNdef( phFriNfc_NdefMap_t *NdefMap, return status; } +#ifdef FRINFC_READONLY_NDEF +NFCSTATUS +phFriNfc_NdefMap_ConvertToReadOnly ( + phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS result = NFCSTATUS_PENDING; + + + /* Check for ndefmap context and relevant state. Else return error*/ + if (NULL == NdefMap) + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else if ((NdefMap->CompletionRoutine->CompletionRoutine == NULL) + || (NdefMap->CompletionRoutine->Context == NULL)) + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER); + } + else + { + switch (NdefMap->CardType) + { + case PH_FRINFC_NDEFMAP_TOPAZ_CARD: + case PH_FRINFC_NDEFMAP_TOPAZ_DYNAMIC_CARD: + { + result = phFriNfc_TopazMap_ConvertToReadOnly (NdefMap); + break; + } + + default: + { + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_REMOTE_DEVICE); + break; + } + } + } + return result; +} +#endif /* #ifdef FRINFC_READONLY_NDEF */ + /*! * Check whether a particular Remote Device is NDEF compliant. * diff --git a/src/phFriNfc_NdefMap.h b/src/phFriNfc_NdefMap.h index f708d74..e58e338 100644 --- a/src/phFriNfc_NdefMap.h +++ b/src/phFriNfc_NdefMap.h @@ -1114,6 +1114,29 @@ extern NFCSTATUS phFriNfc_NdefMap_WrNdef(phFriNfc_NdefMap_t *NdefMap, */ NFCSTATUS phFriNfc_NdefMap_ChkNdef(phFriNfc_NdefMap_t *NdefMap); +#ifdef FRINFC_READONLY_NDEF +/*! + * \ingroup grp_fri_smart_card_formatting + * + * \brief Initiates the conversion of the already NDEF formatted tag to READ ONLY. + * + * \copydoc page_ovr The function initiates the conversion of the already NDEF formatted + * tag to READ ONLY.After this formation, remote card would be properly Ndef Compliant and READ ONLY. + * Depending upon the different card type, this function handles formatting procedure. + * This function supports only for the TOPAZ tags. + * + * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing + * the component context. + * \retval NFCSTATUS_PENDING The action has been successfully triggered. + * \retval Other values An error has occurred. + * + */ +NFCSTATUS +phFriNfc_NdefMap_ConvertToReadOnly ( + phFriNfc_NdefMap_t *NdefMap); + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + /** * \ingroup grp_fri_nfc_ndef_map * diff --git a/src/phFriNfc_SmtCrdFmt.c b/src/phFriNfc_SmtCrdFmt.c index 5532862..0174c2d 100644 --- a/src/phFriNfc_SmtCrdFmt.c +++ b/src/phFriNfc_SmtCrdFmt.c @@ -184,6 +184,59 @@ NFCSTATUS phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt return status; } +#ifdef FRINFC_READONLY_NDEF + +NFCSTATUS +phFriNfc_NdefSmtCrd_ConvertToReadOnly ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) +{ + NFCSTATUS result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_INVALID_PARAMETER); + uint8_t sak = 0; + + if((NdefSmtCrdFmt != NULL) + && (NdefSmtCrdFmt->CompletionRoutine->CompletionRoutine != NULL) + && (NdefSmtCrdFmt->CompletionRoutine->Context != NULL)) + { + sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; + switch (NdefSmtCrdFmt->psRemoteDevInfo->RemDevType) + { + case phHal_eMifare_PICC: + { + if (0x00 == sak) + { + result = phFriNfc_MfUL_ConvertToReadOnly (NdefSmtCrdFmt); + } + else + { + /* MIFARE classic 1k/4k is not supported */ + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_INVALID_REMOTE_DEVICE); + } + break; + } + + case phHal_eISO14443_A_PICC: + { + result = phFriNfc_Desfire_ConvertToReadOnly (NdefSmtCrdFmt); + break; + } + + default : + { + /* Remote device is not recognised. + Probably not NDEF compliant */ + result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_INVALID_REMOTE_DEVICE); + break; + } + } + } + return result; +} + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + /*! * \brief Used to format the different smart cards. diff --git a/src/phFriNfc_SmtCrdFmt.h b/src/phFriNfc_SmtCrdFmt.h index 21bac7d..c63be23 100644 --- a/src/phFriNfc_SmtCrdFmt.h +++ b/src/phFriNfc_SmtCrdFmt.h @@ -61,6 +61,9 @@ during the implementation phase. */ +#define DESFIRE_FMT_EV1 + + #define PH_FRI_NFC_SMTCRDFMT_NFCSTATUS_FORMAT_ERROR 9 #define PH_FRINFC_SMTCRDFMT_MSTD_DEFAULT_KEYA_OR_KEYB {0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF} #define PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA {0xA0, 0xA1,0xA2,0xA3,0xA4,0xA5} @@ -399,6 +402,30 @@ NFCSTATUS phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt NFCSTATUS phFriNfc_NdefSmtCrd_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB); +#ifdef FRINFC_READONLY_NDEF +/*! + * \ingroup grp_fri_smart_card_formatting + * + * \brief Initiates the conversion of the already NDEF formatted tag to READ ONLY. + * + * \copydoc page_ovr The function initiates the conversion of the already NDEF formatted + * tag to READ ONLY.After this formation, remote card would be properly Ndef Compliant and READ ONLY. + * Depending upon the different card type, this function handles formatting procedure. + * This function supports only for the DESFIRE, MIFARE UL and TOPAZ tags. + * + * \param[in] phFriNfc_sNdefSmtCrdFmt_t Pointer to a valid instance of the \ref phFriNfc_sNdefSmartCardFmt_t + * structure describing the component context. + * \retval NFCSTATUS_PENDING The action has been successfully triggered. + * \retval Other values An error has occurred. + * + */ +NFCSTATUS +phFriNfc_NdefSmtCrd_ConvertToReadOnly ( + phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + + /** *\ingroup grp_fri_smart_card_formatting * diff --git a/src/phFriNfc_TopazMap.c b/src/phFriNfc_TopazMap.c index 8901aa7..ff445cb 100644 --- a/src/phFriNfc_TopazMap.c +++ b/src/phFriNfc_TopazMap.c @@ -53,6 +53,14 @@ */ /* #define TOPAZ_RF_ERROR_WORKAROUND */ +#ifdef FRINFC_READONLY_NDEF + + #define CC_BLOCK_NUMBER (0x01U) + #define CC_RWA_BYTE_NUMBER (0x03U) + #define CC_READ_ONLY_VALUE (0x0FU) + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + #ifdef TOPAZ_RF_ERROR_WORKAROUND /* Below MACROs are added for the error returned from HAL, if the @@ -277,6 +285,25 @@ NFCSTATUS phFriNfc_TopazMap_ChkNdef( phFriNfc_NdefMap_t *NdefMap) return Result; } +#ifdef FRINFC_READONLY_NDEF + +NFCSTATUS +phFriNfc_TopazMap_ConvertToReadOnly ( + phFriNfc_NdefMap_t *NdefMap) +{ + NFCSTATUS result = NFCSTATUS_SUCCESS; + + result = phFriNfc_Tpz_H_WrAByte (NdefMap, CC_BLOCK_NUMBER, + CC_RWA_BYTE_NUMBER, CC_READ_ONLY_VALUE); + + if (NFCSTATUS_PENDING == PHNFCSTATUS(result)) + { + NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ_ONLY; + } + return result; +} + +#endif /* #ifdef FRINFC_READONLY_NDEF */ /*! * \brief Initiates Reading of NDEF information from the Remote Device. @@ -482,6 +509,22 @@ void phFriNfc_TopazMap_Process( void *Context, { switch (psNdefMap->State) { +#ifdef FRINFC_READONLY_NDEF + case PH_FRINFC_TOPAZ_STATE_READ_ONLY: + { + if((CC_READ_ONLY_VALUE == *psNdefMap->SendRecvBuf) + && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)) + { + /* Do nothing */ + } + else + { + Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_INVALID_RECEIVE_LENGTH); + } + break; + } +#endif /* #ifdef FRINFC_READONLY_NDEF */ case PH_FRINFC_TOPAZ_STATE_WRITE: { Status = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap); @@ -821,9 +864,9 @@ static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap, /*Copy UID of the tag to Send Buffer*/ (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]), &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid), - (NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength)); + TOPAZ_UID_LENGTH_FOR_READ_WRITE); - index = index + NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength; + index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE); /* Update the length of the command buffer*/ NdefMap->SendLength = index; @@ -866,8 +909,8 @@ static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap, /*Copy UID of the tag to Send Buffer*/ (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]), &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid), - (NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength)); - index = index + NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength; + TOPAZ_UID_LENGTH_FOR_READ_WRITE); + index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE); /* Update the length of the command buffer*/ NdefMap->SendLength = index; @@ -968,8 +1011,8 @@ static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap, /*Copy UID of the tag to Send Buffer*/ (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]), &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid), - (NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength)); - index = index + NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength; + TOPAZ_UID_LENGTH_FOR_READ_WRITE); + index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE); /* Update the length of the command buffer*/ NdefMap->SendLength = index; diff --git a/src/phFriNfc_TopazMap.h b/src/phFriNfc_TopazMap.h index d13faac..967a6ce 100644 --- a/src/phFriNfc_TopazMap.h +++ b/src/phFriNfc_TopazMap.h @@ -20,10 +20,10 @@ * * Project: NFC-FRI * - * $Date: Tue Mar 30 11:51:44 2010 $ + * $Date: Tue Aug 31 15:13:10 2010 $ * $Author: ing02260 $ - * $Revision: 1.24 $ - * $Aliases: NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $ + * $Revision: 1.25 $ + * $Aliases: $ * */ @@ -31,16 +31,18 @@ #define PHFRINFC_TOPAZMAP_H #include <phFriNfc.h> -#if !defined PH_HAL4_ENABLE +#ifdef PH_HAL4_ENABLE #include <phHal4Nfc.h> +#else +#include <phHalNfc.h> #endif #include <phNfcStatus.h> #include <phNfcTypes.h> #include <phFriNfc_NdefMap.h> -#define PH_FRINFC_NDEFMAP_TOPAZMAP_FILEREVISION "$Revision: 1.24 $" -#define PH_FRINFC_NDEFMAP_TOPAZMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $" +#define PH_FRINFC_NDEFMAP_TOPAZMAP_FILEREVISION "$Revision: 1.25 $" +#define PH_FRINFC_NDEFMAP_TOPAZMAP_FILEALIASES "$Aliases: $" #if !defined (ES_HW_VER) @@ -57,6 +59,8 @@ #endif /* #if (ES_HW_VER == 32) */ +#define TOPAZ_UID_LENGTH_FOR_READ_WRITE 0x04U + /*! * \name Topaz - states of the Finite State machine * @@ -70,6 +74,12 @@ #define PH_FRINFC_TOPAZ_STATE_WRITE_NMN 6 /*!< Write ndef magic number */ #define PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV 7 /*!< Write length field of TLV */ #define PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV 8 /*!< Write CC or NDEF TLV */ + +#ifdef FRINFC_READONLY_NDEF + + #define PH_FRINFC_TOPAZ_STATE_READ_ONLY 9 /*!< READ ONLY state */ + +#endif /* #ifdef FRINFC_READONLY_NDEF */ /*@}*/ /*! @@ -223,6 +233,30 @@ enum */ void phFriNfc_TopazMap_H_Reset( phFriNfc_NdefMap_t *NdefMap); +#ifdef FRINFC_READONLY_NDEF + +/*! + * \ingroup grp_fri_smart_card_formatting + * + * \brief Initiates the conversion of the already NDEF formatted tag to READ ONLY. + * + * \copydoc page_ovr The function initiates the conversion of the already NDEF formatted + * tag to READ ONLY.After this formation, remote card would be properly Ndef Compliant and READ ONLY. + * Depending upon the different card type, this function handles formatting procedure. + * This function supports only for the TOPAZ tags. + * + * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing + * the component context. + * \retval NFCSTATUS_PENDING The action has been successfully triggered. + * \retval Other values An error has occurred. + * + */ +NFCSTATUS +phFriNfc_TopazMap_ConvertToReadOnly ( + phFriNfc_NdefMap_t *NdefMap); + +#endif /* #ifdef FRINFC_READONLY_NDEF */ + /*! * \brief \copydoc page_ovr Initiates Reading of NDEF information from the Remote Device. * diff --git a/src/phLibNfc.h b/src/phLibNfc.h index f96b86d..0ef7522 100644 --- a/src/phLibNfc.h +++ b/src/phLibNfc.h @@ -46,6 +46,7 @@ *\def PHLIBNFC_MAXNO_OF_SE *Defines maximum no of secured elements supported by PN544. */ +#define LIBNFC_READONLY_NDEF #define PHLIBNFC_MAXNO_OF_SE (0x02) typedef uint32_t phLibNfc_Handle; @@ -1928,6 +1929,76 @@ NFCSTATUS phLibNfc_RemoteDev_FormatNdef(phLibNfc_Handle hRemoteDevice, void* pContext ); +#ifdef LIBNFC_READONLY_NDEF +/** +* \ingroup grp_lib_nfc +* +* \brief To convert a already formatted NDEF READ WRITE tag to READ ONLY. +* +* This function allows the LibNfc client to convert a already formatted NDEF READ WRITE +* tag to READ ONLY on discovered target. +* +*\note +* <br>1. Prior to formating it is recommended to perform NDEF check using \ref phLibNfc_Ndef_CheckNdef interface. +* <br>2. READ ONLY feature supported only for MIFARE UL and Desfire tag types. +* If the call back error code is NFCSTATUS_FAILED then the LIBNFC client has to do the +* phLibNfc_RemoteDev_CheckPresence to find, its communication error or target lost. +* +*\param[in] hRemoteDevice handle of the remote device.This handle to be +* same as as handle obtained for specific remote device +* during device discovery. +*\param[in] pNdefReadOnly_RspCb Response callback defined by the caller. +*\param[in] pContext Client context which will be included in +* callback when the request is completed. +* +* +* \retval NFCSTATUS_PENDING Request accepted and started. +* \retval NFCSTATUS_SHUTDOWN Shutdown in progress. +* \retval NFCSTATUS_INVALID_HANDLE Target handle is invalid. +* \retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized. +* \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters could not +* be properly interpreted. +* \retval NFCSTATUS_TARGET_NOT_CONNECTED The Remote Device is not connected. +* \retval NFCSTATUS_FAILED operation failed. +* \retval NFCSTATUS_REJECTED Tag is already formatted one. +* +*\msc +*LibNfcClient,LibNfc; +*LibNfcClient=>LibNfc [label="phLibNfc_Mgt_Initialize()",URL="\ref phLibNfc_Mgt_Initialize"]; +*LibNfcClient<-LibNfc [label="pInitCb()",URL="\ref pphLibNfc_RspCb_t()"]; +*LibNfcClient=>LibNfc [label="phLibNfc_RemoteDev_NtfRegister()",URL="\ref phLibNfc_RemoteDev_NtfRegister"]; +*LibNfcClient<<LibNfc [label="NFCSTATUS_SUCCESS"]; +*LibNfcClient=>LibNfc [label="phLibNfc_Mgt_configureDiscovery()",URL="\ref phLibNfc_Mgt_ConfigureDiscovery"]; +*LibNfcClient<-LibNfc [label="pConfigDiscovery_RspCb",URL="\ref pphLibNfc_RspCb_t"]; +*--- [label="Now Present NDEF Tag "]; +*LibNfcClient<-LibNfc [label="pNotificationHandler",URL="\ref phLibNfc_NtfRegister_RspCb_t"]; +*LibNfcClient=>LibNfc [label="phLibNfc_RemoteDev_Connect()",URL="\ref phLibNfc_RemoteDev_Connect"]; +*LibNfcClient<-LibNfc [label="pNotifyConnect_RspCb",URL="\ref pphLibNfc_RspCb_t"]; +*LibNfcClient=>LibNfc [label="phLibNfc_Ndef_CheckNdef()",URL="\ref phLibNfc_Ndef_CheckNdef "]; +*LibNfcClient<-LibNfc [label="pCheckNdef_RspCb",URL="\ref pphLibNfc_RspCb_t"]; +*--- [label="Tag found to be NDEF compliant ,now convert the tag to read only"]; +*LibNfcClient=>LibNfc [label="phLibNfc_ConvertToReadOnlyNdef()",URL="\ref phLibNfc_ConvertToReadOnlyNdef "]; +*LibNfcClient<-LibNfc [label="pNdefReadOnly_RspCb",URL="\ref pphLibNfc_RspCb_t"]; +* +*\endmsc +* +*\note Response callback parameters details for this interface are as listed below. +* +* \param[in] pContext LibNfc client context passed in the corresponding request before. +* \param[in] status Status of the response callback. +* +* \param NFCSTATUS_SUCCESS Converting the tag to READ ONLY NDEF is successful. +* \param NFCSTATUS_SHUTDOWN Shutdown in progress. +* \param NFCSTATUS_ABORTED, Aborted due to disconnect operation in between. +* \param NFCSTATUS_FAILED Request failed. +*/ + +NFCSTATUS phLibNfc_ConvertToReadOnlyNdef (phLibNfc_Handle hRemoteDevice, + pphLibNfc_RspCb_t pNdefReadOnly_RspCb, + void* pContext + ); +#endif /* #ifdef LIBNFC_READONLY_NDEF */ + /** * \ingroup grp_lib_nfc * \brief <b>Search for NDEF Record type</b>. diff --git a/src/phLibNfc_ndef_raw.c b/src/phLibNfc_ndef_raw.c index 4c3d647..6b7bfe5 100644 --- a/src/phLibNfc_ndef_raw.c +++ b/src/phLibNfc_ndef_raw.c @@ -81,6 +81,14 @@ void phLibNfc_Ndef_Read_Cb(void* Context,NFCSTATUS status); STATIC void phLibNfc_Ndef_format_Cb(void *Context,NFCSTATUS status); +#ifdef LIBNFC_READONLY_NDEF +STATIC +void +phLibNfc_Ndef_ReadOnly_Cb ( + void *p_context, + NFCSTATUS status); +#endif /* #ifdef LIBNFC_READONLY_NDEF */ + /* Response callback for Search Ndef Content */ STATIC void phLibNfc_Ndef_SrchNdefCnt_Cb(void *context, NFCSTATUS status); @@ -1179,6 +1187,9 @@ void phLibNfc_Reconnect_Mifare_Cb ( } break; case NdefFmt: +#ifdef LIBNFC_READONLY_NDEF + case NdefReadOnly: +#endif /* #ifdef LIBNFC_READONLY_NDEF */ { pphLibNfc_RspCb_t pClientCb = pLibNfc_Ctxt->ndef_cntx.pClientNdefFmtCb; @@ -1323,6 +1334,171 @@ NFCSTATUS phLibNfc_RemoteDev_FormatNdef(phLibNfc_Handle hRemoteDevice, return RetVal; } +#ifdef LIBNFC_READONLY_NDEF + +NFCSTATUS +phLibNfc_ConvertToReadOnlyNdef ( + phLibNfc_Handle hRemoteDevice, + pphLibNfc_RspCb_t pNdefReadOnly_RspCb, + void* pContext + ) +{ + NFCSTATUS ret_val = NFCSTATUS_FAILED; + + if ((NULL == gpphLibContext) + || (gpphLibContext->LibNfcState.cur_state + == eLibNfcHalStateShutdown)) + { + /* LibNfc not initialized */ + ret_val = NFCSTATUS_NOT_INITIALISED; + } + else if ((NULL == pContext) + || (NULL == pNdefReadOnly_RspCb) + || (0 == hRemoteDevice)) + { + ret_val = NFCSTATUS_INVALID_PARAMETER; + } + else if (gpphLibContext->LibNfcState.next_state + == eLibNfcHalStateShutdown) + { + ret_val = NFCSTATUS_SHUTDOWN; + } + else if (0 == gpphLibContext->Connected_handle) + { + ret_val = NFCSTATUS_TARGET_NOT_CONNECTED; + } + else if (hRemoteDevice != gpphLibContext->Connected_handle) + { + ret_val = NFCSTATUS_INVALID_HANDLE; + } + else if ((TRUE == gpphLibContext->status.GenCb_pending_status) + || (NULL != gpphLibContext->ndef_cntx.pClientNdefFmtCb) + || (FALSE == gpphLibContext->ndef_cntx.is_ndef)) + { + /* Previous Callback is Pending */ + ret_val = NFCSTATUS_REJECTED; + PHDBG_INFO("LIbNfc:Previous Callback is Pending"); + } + else if (PH_NDEFMAP_CARD_STATE_READ_WRITE != + gpphLibContext->ndef_cntx.psNdefMap->CardState) + { + /* Tag is in different state */ + ret_val = NFCSTATUS_REJECTED; + } + else + { + gpphLibContext->ndef_cntx.eLast_Call = NdefReadOnly; + + if(eLibNfcHalStatePresenceChk != gpphLibContext->LibNfcState.next_state) + { + phHal_sRemoteDevInformation_t *ps_rem_dev_info = + (phHal_sRemoteDevInformation_t *)hRemoteDevice; + uint8_t fun_id; + + switch (ps_rem_dev_info->RemDevType) + { + case phHal_eMifare_PICC: + case phHal_eISO14443_A_PICC: + { + if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType) + && (0x00 != ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak)) + { + /* Mifare classic 1k/4k not supported */ + ret_val = NFCSTATUS_REJECTED; + } + else + { + gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN; + + /* Call ndef format reset, this will initialize the ndef + format structure, and appropriate values are filled */ + ret_val = phFriNfc_NdefSmtCrd_Reset (gpphLibContext->ndef_cntx.ndef_fmt, + gpphLibContext->psOverHalCtxt, + (phHal_sRemoteDevInformation_t*)hRemoteDevice, + gpphLibContext->psDevInputParam, + gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf, + &(gpphLibContext->ndef_cntx.NdefSendRecvLen)); + + for(fun_id = 0; fun_id < PH_FRINFC_SMTCRDFMT_CR; fun_id++) + { + /* Register for all the callbacks */ + ret_val = phFriNfc_NdefSmtCrd_SetCR (gpphLibContext->ndef_cntx.ndef_fmt, + fun_id, phLibNfc_Ndef_ReadOnly_Cb, + gpphLibContext); + } + + /* Start smart card formatting function */ + ret_val = phFriNfc_NdefSmtCrd_ConvertToReadOnly ( + gpphLibContext->ndef_cntx.ndef_fmt); + ret_val = PHNFCSTATUS(ret_val); + } + break; + } + + case phHal_eJewel_PICC: + { + static uint16_t data_cnt = 0; + + /* Resets the component instance */ + ret_val = phFriNfc_NdefMap_Reset (gpphLibContext->ndef_cntx.psNdefMap, + gpphLibContext->psOverHalCtxt, + (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice, + gpphLibContext->psDevInputParam, + gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf, + gpphLibContext->ndef_cntx.NdefSendRecvLen, + gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf, + &(gpphLibContext->ndef_cntx.NdefSendRecvLen), + &(data_cnt)); + + + for (fun_id = 0; fun_id < PH_FRINFC_NDEFMAP_CR; fun_id++) + { + /* Register the callback for the check ndef */ + ret_val = phFriNfc_NdefMap_SetCompletionRoutine ( + gpphLibContext->ndef_cntx.psNdefMap, + fun_id, phLibNfc_Ndef_ReadOnly_Cb, + (void *)gpphLibContext); + } + + /* call below layer check Ndef function */ + ret_val = phFriNfc_NdefMap_ConvertToReadOnly ( + gpphLibContext->ndef_cntx.psNdefMap); + ret_val = PHNFCSTATUS(ret_val); + break; + } + + default: + { + /* Tag not supported */ + ret_val = NFCSTATUS_REJECTED; + break; + } + } + } + else + { + gpphLibContext->ndef_cntx.pClientNdefFmtCb= NULL; + ret_val = NFCSTATUS_PENDING; + } + + if (NFCSTATUS_PENDING == ret_val) + { + gpphLibContext->ndef_cntx.pClientNdefFmtCb = pNdefReadOnly_RspCb; + gpphLibContext->ndef_cntx.pClientNdefFmtCntx = pContext; + + gpphLibContext->status.GenCb_pending_status = TRUE; + gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; + } + else + { + ret_val = NFCSTATUS_FAILED; + } + } + return ret_val; +} + +#endif /* #ifdef LIBNFC_READONLY_NDEF */ + /** * Response callback for NDEF format. */ @@ -1400,6 +1576,69 @@ void phLibNfc_Ndef_format_Cb(void *Context,NFCSTATUS status) return; } +#ifdef LIBNFC_READONLY_NDEF +STATIC +void +phLibNfc_Ndef_ReadOnly_Cb ( + void *p_context, + NFCSTATUS status) +{ + NFCSTATUS ret_status = NFCSTATUS_SUCCESS; + pphLibNfc_RspCb_t p_client_cb = NULL; + phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)p_context; + void *p_upper_layer_ctxt = NULL; + + if(pLibNfc_Ctxt != gpphLibContext) + { + /*wrong context returned*/ + phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + } + else + { + if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) + { + /*shutdown is pending so issue shutdown*/ + phLibNfc_Pending_Shutdown(); + ret_status = NFCSTATUS_SHUTDOWN; + } + else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) + { + ret_status = NFCSTATUS_ABORTED; + } + else + { + gpphLibContext->status.GenCb_pending_status = FALSE; + if(NFCSTATUS_SUCCESS == status) + { + gpphLibContext->ndef_cntx.psNdefMap->CardState = + PH_NDEFMAP_CARD_STATE_READ_ONLY; + ret_status = NFCSTATUS_SUCCESS; + } + else + { + ret_status = NFCSTATUS_FAILED; + } + gpphLibContext->LibNfcState.cur_state =eLibNfcHalStateConnect; + } + + phLibNfc_UpdateCurState(status, gpphLibContext); + + p_client_cb = gpphLibContext->ndef_cntx.pClientNdefFmtCb; + p_upper_layer_ctxt = gpphLibContext->ndef_cntx.pClientNdefFmtCntx; + gpphLibContext->ndef_cntx.pClientNdefFmtCb = NULL; + gpphLibContext->ndef_cntx.pClientNdefFmtCntx = NULL; + if(NFCSTATUS_PENDING != ret_status) + { + if (NULL != p_client_cb) + { + /* Call the tag format upper layer callback */ + p_client_cb (p_upper_layer_ctxt, ret_status); + } + } + } +} +#endif /* #ifdef LIBNFC_READONLY_NDEF */ + STATIC void phLibNfc_Ndef_SrchNdefCnt_Cb(void *context, NFCSTATUS status) { diff --git a/src/phLibNfc_ndef_raw.h b/src/phLibNfc_ndef_raw.h index ac31f72..ffeff2c 100644 --- a/src/phLibNfc_ndef_raw.h +++ b/src/phLibNfc_ndef_raw.h @@ -34,6 +34,9 @@ typedef enum phLibNfc_Last_Call{ NdefRd, NdefWr, NdefFmt, +#ifdef LIBNFC_READONLY_NDEF + NdefReadOnly, +#endif /* #ifdef LIBNFC_READONLY_NDEF */ RawTrans } phLibNfc_Last_Call_t; |