diff options
-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; |