summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/phFriNfc.h6
-rw-r--r--src/phFriNfc_DesfireFormat.c376
-rw-r--r--src/phFriNfc_DesfireFormat.h52
-rw-r--r--src/phFriNfc_MifULFormat.c92
-rw-r--r--src/phFriNfc_MifULFormat.h29
-rw-r--r--src/phFriNfc_NdefMap.c41
-rw-r--r--src/phFriNfc_NdefMap.h23
-rw-r--r--src/phFriNfc_SmtCrdFmt.c53
-rw-r--r--src/phFriNfc_SmtCrdFmt.h27
-rw-r--r--src/phFriNfc_TopazMap.c55
-rw-r--r--src/phFriNfc_TopazMap.h46
-rw-r--r--src/phLibNfc.h71
-rw-r--r--src/phLibNfc_ndef_raw.c239
-rw-r--r--src/phLibNfc_ndef_raw.h3
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;