Support formatting / makeReadOnly() of NDEF on ICODE.

Change-Id: I2a7a185ead5de8f2b165c81dcc8ab8fb46c1ddc0
diff --git a/Android.mk b/Android.mk
index 5dc9682..0557a87 100644
--- a/Android.mk
+++ b/Android.mk
@@ -89,6 +89,7 @@
 LOCAL_SRC_FILES += src/phFriNfc_MifULFormat.c
 LOCAL_SRC_FILES += src/phFriNfc_MifStdFormat.c
 LOCAL_SRC_FILES += src/phFriNfc_SmtCrdFmt.c
+LOCAL_SRC_FILES += src/phFriNfc_ISO15693Format.c
 
 #phFriNfc_OvrHal
 LOCAL_SRC_FILES += src/phFriNfc_OvrHal.c
diff --git a/src/phFriNfc.h b/src/phFriNfc.h
index fb4b5ee..3677405 100644
--- a/src/phFriNfc.h
+++ b/src/phFriNfc.h
@@ -67,6 +67,7 @@
 #define PH_FRINFC_FMT_DESFIRE_DISABLED
 #define PH_FRINFC_FMT_MIFAREUL_DISABLED
 #define PH_FRINFC_FMT_MIFARESTD_DISABLED
+#define PH_FRINFC_FMT_ISO15693_DISABLED
 #endif /* #ifdef DISABLE_FORMAT */
 
 #define PH_FRINFC_FMT_TOPAZ_DISABLED
