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
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 @@
 /* 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 @@
 #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 @@
 /* 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 @@
     {
         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 @@
     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 @@
     {
         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 @@
     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 @@
     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 @@
 */
 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 @@
     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 @@
 
             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 @@
     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 @@
  */
 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 @@
     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 @@
  */
 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 @@
     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_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 @@
     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 @@
     {
         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 @@
         /*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 @@
         /*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 @@
     /*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 @@
  */
 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 @@
                                         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 @@
 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 @@
         }
         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 @@
     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 @@
     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 @@
                     NdefRd,
                     NdefWr,
                     NdefFmt,
+#ifdef LIBNFC_READONLY_NDEF
+                    NdefReadOnly,
+#endif /* #ifdef LIBNFC_READONLY_NDEF */
                     RawTrans
 } phLibNfc_Last_Call_t;