diff --git a/src/phFriNfc_ISO15693Format.c b/src/phFriNfc_ISO15693Format.c
new file mode 100644
index 0000000..574c107
--- /dev/null
+++ b/src/phFriNfc_ISO15693Format.c
@@ -0,0 +1,594 @@
+/*
+/*
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*!
+* \file  phFriNfc_ISO15693Format.c
+* \brief This component encapsulates different format functinalities ,
+*        for the ISO-15693 card. 
+*
+* Project: NFC-FRI
+*
+* $Date:  $
+* $Author: ing02260 $
+* $Revision: 1.0 $
+* $Aliases:  $
+*
+*/
+
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+
+#include <phNfcTypes.h>
+#include <phFriNfc_OvrHal.h>
+#include <phFriNfc_SmtCrdFmt.h>
+#include <phFriNfc_ISO15693Format.h>
+
+
+/****************************** Macro definitions start ********************************/
+/* State for the format */
+#define ISO15693_FORMAT                                 0x01U
+
+/* Bytes per block in the ISO-15693 */
+#define ISO15693_BYTES_PER_BLOCK                        0x04U
+
+/* ISO-15693 Commands 
+GET SYSTEM INFORMATION COMMAND
+*/
+#define ISO15693_GET_SYSTEM_INFO_CMD                    0x2BU
+/* READ SINGLE BLOCK COMMAND */
+#define ISO15693_RD_SINGLE_BLK_CMD                      0x20U
+/* WRITE SINGLE BLOCK COMMAND */
+#define ISO15693_WR_SINGLE_BLK_CMD                      0x21U
+/* READ MULTIPLE BLOCK COMMAND */
+#define ISO15693_RD_MULTIPLE_BLKS_CMD                   0x23U
+
+/* CC bytes 
+CC BYTE 0 - Magic Number - 0xE1
+*/
+#define ISO15693_CC_MAGIC_NUM                           0xE1U
+/* CC BYTE 1 - Mapping version and READ WRITE settings 0x40
+*/
+#define ISO15693_CC_VER_RW                              0x40U
+/* CC BYTE 2 - max size is calaculated using the byte 3 multiplied by 8 */
+#define ISO15693_CC_MULTIPLE_FACTOR                     0x08U
+
+/* Inventory command support mask for the CC byte 4 */
+#define ISO15693_INVENTORY_CMD_MASK                     0x02U
+/* Read MULTIPLE blocks support mask for CC byte 4 */
+#define ISO15693_RDMULBLKS_CMD_MASK                     0x01U
+/* Flags for the command */
+#define ISO15693_FMT_FLAGS                              0x20U
+
+/* Read two blocks */
+#define ISO15693_RD_2_BLOCKS                            0x02U
+
+/* TYPE identifier of the NDEF TLV */
+#define ISO15693_NDEF_TLV_TYPE_ID                       0x03U
+/* Terminator TLV identifier  */
+#define ISO15693_TERMINATOR_TLV_ID                      0xFEU
+
+/* UID 7th byte value shall be 0xE0 */
+#define ISO15693_7TH_BYTE_UID_VALUE                     0xE0U
+#define ISO15693_BYTE_7_INDEX                           0x07U
+
+/* UID 6th byte value shall be 0x04 - NXP manufacturer */
+#define ISO15693_6TH_BYTE_UID_VALUE                     0x04U
+#define ISO15693_BYTE_6_INDEX                           0x06U
+
+#define ISO15693_EXTRA_RESPONSE_FLAG                    0x01U
+
+#define ISO15693_GET_SYS_INFO_RESP_LEN                  0x0EU
+#define ISO15693_DSFID_MASK                             0x01U
+#define ISO15693_AFI_MASK                               0x02U
+#define ISO15693_MAX_SIZE_MASK                          0x04U
+#define ISO15693_ICREF_MASK                             0x08U
+#define ISO15693_SKIP_DFSID                             0x01U
+#define ISO15693_SKIP_AFI                               0x01U
+#define ISO15693_BLOCK_SIZE_IN_BYTES_MASK               0x1FU
+
+
+/* MAXimum size of ICODE SLI/X */
+#define ISO15693_SLI_X_MAX_SIZE                         112U
+/* MAXimum size of ICODE SLI/X - S */
+#define ISO15693_SLI_X_S_MAX_SIZE                       160U
+/* MAXimum size of ICODE SLI/X - L */
+#define ISO15693_SLI_X_L_MAX_SIZE                       32U
+/****************************** Macro definitions end ********************************/
+
+/****************************** Data structures start ********************************/
+typedef enum phFriNfc_ISO15693_FormatSeq
+{
+    ISO15693_GET_SYS_INFO, 
+    ISO15693_RD_MULTIPLE_BLKS_CHECK, 
+    ISO15693_WRITE_CC_FMT, 
+    ISO15693_WRITE_NDEF_TLV
+}phFriNfc_ISO15693_FormatSeq_t;
+/****************************** Data structures end ********************************/
+
+/*********************** Static function declarations start ***********************/
+static 
+NFCSTATUS 
+phFriNfc_ISO15693_H_ProFormat (
+    phFriNfc_sNdefSmtCrdFmt_t   *psNdefSmtCrdFmt);
+
+static 
+NFCSTATUS 
+phFriNfc_ISO15693_H_GetMaxDataSize (
+    phFriNfc_sNdefSmtCrdFmt_t   *psNdefSmtCrdFmt, 
+    uint8_t                     *p_recv_buf, 
+    uint8_t                     recv_length);
+
+static 
+NFCSTATUS 
+phFriNfc_ISO15693_H_FmtReadWrite (
+    phFriNfc_sNdefSmtCrdFmt_t   *psNdefSmtCrdFmt, 
+    uint8_t                     command, 
+    uint8_t                     *p_data, 
+    uint8_t                     data_length);
+/*********************** Static function declarations end ***********************/
+
+/*********************** Static function definitions start ***********************/
+
+static 
+NFCSTATUS 
+phFriNfc_ISO15693_H_FmtReadWrite (
+    phFriNfc_sNdefSmtCrdFmt_t   *psNdefSmtCrdFmt, 
+    uint8_t                     command, 
+    uint8_t                     *p_data, 
+    uint8_t                     data_length)
+{
+    NFCSTATUS                   result = NFCSTATUS_SUCCESS;
+    uint8_t                     send_index = 0;
+
+    /* set the data for additional data exchange*/
+    psNdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
+    psNdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0;
+    psNdefSmtCrdFmt->psDepAdditionalInfo.NAD = 0;
+
+    psNdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = 
+                                            phFriNfc_ISO15693_FmtProcess;
+    psNdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = psNdefSmtCrdFmt;
+
+    *psNdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
+
+    psNdefSmtCrdFmt->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
+
+    *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)ISO15693_FMT_FLAGS;
+    send_index = (uint8_t)(send_index + 1);
+
+    *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)command;
+    send_index = (uint8_t)(send_index + 1);
+
+    (void)memcpy ((void *)(psNdefSmtCrdFmt->SendRecvBuf + send_index), 
+        (void *)psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid, 
+        psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+    send_index = (uint8_t)(send_index + 
+            psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+
+    switch (command)
+    {        
+        case ISO15693_WR_SINGLE_BLK_CMD:
+        case ISO15693_RD_MULTIPLE_BLKS_CMD:
+        {
+            *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)
+                        psNdefSmtCrdFmt->AddInfo.s_iso15693_info.current_block;
+            send_index = (uint8_t)(send_index + 1);
+
+            if (data_length)
+            {
+                (void)memcpy ((void *)(psNdefSmtCrdFmt->SendRecvBuf + send_index), 
+                            (void *)p_data, data_length);
+                send_index = (uint8_t)(send_index + data_length);
+            }
+            else
+            {
+                result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                                    NFCSTATUS_INVALID_DEVICE_REQUEST);
+            }
+            break;
+        }
+
+        case ISO15693_RD_SINGLE_BLK_CMD:
+        {
+            *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)
+                        psNdefSmtCrdFmt->AddInfo.s_iso15693_info.current_block;
+            send_index = (uint8_t)(send_index + 1);
+            break;
+        }
+
+        case ISO15693_GET_SYSTEM_INFO_CMD:
+        {
+            /* Dont do anything */
+            break;
+        }
+
+        default:
+        {
+            result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                                NFCSTATUS_INVALID_DEVICE_REQUEST);
+            break;
+        }
+    }
+
+    psNdefSmtCrdFmt->SendLength = send_index;
+
+    if (!result)
+    {
+        result = phFriNfc_OvrHal_Transceive(psNdefSmtCrdFmt->LowerDevice,
+                                            &psNdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+                                            psNdefSmtCrdFmt->psRemoteDevInfo,
+                                            psNdefSmtCrdFmt->Cmd,
+                                            &psNdefSmtCrdFmt->psDepAdditionalInfo,
+                                            psNdefSmtCrdFmt->SendRecvBuf,
+                                            psNdefSmtCrdFmt->SendLength,
+                                            psNdefSmtCrdFmt->SendRecvBuf,
+                                            psNdefSmtCrdFmt->SendRecvLength);
+    }
+
+    return result;
+}
+
+static 
+NFCSTATUS 
+phFriNfc_ISO15693_H_GetMaxDataSize (
+    phFriNfc_sNdefSmtCrdFmt_t   *psNdefSmtCrdFmt, 
+    uint8_t                     *p_recv_buf, 
+    uint8_t                     recv_length)
+{
+    NFCSTATUS                       result = NFCSTATUS_SUCCESS;
+    phFriNfc_ISO15693_AddInfo_t     *ps_iso15693_info = 
+                                    &(psNdefSmtCrdFmt->AddInfo.s_iso15693_info);
+    phHal_sIso15693Info_t           *ps_rem_iso_15693_info = 
+                        &(psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
+    uint8_t                         recv_index = 0;
+
+    if ((ISO15693_GET_SYS_INFO_RESP_LEN == recv_length)
+        && (ISO15693_MAX_SIZE_MASK == (*p_recv_buf & ISO15693_MAX_SIZE_MASK)))
+    {
+        uint8_t information_flag = *p_recv_buf;
+        /* MAX size is present in the system information and 
+        also response length is correct */
+        recv_index = (uint8_t)(recv_index + 1);
+
+        if (!phOsalNfc_MemCompare ((void *)ps_rem_iso_15693_info->Uid, 
+                                (void *)(p_recv_buf + recv_index), 
+                                ps_rem_iso_15693_info->UidLength))
+        {
+            /* UID comaparision successful */
+            uint8_t                 no_of_blocks = 0;
+            uint8_t                 blk_size_in_bytes = 0;
+            uint8_t                 ic_reference = 0;
+
+            /* So skip the UID size compared in the received buffer */
+            recv_index = (uint8_t)(recv_index + 
+                                    ps_rem_iso_15693_info->UidLength);
+
+            if (information_flag & ISO15693_DSFID_MASK) {
+                /* Skip DFSID  */
+                recv_index = (uint8_t)(recv_index + ISO15693_SKIP_DFSID);
+            }
+            if (information_flag & ISO15693_AFI_MASK) {
+                /* Skip AFI  */
+                recv_index = (uint8_t)(recv_index + ISO15693_SKIP_AFI);
+            }
+
+            /* To get the number of blocks in the card */
+            no_of_blocks = (uint8_t)(*(p_recv_buf + recv_index) + 1);
+            recv_index = (uint8_t)(recv_index + 1);
+
+            /* To get the each block size in bytes */
+            blk_size_in_bytes = (uint8_t)((*(p_recv_buf + recv_index) 
+                                & ISO15693_BLOCK_SIZE_IN_BYTES_MASK) + 1);
+            recv_index = (uint8_t)(recv_index + 1);
+
+            if (information_flag & ISO15693_ICREF_MASK) {
+                /* Get the IC reference */
+                ic_reference = (uint8_t)(*(p_recv_buf + recv_index));
+                if (ic_reference == 0x03) {
+                    no_of_blocks = 8;
+                }
+            }
+
+            /* calculate maximum data size in the card */
+            ps_iso15693_info->max_data_size = (uint16_t)
+                                        (no_of_blocks * blk_size_in_bytes);
+
+        }
+        else
+        {
+            result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                                NFCSTATUS_INVALID_DEVICE_REQUEST);
+        }                     
+    }
+    else
+    {
+        result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                            NFCSTATUS_INVALID_DEVICE_REQUEST);
+    }
+
+
+    return result;
+}
+
+static 
+NFCSTATUS 
+phFriNfc_ISO15693_H_ProFormat (
+    phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt)
+{
+    NFCSTATUS                       result = NFCSTATUS_SUCCESS;
+    phFriNfc_ISO15693_AddInfo_t     *ps_iso15693_info = 
+                                    &(psNdefSmtCrdFmt->AddInfo.s_iso15693_info);
+    phFriNfc_ISO15693_FormatSeq_t   e_format_seq = 
+                                    (phFriNfc_ISO15693_FormatSeq_t)
+                                    ps_iso15693_info->format_seq;
+    uint8_t                         command_type = 0;
+    uint8_t                         a_send_byte[ISO15693_BYTES_PER_BLOCK] = {0};
+    uint8_t                         send_length = 0;
+    uint8_t                         send_index = 0;
+    uint8_t                         format_complete = FALSE;
+    
+    switch (e_format_seq)
+    {
+        case ISO15693_GET_SYS_INFO:
+        {
+            /* RESPONSE received for GET SYSTEM INFO  */
+
+            if (!phFriNfc_ISO15693_H_GetMaxDataSize (psNdefSmtCrdFmt, 
+                (psNdefSmtCrdFmt->SendRecvBuf + ISO15693_EXTRA_RESPONSE_FLAG), 
+                (uint8_t)(*psNdefSmtCrdFmt->SendRecvLength - 
+                ISO15693_EXTRA_RESPONSE_FLAG)))
+            {
+                /* Send the READ MULTIPLE BLOCKS COMMAND */
+                command_type = ISO15693_RD_MULTIPLE_BLKS_CMD;
+                e_format_seq = ISO15693_RD_MULTIPLE_BLKS_CHECK;
+
+                /* Prepare data for the command, 
+                First add the current block */
+                *a_send_byte = (uint8_t)ps_iso15693_info->current_block;
+                send_index = (uint8_t)(send_index + 1);
+
+                /* Second, add number of blocks to read, here 2 blocks means 
+                8 bytes. 1 is decremented because to read multiple block.
+                the first block is read by default, apart from the first block,  
+                next block shall be read, that means remaining block to read is 1
+                So, if for eg: 2 blocks needs to be read from block number 0, then 1 
+                is number of blocks to read. This will read both block 0 and 1
+                */
+                *(a_send_byte + send_index) = (uint8_t)
+                                    (ISO15693_RD_2_BLOCKS - 1);
+                send_index = (uint8_t)(send_index + 1);
+
+                send_length = send_index;
+            }
+            else
+            {
+                result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                                    NFCSTATUS_INVALID_RECEIVE_LENGTH);
+            }
+            break;
+        }
+
+        case ISO15693_RD_MULTIPLE_BLKS_CHECK:
+        {
+            /* RESPONSE received for READ MULTIPLE BLOCKS 
+            received, prepare data for writing CC bytes */            
+            
+            command_type = ISO15693_WR_SINGLE_BLK_CMD;
+            e_format_seq = ISO15693_WRITE_CC_FMT;
+
+            /* CC magic number */
+            *a_send_byte = (uint8_t)ISO15693_CC_MAGIC_NUM;
+            send_index = (uint8_t)(send_index + 1);
+
+            /* CC Version and read/write access */
+            *(a_send_byte + send_index) = (uint8_t)
+                            ISO15693_CC_VER_RW;
+            send_index = (uint8_t)(send_index + 1);
+
+            /* CC MAX data size, calculated during GET system information */
+            *(a_send_byte + send_index) = (uint8_t)
+                            (ps_iso15693_info->max_data_size / 
+                            ISO15693_CC_MULTIPLE_FACTOR);
+            send_index = (uint8_t)(send_index + 1);
+
+            switch (ps_iso15693_info->max_data_size)
+            {
+                case ISO15693_SLI_X_MAX_SIZE:
+                {
+                    /* For SLI tags : Inventory Page read not supported */
+                    *(a_send_byte + send_index) = (uint8_t)
+                                        ISO15693_RDMULBLKS_CMD_MASK;
+                    break;
+                }
+
+                case ISO15693_SLI_X_S_MAX_SIZE:
+                {
+                    /* For SLI - S tags : Read multiple blocks not supported */
+                    *(a_send_byte + send_index) = (uint8_t)
+                                        ISO15693_INVENTORY_CMD_MASK;
+                    break;
+                }
+
+                case ISO15693_SLI_X_L_MAX_SIZE:
+                {
+                    /* For SLI - L tags : Read multiple blocks not supported */
+                    *(a_send_byte + send_index) = (uint8_t)
+                                        ISO15693_INVENTORY_CMD_MASK;
+                    break;
+                }
+
+                default:
+                {
+                    result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                                        NFCSTATUS_INVALID_DEVICE_REQUEST);
+                    break;
+                }
+            }
+            
+            send_index = (uint8_t)(send_index + 1);
+
+            send_length = sizeof (a_send_byte);
+            
+            break;
+        }
+
+        case ISO15693_WRITE_CC_FMT:
+        {
+            /* CC byte write succcessful. 
+            Prepare data for NDEF TLV writing */
+            command_type = ISO15693_WR_SINGLE_BLK_CMD;
+            e_format_seq = ISO15693_WRITE_NDEF_TLV;
+
+            ps_iso15693_info->current_block = (uint16_t)
+                        (ps_iso15693_info->current_block + 1);
+            
+            /* NDEF TLV - Type byte updated to 0x03 */
+            *a_send_byte = (uint8_t)ISO15693_NDEF_TLV_TYPE_ID;
+            send_index = (uint8_t)(send_index + 1);
+
+            /* NDEF TLV - Length byte updated to 0 */
+            *(a_send_byte + send_index) = 0;
+            send_index = (uint8_t)(send_index + 1);
+
+            /* Terminator TLV - value updated to 0xFEU */
+            *(a_send_byte + send_index) = (uint8_t)
+                            ISO15693_TERMINATOR_TLV_ID;
+            send_index = (uint8_t)(send_index + 1);
+
+            send_length = sizeof (a_send_byte);
+            break;
+        }
+
+        case ISO15693_WRITE_NDEF_TLV:
+        {
+            /* SUCCESSFUL formatting complete */
+            format_complete = TRUE;
+            break;
+        }
+
+        default:
+        {
+            result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                                NFCSTATUS_INVALID_DEVICE_REQUEST);
+            break;
+        }
+    }
+
+    if ((!format_complete) && (!result))
+    {
+        result = phFriNfc_ISO15693_H_FmtReadWrite (psNdefSmtCrdFmt, 
+                            command_type, a_send_byte, send_length);
+    }
+
+    ps_iso15693_info->format_seq = (uint8_t)e_format_seq; 
+    return result;
+}
+
+/*********************** Static function definitions end ***********************/
+
+/*********************** External function definitions start ***********************/
+void 
+phFriNfc_ISO15693_FmtReset (
+    phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt)
+{
+    /* reset to ISO15693 data structure */
+    (void)memset((void *)&(psNdefSmtCrdFmt->AddInfo.s_iso15693_info), 
+                0x00, sizeof (phFriNfc_ISO15693_AddInfo_t));
+    psNdefSmtCrdFmt->FmtProcStatus = 0;
+}
+
+NFCSTATUS 
+phFriNfc_ISO15693_Format (
+    phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt)
+{
+    NFCSTATUS                       result = NFCSTATUS_SUCCESS;
+    phHal_sIso15693Info_t           *ps_rem_iso_15693_info = 
+                        &(psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
+    
+    
+    if ((ISO15693_7TH_BYTE_UID_VALUE == 
+        ps_rem_iso_15693_info->Uid[ISO15693_BYTE_7_INDEX]) 
+        && (ISO15693_6TH_BYTE_UID_VALUE == 
+        ps_rem_iso_15693_info->Uid[ISO15693_BYTE_6_INDEX]))
+    {
+        /* Check if the card is manufactured by NXP (6th byte 
+        index of UID value = 0x04 and the 
+        last byte of UID is 0xE0, only then the card detected 
+        is NDEF compliant */
+        psNdefSmtCrdFmt->State = ISO15693_FORMAT;
+
+        /* GET system information command to get the card size */
+        result = phFriNfc_ISO15693_H_FmtReadWrite (psNdefSmtCrdFmt, 
+                            ISO15693_GET_SYSTEM_INFO_CMD, NULL, 0);
+    }
+    else
+    {
+        result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                            NFCSTATUS_INVALID_DEVICE_REQUEST);
+    }
+
+    return result;
+}
+
+void 
+phFriNfc_ISO15693_FmtProcess (
+    void        *pContext,
+    NFCSTATUS   Status)
+{
+    phFriNfc_sNdefSmtCrdFmt_t      *psNdefSmtCrdFmt = 
+                                    (phFriNfc_sNdefSmtCrdFmt_t *)pContext;
+    phFriNfc_ISO15693_AddInfo_t     *ps_iso15693_info = 
+                                    &(psNdefSmtCrdFmt->AddInfo.s_iso15693_info);
+
+    if((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
+    {
+        if (ISO15693_FORMAT == psNdefSmtCrdFmt->State)
+        {
+            /* Check for further formatting */
+            Status = phFriNfc_ISO15693_H_ProFormat (psNdefSmtCrdFmt);
+        }
+        else
+        {
+            Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, 
+                                NFCSTATUS_INVALID_DEVICE_REQUEST);
+        }
+    }
+    else
+    {   
+        if (ISO15693_RD_MULTIPLE_BLKS_CHECK == 
+            (phFriNfc_ISO15693_FormatSeq_t)ps_iso15693_info->format_seq)
+        {
+            /* If READ MULTIPLE BLOCKS is not working then 
+                do further formatting, disable the READ MULTIPLE BLOCK 
+                flag in the CC 4th byte, this says that COMMAND is not 
+                supported and dont use this command
+                */
+            Status = phFriNfc_ISO15693_H_ProFormat (psNdefSmtCrdFmt);            
+        }
+    }
+
+    /* Handle the all the error cases */
+    if ((NFCSTATUS_PENDING & PHNFCSTBLOWER) != (Status & PHNFCSTBLOWER))
+    {
+        /* call respective CR */
+        phFriNfc_SmtCrdFmt_HCrHandler (psNdefSmtCrdFmt, Status);
+    }
+}
+/*********************** External function definitions end ***********************/
+
+
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
+
diff --git a/src/phFriNfc_ISO15693Format.h b/src/phFriNfc_ISO15693Format.h
new file mode 100644
index 0000000..9dab3c1
--- /dev/null
+++ b/src/phFriNfc_ISO15693Format.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*!
+* \file  phFriNfc_ISO15693Format.h
+* \brief ISO-15693 Smart card formatting.
+*
+* Project: NFC-FRI
+*
+* $Date:  $
+* $Author: ing02260 $
+* $Revision: 1.0 $
+* $Aliases:  $
+*
+*/
+
+#ifndef PHFRINFC_ISO15693FORMAT_H
+#define PHFRINFC_ISO15693FORMAT_H
+
+/****************************** Macro definitions start ********************************/
+
+/****************************** Macro definitions end ********************************/
+
+/****************************** Data structures start ********************************/
+
+/****************************** Data structures end ********************************/
+
+/*********************** External function declarations start ***********************/
+/*!
+* \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_ISO15693_FmtReset (
+    phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt);
+
+/*!
+* \ingroup grp_fri_smart_card_formatting
+*
+* \brief Initiates the card formatting procedure for Remote Smart Card Type.
+*
+* \copydoc page_ovr The function initiates and formats the ISO-15693 Card.After this 
+*                   operation,remote card would be properly initialized and 
+*                   Ndef Compliant.Depending upon the different card type, this 
+*                   function handles formatting procedure.This function also handles
+*                   the different recovery procedures for different types of the cards. 
+*                   For both Format and Recovery Management same API is used.
+* 
+* \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_ISO15693_Format (
+    phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt);
+
+/**
+*\ingroup grp_fri_smart_card_formatting
+*
+* \brief Smart card Formatting \b Completion \b Routine or \b Process function
+*
+* \copydoc page_ovr Completion Routine: This function is called by the lower layer (OVR HAL)
+*                  when an I/O operation has finished. The internal state machine decides
+*                  whether to call into the lower device again or to complete the process
+*                  by calling into the upper layer's completion routine, stored within this
+*                  component's context (\ref phFriNfc_sNdefSmtCrdFmt_t).
+*
+* The function call scheme is according to \ref grp_interact. No State reset is performed during
+* operation.
+*
+* \param[in] Context The context of the current (not the lower/upper) instance, as set by the lower,
+*            calling layer, upon its completion.
+* \param[in] Status  The completion status of the lower layer (to be handled by the implementation of
+*                    the state machine of this function like a regular return value of an internally
+*                    called function).
+*
+* \note For general information about the completion routine interface please see \ref pphFriNfc_Cr_t . 
+* The Different Status Values are as follows
+*
+*/
+void 
+phFriNfc_ISO15693_FmtProcess (
+    void        *pContext,
+    NFCSTATUS   Status);
+
+/*********************** External function declarations end ***********************/
+
+#endif /* #define PHFRINFC_ISO15693FORMAT_H */
+
+
+
diff --git a/src/phFriNfc_ISO15693Map.c b/src/phFriNfc_ISO15693Map.c
index 8b6d1f1..f07b1bf 100644
--- a/src/phFriNfc_ISO15693Map.c
+++ b/src/phFriNfc_ISO15693Map.c
@@ -84,6 +84,14 @@
 /* UID bytes to differentiate ICODE cards */
 #define ISO15693_UID_BYTE_4                 0x04U
 #define ISO15693_UID_BYTE_5                 0x05U
+#define ISO15693_UID_BYTE_6                 0x06U
+#define ISO15693_UID_BYTE_7                 0x07U
+
+/* UID 7th byte value shall be 0xE0 */
+#define ISO15693_UIDBYTE_7_VALUE            0xE0U
+/* UID 6th byte value shall be 0x04 - NXP manufacturer */
+#define ISO15693_UIDBYTE_6_VALUE            0x04U
+
 
 /* UID value for 
     SL2 ICS20 
@@ -159,8 +167,6 @@
 #define ISO15693_MULT_FACTOR                0x08U
 /* NIBBLE mask for READ WRITE access */
 #define ISO15693_LSB_NIBBLE_MASK            0x0FU
-#define ISO15693_MSB_NIBBLE_MASK            0xF0U
-
 #define ISO15693_RD_WR_PERMISSION           0x00U
 #define ISO15693_RD_ONLY_PERMISSION         0x03U
 
@@ -205,7 +211,7 @@
     (max_data_size - ((blk * ISO15693_BYTES_PER_BLOCK) + index))
 
 #define ISO15693_GET_LEN_FIELD_BLOCK_NO(blk, byte_addr, ndef_size) \
-    (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) >= \
+    (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) > \
     (ISO15693_BYTES_PER_BLOCK - 1)) ? (blk + 1) : blk)
 
 #define ISO15693_GET_LEN_FIELD_BYTE_NO(blk, byte_addr, ndef_size) \
@@ -281,15 +287,17 @@
     {
         case ISO15693_RD_BEFORE_WR_NDEF_L_0:
         {
-            p_recv_buf = (psNdefMap->SendRecvBuf + 
-                        ISO15693_EXTRA_RESP_BYTE);
+            /* L byte is read  */
+            p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
             recv_length = (uint8_t)
                         (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
 
             if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
             {
+                /* Response length is correct */
                 uint8_t     byte_index = 0;
 
+                /* Copy the recevied buffer */
                 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf, 
                                 recv_length);
 
@@ -298,12 +306,14 @@
                         ps_iso_15693_con->ndef_tlv_type_byte, 
                         psNdefMap->ApduBufferSize);
 
-                /* Writing length field to 0 */
+                /* Writing length field to 0, Update length field to 0 */
                 *(a_write_buf + byte_index) = 0x00;
                 
                 if ((ISO15693_BYTES_PER_BLOCK - 1) != byte_index)
                 {
+                    /* User data is updated in the buffer */
                     byte_index = (uint8_t)(byte_index + 1);
+                    /* Block number shall be udate */
                     remaining_size = (ISO15693_BYTES_PER_BLOCK - byte_index);
 
                     if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex) 
@@ -314,15 +324,17 @@
                     }
 
                     /* Go to next byte to fill the write buffer */
-                    
                     (void)memcpy ((void *)(a_write_buf + byte_index), 
                                 (void *)(psNdefMap->ApduBuffer + 
                                 psNdefMap->ApduBuffIndex), remaining_size);
 
+                    /* Write index updated */
                     psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex + 
                                                 remaining_size);                    
                 }
                 
+                /* After this write, user data can be written. 
+                Update the sequence accordingly */
                 e_wr_ndef_seq = ISO15693_WRITE_DATA;
                 write_flag = TRUE;
             } /* if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) */
@@ -415,7 +427,9 @@
         }
     } /* switch (e_wr_ndef_seq) */
 
-    if (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex)
+    if (((0 == psNdefMap->ApduBuffIndex) 
+        || (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex))
+        && (!result))
     {
         if (FALSE == write_flag)
         {
@@ -621,7 +635,7 @@
     }
     if (ps_iso_15693_con->store_length)
     {
-        /* Continue read option selected 
+        /* Continue Offset option selected 
             So stored data already existing, 
             copy the information to the user buffer 
         */
@@ -632,7 +646,7 @@
                 to the user expected size */
             (void)memcpy ((void *)(psNdefMap->ApduBuffer + 
                         psNdefMap->ApduBuffIndex), 
-                        (void *)p_recv_buf, 
+                            (void *)ps_iso_15693_con->store_read_data, 
                         ps_iso_15693_con->store_length);
 
             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + 
@@ -653,6 +667,8 @@
                         (void *)ps_iso_15693_con->store_read_data, 
                         remaining_data_size);
 
+                /* As stored data is more than the user expected data. So store 
+                    the remaining bytes again into the data structure */
             (void)memcpy ((void *)ps_iso_15693_con->store_read_data, 
                         (void *)(ps_iso_15693_con->store_read_data + 
                         remaining_data_size), 
@@ -660,13 +676,19 @@
 
             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + 
                                         remaining_data_size);
+
+                ps_iso_15693_con->store_length = (uint8_t)
+                            (ps_iso_15693_con->store_length - remaining_data_size);
         }
     } /* if (ps_iso_15693_con->store_length) */
     else
     {
+            /* Data is read from the card. */
         uint8_t                 byte_index = 0;
 
         remaining_data_size = ps_iso_15693_con->remaining_size_to_read;
+
+            /* Check if the block number is to read the first VALUE field */
         if (ISO15693_GET_VALUE_FIELD_BLOCK_NO(ps_iso_15693_con->ndef_tlv_type_blk, 
                                     ps_iso_15693_con->ndef_tlv_type_byte, 
                                     ps_iso_15693_con->actual_ndef_size) 
@@ -683,44 +705,53 @@
         if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)  
             < remaining_data_size)
         {
+                remaining_data_size = (uint8_t)
+                                    (recv_length - byte_index);
+                /* user input is less than the remaining card size */
             if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex) 
-                < (uint16_t)(recv_length - byte_index))
+                    < (uint16_t)remaining_data_size)
             {
+                    /* user data required is less than the data read */
                 remaining_data_size = (uint8_t)(psNdefMap->ApduBufferSize - 
                                                 psNdefMap->ApduBuffIndex);
+
+                    if (0 != (recv_length - (byte_index + 
+                                    remaining_data_size)))
+                    {
                 /* Store the data for the continue read option */
                 (void)memcpy ((void *)ps_iso_15693_con->store_read_data, 
-                        (void *)(p_recv_buf + byte_index + 
-                                remaining_data_size), 
-                                ((recv_length - byte_index) - 
-                                remaining_data_size));
+                                (void *)(p_recv_buf + (byte_index + 
+                                        remaining_data_size)), 
+                                        (recv_length - (byte_index + 
+                                        remaining_data_size)));
 
                 ps_iso_15693_con->store_length = (uint8_t)
-                            ((recv_length - byte_index) - remaining_data_size);
+                                    (recv_length - (byte_index + 
+                                        remaining_data_size));
             }
-            else
-            {
-                remaining_data_size = (uint8_t)
-                                (recv_length - byte_index);
             }
         }
         else
         {
+                /* user data required is equal or greater than the data read */
             if (remaining_data_size > (recv_length - byte_index))                
             {
                 remaining_data_size = (uint8_t)
                                 (recv_length - byte_index);
             }
         }
+
+            /* Copy data in the user buffer */
         (void)memcpy ((void *)(psNdefMap->ApduBuffer + 
                         psNdefMap->ApduBuffIndex), 
                         (void *)(p_recv_buf + byte_index), 
                         remaining_data_size);
 
+            /* Update the read index */
         psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + 
                                     remaining_data_size);            
 
-    } /* if (ps_iso_15693_con->store_length) */
+        } /* else part of if (ps_iso_15693_con->store_length) */
 
     /* Remaining size is decremented */
     ps_iso_15693_con->remaining_size_to_read = (uint8_t)
@@ -744,7 +775,9 @@
     }
     else
     {
-        /* Read completed */
+            /* Read completed, EITHER index has reached to the user size 
+            OR end of the card is reached
+            update the user data structure with read data size */
         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
     }
     if (reformatted_buf != NULL) {
@@ -764,22 +797,27 @@
     uint8_t                 recv_index = 0;
     uint8_t                 *p_recv_buf = (psNdefMap->SendRecvBuf + 1);
 
+    /* expected CC byte : E1 40 "MAX SIZE depends on tag" */
     if (ISO15693_CC_MAGIC_BYTE == *p_recv_buf)
     {
+        /*  0xE1 magic byte found*/
         recv_index = (uint8_t)(recv_index + 1);
         uint8_t tag_major_version = (*(p_recv_buf + recv_index) & ISO15693_MAJOR_VERSION_MASK) >> 6;
         if (ISO15693_MAPPING_VERSION >= tag_major_version)
         {
+            /* Correct mapping version found */
             switch (*(p_recv_buf + recv_index) & ISO15693_LSB_NIBBLE_MASK)
             {
                 case ISO15693_RD_WR_PERMISSION:
                 {
+                    /* READ/WRITE possible */
                     psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
                     break;
                 }
 
                 case ISO15693_RD_ONLY_PERMISSION:
                 {
+                    /* ONLY READ possible, WRITE NOT possible */
                     psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
                     break;
                 }
@@ -795,6 +833,7 @@
             
             if (!result)
             {
+                /* Update MAX SIZE */
                 ps_iso_15693_con->max_data_size = (uint16_t)
                     (*(p_recv_buf + recv_index) *
                     ISO15693_MULT_FACTOR);
@@ -856,7 +895,8 @@
     else
     {
         /* Propreitary TLVs VALUE can end in between a block, 
-            so when that block is read, dont read the proprietary data  */
+            so when that block is read, update the parse_index 
+            with byte address value */
         if (ISO15693_PROP_TLV_V == e_chk_ndef_seq)
         {
             parse_index = ps_iso_15693_con->ndef_tlv_type_byte;
@@ -868,20 +908,28 @@
             && (NFCSTATUS_SUCCESS == result) 
             && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq))
     {
+        /* Parse 
+            1. till the received length of the block 
+            2. till there is no error during parse 
+            3. till LENGTH field of NDEF TLV is found  
+        */
         switch (e_chk_ndef_seq)
         {
             case ISO15693_NDEF_TLV_T:
             {
+                /* Expected value is 0x03 TYPE identifier 
+                    of the NDEF TLV */
                 prop_ndef_index = 0;
                 switch (*(p_recv_buf + parse_index))
                 {
                     case ISO15693_NDEF_TLV_TYPE_ID:
                     {
+                        /* Update the data structure with the byte address and 
+                        the block number */
                         ps_iso_15693_con->ndef_tlv_type_byte = parse_index;
                         ps_iso_15693_con->ndef_tlv_type_blk = 
                                             ps_iso_15693_con->current_block;
                         e_chk_ndef_seq = ISO15693_NDEF_TLV_L;
-                        /* Update the block number */
 
                         break;
                     }
@@ -912,27 +960,36 @@
 
             case ISO15693_PROP_TLV_L:
             {
+                /* Length field of the proprietary TLV */
                 switch (prop_ndef_index)
                 {
+                    /* Length field can have 1 or 3 bytes depending 
+                        on the data size, so check for each index byte */
                     case 0:
                     {
+                        /* 1st index of the length field of the TLV */
                         if (0 == *(p_recv_buf + parse_index))
                         {
+                            /* LENGTH is 0, not possible, so error */
                             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                                                 NFCSTATUS_NO_NDEF_SUPPORT);
                             e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
                         }
                         else 
                         {
-                            prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
-
                             if (ISO15693_THREE_BYTE_LENGTH_ID == 
                                 *(p_recv_buf + parse_index))
                             {
+                                /* 3 byte LENGTH field identified, so increment the 
+                                index, so next time 2nd byte is parsed */
                                 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
                             }
                             else
                             {
+                                /* 1 byte LENGTH field identified, so "static" 
+                                index is set to 0 and actual ndef size is 
+                                copied to the data structure
+                                */
                                 ps_iso_15693_con->actual_ndef_size = 
                                                     *(p_recv_buf + parse_index);
                                 e_chk_ndef_seq = ISO15693_PROP_TLV_V;
@@ -944,6 +1001,8 @@
 
                     case 1:
                     {
+                        /* 2nd index of the LENGTH field that is MSB of the length, 
+                        so the length is left shifted by 8 */
                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
                                         (*(p_recv_buf + parse_index) << 
                                         ISO15693_BTYE_SHIFT);
@@ -953,6 +1012,8 @@
 
                     case 2:
                     {
+                        /* 3rd index of the LENGTH field that is LSB of the length, 
+                        so the length ORed with the previously stored size */
                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
                                         (ps_iso_15693_con->actual_ndef_size | 
                                         *(p_recv_buf + parse_index));
@@ -984,6 +1045,7 @@
                 else
                 {
                     uint16_t            prop_byte_addr = 0;
+
                     /* skip the proprietary TLVs value field */
                     prop_byte_addr = (uint16_t)
                         ((ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK) + 
@@ -1039,12 +1101,17 @@
 
             case ISO15693_NDEF_TLV_L:
             {
+                /* Length field of the NDEF TLV */
                 switch (prop_ndef_index)
                 {
+                    /* Length field can have 1 or 3 bytes depending 
+                        on the data size, so check for each index byte */
                     case 0:
                     {
+                        /* 1st index of the length field of the TLV */
                         if (0 == *(p_recv_buf + parse_index))
                         {
+                            /* LENGTH is 0, card is in INITILIASED STATE */
                             e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
                             ps_iso_15693_con->actual_ndef_size = 0;
                         }
@@ -1055,6 +1122,8 @@
                             if (ISO15693_THREE_BYTE_LENGTH_ID == 
                                 *(p_recv_buf + parse_index))
                             {
+                                /* At present no CARD supports more than 255 bytes, 
+                                so error is returned */
                                 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
                                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                                                     NFCSTATUS_NO_NDEF_SUPPORT);
@@ -1062,8 +1131,13 @@
                             }
                             else
                             {
+                                /* 1 byte LENGTH field identified, so "static" 
+                                index is set to 0 and actual ndef size is 
+                                copied to the data structure
+                                */
                                 ps_iso_15693_con->actual_ndef_size = 
                                                     *(p_recv_buf + parse_index);
+                                /* next values are the DATA field of the NDEF TLV */
                                 e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
                                 prop_ndef_index = 0;
                             }
@@ -1073,6 +1147,8 @@
 
                     case 1:
                     {
+                        /* 2nd index of the LENGTH field that is MSB of the length, 
+                        so the length is left shifted by 8 */
                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
                             (*(p_recv_buf + parse_index) << 
                             ISO15693_BTYE_SHIFT);
@@ -1082,6 +1158,8 @@
 
                     case 2:
                     {
+                        /* 3rd index of the LENGTH field that is LSB of the length, 
+                        so the length ORed with the previously stored size */
                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
                             (ps_iso_15693_con->actual_ndef_size | 
                             *(p_recv_buf + parse_index));
@@ -1102,7 +1180,7 @@
                 if ((ISO15693_NDEF_TLV_V == e_chk_ndef_seq)
                     && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size, 
                         /* parse_index + 1 is done because the data starts from the next index. 
-                        MOD operation is used to know that parse_index > 
+                        "MOD" operation is used to know that parse_index > 
                         ISO15693_BYTES_PER_BLOCK, then block shall be incremented 
                         */
                         (((parse_index + 1) % ISO15693_BYTES_PER_BLOCK) ?  
@@ -1162,6 +1240,7 @@
         }
         else
         {
+            /* Proprietary TLV detected, so skip the proprietary blocks */
             ps_iso_15693_con->current_block = ps_iso_15693_con->ndef_tlv_type_blk;
         }
    
@@ -1179,6 +1258,7 @@
         }
         else
         {
+            /* End of card reached, error no NDEF information found */
             e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
             prop_ndef_index = 0;
             /* Error, no size to parse */
@@ -1241,25 +1321,37 @@
         {
             if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
             {
+                result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
+                /* Check CC bytes and also the card state for READ ONLY, 
+                if the card is already read only, then dont continue with 
+                next operation */
+                if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState) 
+                    && (!result))
+                {
+                    /* CC byte read successful */
                 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf, 
                                 sizeof (a_write_buf));
 
+                    /* Change the read write access to read only */
                 *(a_write_buf + ISO15693_RW_BTYE_INDEX) = (uint8_t)
                             (*(a_write_buf + ISO15693_RW_BTYE_INDEX) | 
                             ISO15693_CC_READ_ONLY_MASK);
 
                 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, 
-                                ISO15693_WRITE_DATA, a_write_buf, 
+                                    ISO15693_WRITE_COMMAND, a_write_buf, 
                                 sizeof (a_write_buf));
 
                 e_ro_ndef_seq = ISO15693_WRITE_CC;
             }
+            }
             break;
         }
 
         case ISO15693_WRITE_CC:
         {
+            /* Write to CC is successful. */
             e_ro_ndef_seq = ISO15693_LOCK_BLOCK;
+            /* Start the lock block command to lock the blocks */
             result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, 
                                 ISO15693_LOCK_BLOCK_CMD, NULL, 0);
             break;
@@ -1268,14 +1360,17 @@
         case ISO15693_LOCK_BLOCK:
         {
             if (ps_iso_15693_con->current_block == 
-                (ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK))
+                ((ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK) - 
+                1))
             {
-                /* READ ONLY successful */
+                /* End of card reached, READ ONLY successful */
             }
             else
             {
+                /* current block is incremented */
                 ps_iso_15693_con->current_block = (uint16_t)
                     (ps_iso_15693_con->current_block + 1);
+                /* Lock the current block */
                 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, 
                                 ISO15693_LOCK_BLOCK_CMD, NULL, 0);
             }
@@ -1323,10 +1418,22 @@
     psNdefMap->ISO15693Container.remaining_size_to_read = 0;
     psNdefMap->ISO15693Container.read_capabilities = 0;
 
+    if ((ISO15693_UIDBYTE_6_VALUE == 
+        ps_iso_15693_info->Uid[ISO15693_UID_BYTE_6]) 
+        && (ISO15693_UIDBYTE_7_VALUE == 
+        ps_iso_15693_info->Uid[ISO15693_UID_BYTE_7]))
+    {
+        /* Check if the card is manufactured by NXP (6th byte 
+            index of UID value = 0x04 and the 
+            last byte i.e., 7th byte of UID is 0xE0, only then the card detected 
+            is NDEF compliant */
     switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_5])
     {
+            /* Check for supported tags, by checking the 5th byte index of UID */
         case ISO15693_UIDBYTE_5_VALUE_SLI_X:
         {
+                /* ISO 15693 card type is ICODE SLI 
+                so maximum size is 112 */
             psNdefMap->ISO15693Container.max_data_size = 
                             ISO15693_SL2_S2002_ICS20;
             break;
@@ -1334,12 +1441,17 @@
 
         case ISO15693_UIDBYTE_5_VALUE_SLI_X_S:
         {
+                /* ISO 15693 card type is ICODE SLI/X S  
+                so maximum size depends on the 4th UID byte index */
             switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
             {
                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_S:
                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC:
                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_SY:
                 {
+                        /* Supported tags are with value (4th byte UID index)
+                        of 0x00, 0x80 and 0x40 
+                        For these cards max size is 160 bytes */
                     psNdefMap->ISO15693Container.max_data_size = 
                                     ISO15693_SL2_S5302_ICS53_ICS54;
                     break;
@@ -1347,6 +1459,7 @@
 
                 default:
                 {
+                        /* Tag not supported */
                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                                         NFCSTATUS_INVALID_DEVICE_REQUEST);
                     break;
@@ -1357,11 +1470,16 @@
 
         case ISO15693_UIDBYTE_5_VALUE_SLI_X_L:
         {
+                /* ISO 15693 card type is ICODE SLI/X L  
+                so maximum size depends on the 4th UID byte index */
             switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
             {
                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_L:
                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC:
                 {
+                        /* Supported tags are with value (4th byte UID index)
+                        of 0x00 and 0x80
+                        For these cards max size is 32 bytes */
                     psNdefMap->ISO15693Container.max_data_size = 
                                     ISO15693_SL2_S5002_ICS50_ICS51;
                     break;
@@ -1369,6 +1487,7 @@
 
                 default:
                 {
+                        /* Tag not supported */
                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                                         NFCSTATUS_INVALID_DEVICE_REQUEST);
                     break;
@@ -1379,14 +1498,23 @@
 
         default:
         {
+                /* Tag not supported */
             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
             break;
         }
     }
+    }
+    else
+    {
+        /* Tag not supported */
+        result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
+                            NFCSTATUS_INVALID_DEVICE_REQUEST);
+    }
 
     if (!result)
     {
+        /* Start reading the data */
         result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND, 
                                                 NULL, 0);
     }
@@ -1432,21 +1560,27 @@
     if ((!ps_iso_15693_con->remaining_size_to_read) 
         && (!psNdefMap->Offset))
     {
+        /* Entire data is already read from the card. 
+        There is no data to give */
         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 
     }
     else if (0 == ps_iso_15693_con->actual_ndef_size)
     {
+        /* Card is NDEF, but no data in the card. */
         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                             NFCSTATUS_READ_FAILED);
     }
     else if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
     {
+        /* Card is NDEF, but no data in the card. */
         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
                             NFCSTATUS_READ_FAILED);
     }
     else if (psNdefMap->Offset)
     {
+        /* BEGIN offset, so reset the remaining read size and 
+        also the curretn block */
         ps_iso_15693_con->remaining_size_to_read = 
                         ps_iso_15693_con->actual_ndef_size;
         ps_iso_15693_con->current_block = 
@@ -1466,16 +1600,19 @@
     }
     else
     {
+        /* CONTINUE offset */
         if (ps_iso_15693_con->store_length > 0)
         {
+            /* Previous read had extra bytes, so data is stored, so give that take 
+            that data from store. If more data is required, then read remaining bytes */
             result = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
         }
         else
         {
             ps_iso_15693_con->current_block = (uint16_t)
                                 (ps_iso_15693_con->current_block + 1);
-            result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND, 
-                                                        NULL, 0);
+            result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, 
+                                            ISO15693_READ_COMMAND, NULL, 0);
         }
     }
 
@@ -1550,6 +1687,7 @@
     /* Store the offset in the context */
     psNdefMap->Offset = Offset;
 
+    /* Set the current block correctly to write the length field to 0 */
     ps_iso_15693_con->current_block = 
                         ISO15693_GET_LEN_FIELD_BLOCK_NO(
                         ps_iso_15693_con->ndef_tlv_type_blk, 
@@ -1561,12 +1699,18 @@
                         ps_iso_15693_con->ndef_tlv_type_byte, 
                         *pPacketDataLength))
     {
+        /* Check the byte address to write. If length byte address is in between or 
+        is the last byte of the block, then READ before write 
+        reason, write should not corrupt other data 
+        */
         ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_NDEF_L_0;
         result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, 
                                 ISO15693_READ_COMMAND, NULL, 0);
     }
     else
     {
+        /* If length byte address is at the beginning of the block then WRITE 
+        length field to 0 and as also write user DATA */
         ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_WRITE_DATA;
 
         /* Length is made 0x00 */
@@ -1577,10 +1721,12 @@
                         (void *)psNdefMap->ApduBuffer, 
                         (ISO15693_BYTES_PER_BLOCK - 1));
 
+        /* Write data */
         result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, 
                                     ISO15693_WRITE_COMMAND, 
                                     a_write_buf, ISO15693_BYTES_PER_BLOCK);
 
+        /* Increment the index to keep track of bytes sent for write */
         psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex
                                         + (ISO15693_BYTES_PER_BLOCK - 1));
     }
@@ -1599,6 +1745,7 @@
                                 &(psNdefMap->ISO15693Container);
 
     psNdefMap->State = ISO15693_READ_ONLY_NDEF;
+    /* READ CC bytes */
     ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_CC;
     ps_iso_15693_con->current_block = 0;
 
@@ -1625,18 +1772,21 @@
         {
             case ISO15693_CHECK_NDEF:
             {
+                /* State = CHECK NDEF in progress */
                 Status = phFriNfc_ISO15693_H_ProcessCheckNdef (psNdefMap);
                 break;
             }
 
             case ISO15693_READ_NDEF:
             {
+                /* State = READ NDEF in progress */
                 Status = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
                 break;
             }
 
             case ISO15693_WRITE_NDEF:
             {
+                /* State = WRITE NDEF in progress */
                 Status = phFriNfc_ISO15693_H_ProcessWriteNdef (psNdefMap);
                 break;
             }
@@ -1644,6 +1794,7 @@
 #ifdef FRINFC_READONLY_NDEF
             case ISO15693_READ_ONLY_NDEF:
             {
+                /* State = RAD ONLY NDEF in progress */
                 Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap);
                 break;
             }
diff --git a/src/phFriNfc_ISO15693Map.h b/src/phFriNfc_ISO15693Map.h
index f696019..596534a 100644
--- a/src/phFriNfc_ISO15693Map.h
+++ b/src/phFriNfc_ISO15693Map.h
@@ -41,7 +41,7 @@
 
 /* Get the NDEF TLV VALUE field block and byte address */
 #define ISO15693_GET_VALUE_FIELD_BLOCK_NO(blk, byte_addr, ndef_size) \
-    (((byte_addr + 1 + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) >= \
+    (((byte_addr + 1 + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) > \
     (ISO15693_BYTES_PER_BLOCK - 1)) ? (blk + 1) : blk)
 
 #define ISO15693_GET_VALUE_FIELD_BYTE_NO(blk, byte_addr, ndef_size) \
diff --git a/src/phFriNfc_NdefMap.c b/src/phFriNfc_NdefMap.c
index 28f39f7..b25e9ec 100644
--- a/src/phFriNfc_NdefMap.c
+++ b/src/phFriNfc_NdefMap.c
@@ -674,18 +674,18 @@
                 break;
             }
 
+            case PH_FRINFC_NDEFMAP_ISO15693_CARD:
+            {
+                result = phFriNfc_ISO15693_ConvertToReadOnly (NdefMap);
+                break;
+            }
+
             default:
             {
                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
                                     NFCSTATUS_INVALID_REMOTE_DEVICE);
                 break;
             }
-
-            case PH_FRINFC_NDEFMAP_ISO15693_CARD:
-            {
-                result = phFriNfc_ISO15693_ConvertToReadOnly (NdefMap);
-                break;
-            }
         }
     }
     return result;
@@ -1407,7 +1407,7 @@
 #ifndef PH_FRINFC_MAP_ISO15693_DISABLED
             case PH_FRINFC_NDEFMAP_ISO15693_CARD:
             {
-#if 0
+#if 1
                 uint16_t                    block_no = 0;
                 uint8_t                     byte_no = 0;
 
@@ -1423,14 +1423,12 @@
                         NdefMap->ISO15693Container.actual_ndef_size);
 
                 *maxSize = (NdefMap->ISO15693Container.max_data_size - 
-                            ((NdefMap->ISO15693Container.actual_ndef_size > 0) ? 
-                            ((block_no * ISO15693_BYTES_PER_BLOCK) + byte_no) : 
-                            ISO15693_BYTES_PER_BLOCK));
-#else /* #if 0 */
+                            ((block_no * ISO15693_BYTES_PER_BLOCK) + byte_no));
+#else /* #if 1 */
                 /* 2 is used to exclude the T and L part of the TLV */
                 *maxSize = (NdefMap->ISO15693Container.max_data_size
                             - ISO15693_BYTES_PER_BLOCK - 2);
-#endif /* #if 0 */
+#endif /* #if 1 */
                 *actualSize = NdefMap->ISO15693Container.actual_ndef_size;
                 break;
             }
diff --git a/src/phFriNfc_SmtCrdFmt.c b/src/phFriNfc_SmtCrdFmt.c
index 0174c2d..0e250b9 100644
--- a/src/phFriNfc_SmtCrdFmt.c
+++ b/src/phFriNfc_SmtCrdFmt.c
@@ -21,10 +21,10 @@
  *
  * Project: NFC-FRI
  *
- * $Date: Wed Sep 23 14:41:56 2009 $
- * $Author: ing07336 $
- * $Revision: 1.8 $
- * $Aliases: NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,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 $
+ * $Date: Mon Dec 13 14:14:13 2010 $
+ * $Author: ing02260 $
+ * $Revision: 1.9 $
+ * $Aliases:  $
  *
  */
 
@@ -39,6 +39,9 @@
 #include <phFriNfc_MifULFormat.h>
 #include <phFriNfc_DesfireFormat.h>
 #include <phFriNfc_MifStdFormat.h>
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+    #include <phFriNfc_ISO15693Format.h>
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
 
 
 /*! \ingroup grp_file_attributes
@@ -146,6 +149,10 @@
         phFriNfc_MfUL_Reset(NdefSmtCrdFmt);
 #endif /* #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED */
 
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+        phFriNfc_ISO15693_FmtReset (NdefSmtCrdFmt);
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
+
 #ifdef PHFRINFC_OVRHAL_MOCKUP
         /*Reset Desfire Cap Container elements*/
   //      phFriNfc_Mockup_H_Reset(NdefSmtCrdFmt);
@@ -392,6 +399,13 @@
             break;
 #endif  /* PHFRINFC_OVRHAL_MOCKUP */
 
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+            case phHal_eISO15693_PICC:
+            {
+                Result = phFriNfc_ISO15693_Format (NdefSmtCrdFmt);
+                break;
+            }
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
             default :
                 /*  Remote device is not recognised.
                 Probably not NDEF compliant */
@@ -474,6 +488,14 @@
 #endif  /* PH_FRINFC_FMT_TOPAZ_DISABLED*/
             break;
 
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+            case phHal_eISO15693_PICC :
+            {
+                phFriNfc_ISO15693_FmtProcess (NdefSmtCrdFmt, Status);
+                break;
+            }
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
+
 #ifdef PHFRINFC_OVRHAL_MOCKUP
             case phHal_eOpModesMockup:
                 /*  Remote device is Desfire card */
diff --git a/src/phFriNfc_SmtCrdFmt.h b/src/phFriNfc_SmtCrdFmt.h
index 46b0d0d..4800c41 100644
--- a/src/phFriNfc_SmtCrdFmt.h
+++ b/src/phFriNfc_SmtCrdFmt.h
@@ -246,6 +246,27 @@
     uint8_t     UpdMADBlk;
 } phFriNfc_MfStd_AddInfo_t;
 
+
+ /*
+ *  \ingroup grp_fri_smart_card_formatting
+ *  \brief NFC Smart Card Formatting Component ISO-15693 Additional Information Structure
+ *
+ *  This structure is used to specify additional information required to format the ISO-15693 card.
+ *  \note 
+ *         On requirement basis,structure will be filled/modified with other parametes
+ *         during the implementation phase.
+ *
+ */
+ typedef struct phFriNfc_ISO15693_AddInfo
+ {
+    /* Stores the current block executed */
+    uint16_t        current_block;
+    /* Sequence executed */
+    uint8_t         format_seq;
+    /* Maximum data size in the card */
+    uint16_t        max_data_size;
+ }phFriNfc_ISO15693_AddInfo_t;
+
 /**
  *  \ingroup grp_fri_smart_card_formatting
  *
@@ -264,6 +285,7 @@
    phFriNfc_Type2_AddInfo_t         Type2Info;
    phFriNfc_Type4_AddInfo_t         Type4Info;
    phFriNfc_MfStd_AddInfo_t         MfStdInfo;
+   phFriNfc_ISO15693_AddInfo_t      s_iso15693_info;
 
 }phFriNfc_sNdefSmtCrdFmt_AddInfo_t;
 
diff --git a/src/phLibNfc_ndef_raw.c b/src/phLibNfc_ndef_raw.c
index 1da598a..1e5b395 100644
--- a/src/phLibNfc_ndef_raw.c
+++ b/src/phLibNfc_ndef_raw.c
@@ -19,10 +19,10 @@
 
  * Project: NFC FRI 1.1
  *
- * $Date: Thu Apr 22 13:59:50 2010 $
- * $Author: ing07385 $
- * $Revision: 1.70 $
- * $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $
+ * $Date: Mon Dec 13 14:14:15 2010 $
+ * $Author: ing02260 $
+ * $Revision: 1.74 $
+ * $Aliases:  $
  *
  */
 
@@ -1441,6 +1441,7 @@
                 }
 
                 case phHal_eJewel_PICC:
+                case phHal_eISO15693_PICC:
                 {
 // MC: Got the feedback this was #if 0'd because it was resetting the lock bits
 // read in check NDEF, and these should not be reset here already.