Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 NXP Semiconductors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * \file  phFriNfc_MifULFormat.c
     19  * \brief NFC Ndef Formatting For Mifare ultralight card.
     20  *
     21  * Project: NFC-FRI
     22  *
     23  * $Date: Mon Dec 13 14:14:12 2010 $
     24  * $Author: ing02260 $
     25  * $Revision: 1.9 $
     26  * $Aliases:  $
     27  *
     28  */
     29 
     30 #include <phFriNfc_MifULFormat.h>
     31 #include <phFriNfc_OvrHal.h>
     32 
     33 /*! \ingroup grp_file_attributes
     34  *  \name NDEF Mapping
     35  *
     36  * File: \ref phFriNfc_MifULFormat.c
     37  *
     38  */
     39 /*@{*/
     40 #define PHFRINFCMIFULFORMAT_FILEREVISION "$Revision: 1.9 $"
     41 #define PHFRINFCMIFULFORMAT_FILEALIASES  "$Aliases:  $"
     42 /*@}*/
     43 
     44 #ifdef FRINFC_READONLY_NDEF
     45     /* Mifare UL OTP block number is 3 */
     46     #define RD_LOCK_OTP_BLOCK_NUMBER            0x02U
     47     #define OTP_BLOCK_NUMBER                    0x03U
     48     /* READ ONLY value that shall be written in the OTP to make the card read only */
     49     #define READ_ONLY_VALUE_IN_OTP              0x0FU
     50     /* Mifare UL OTP block number is 3 */
     51     #define MIFARE_UL_READ_MAX_SIZE             16U
     52     /* 1st Lock byte value */
     53     #define MIFARE_UL_LOCK_BYTE1_VALUE          0xF8U
     54     /* 2nd Lock byte value */
     55     #define MIFARE_UL_LOCK_BYTE2_VALUE          0xFFU
     56     /* Mifare ULC dynamic lock byte address */
     57     #define MIFARE_ULC_DYNAMIC_LOCK_BYTES_ADDR  0x28U
     58     /* Type 2 STATIC CARD memory value in the OTP */
     59     #define TYPE_2_STATIC_MEM_SIZE_VALUE        0x06U
     60     /* Type 2 DYNAMIC CARD memory value in the OTP */
     61     #define TYPE_2_DYNAMIC_MEM_SIZE_VALUE       0x12U
     62     /* Lock byte 3 value to be ORed with the existing value */
     63     #define MIFARE_UL_LOCK_BYTE3_VALUE          0xEEU
     64     /* Posiiton of the memory information in the stored OTP bytes */
     65     #define TYPE_2_MEM_SIZE_POSITION            0x02U
     66     /* 3rd Lock byte position after reading the block number 0x28 */
     67     #define TYPE_2_LOCK_BYTE3_POS_RD_BLK28      0x00U
     68 
     69 #ifdef PH_NDEF_MIFARE_ULC
     70 
     71     /* Lock control TLVs, TYPE identifier */
     72     #define LOCK_CTRL_TYPE_IN_TLV               0x01U
     73     /* Lock control TLVs, Length expected */
     74     #define LOCK_CTRL_LEN_IN_TLV                0x03U
     75 
     76     /* NDEF message TLVs, TYPE identifier */
     77     #define NDEF_TYPE_IN_TLV                    0x03U
     78 
     79     #define MFUL_NULL_TLV                       0x00U
     80     #define THREE_BYTE_LENGTH_FIELD             0xFFU
     81     #define TERMINATOR_TLV                      0xFEU
     82     #define MIFARE_ULC_SIZE                     0xC0U
     83     #define MFUL_NIBBLE_SIZE                    0x04U
     84     #define MFUL_NIBBLE_MASK                    0x0FU
     85     #define MFUL_BYTE_SIZE_IN_BITS              0x08U
     86     #define MFUL_BLOCK_SIZE_IN_BYTES            0x04U
     87     /* Initial (0 to 3 blocks) 4 blocks are ignored, i.e., 16 bytes */
     88     #define MFUL_INITIAL_BYTES_IGNORED          0x10U
     89 
     90     #define MFUL_CONVERT_BITS_TO_BYTES(bits_to_bytes) \
     91             (((bits_to_bytes % MFUL_BYTE_SIZE_IN_BITS) > 0) ? \
     92             ((bits_to_bytes / MFUL_BYTE_SIZE_IN_BITS) + 1) : \
     93             (bits_to_bytes / MFUL_BYTE_SIZE_IN_BITS))
     94 
     95     typedef enum phFriNfc_MfUL_Parse
     96     {
     97         LOCK_TLV_T,
     98         LOCK_TLV_L,
     99         LOCK_TLV_V,
    100         NDEF_TLV_T,
    101         NDEF_TLV_L,
    102         NDEF_TLV_V
    103     }phFriNfc_MfUL_Parse_t;
    104 
    105 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
    106 
    107 #endif /* #ifdef FRINFC_READONLY_NDEF */
    108 /*!
    109 * \brief \copydoc page_ovr Helper function for Mifare UL. This function calls the
    110 * transceive function
    111 */
    112 static NFCSTATUS phFriNfc_MfUL_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
    113 
    114 /*!
    115 * \brief \copydoc page_ovr Helper function for Mifare UL. This function calls the
    116 * read or write operation
    117 */
    118 static NFCSTATUS phFriNfc_MfUL_H_WrRd(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
    119 
    120 /*!
    121 * \brief \copydoc page_ovr Helper function for Mifare UL. This function fills the
    122 * send buffer for transceive function
    123 */
    124 static void phFriNfc_MfUL_H_fillSendBuf(phFriNfc_sNdefSmtCrdFmt_t   *NdefSmtCrdFmt,
    125                                         uint8_t                     BlockNo);
    126 
    127 /*!
    128 * \brief \copydoc page_ovr Helper function for Mifare UL. This function shall process
    129 * the read bytes
    130 */
    131 static NFCSTATUS phFriNfc_MfUL_H_ProRd16Bytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
    132 
    133 /*!
    134 * \brief \copydoc page_ovr Helper function for Mifare UL. This function shall process the
    135 * OTP bytes written
    136 */
    137 static NFCSTATUS phFriNfc_MfUL_H_ProWrOTPBytes(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
    138 
    139 #ifdef FRINFC_READONLY_NDEF
    140 
    141 #ifdef PH_NDEF_MIFARE_ULC
    142 
    143 static
    144 NFCSTATUS
    145 phFriNfc_MfUL_ParseTLVs (
    146     phFriNfc_sNdefSmtCrdFmt_t       *NdefSmtCrdFmt,
    147     uint8_t                         *data_to_parse,
    148     uint8_t                         size_to_parse);
    149 
    150 static
    151 NFCSTATUS
    152 phFriNfc_MfUL_GetLockBytesInfo (
    153     phFriNfc_sNdefSmtCrdFmt_t       *NdefSmtCrdFmt);
    154 
    155 static
    156 NFCSTATUS
    157 phFriNfc_MfUL_GetDefaultLockBytesInfo (
    158     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt);
    159 
    160 static
    161 uint8_t
    162 phFriNfc_MfUL_GetSkipSize (
    163     phFriNfc_sNdefSmtCrdFmt_t       *NdefSmtCrdFmt,
    164     uint8_t                         block_number,
    165     uint8_t                         byte_number);
    166 
    167 static
    168 NFCSTATUS
    169 phFriNfc_MfUL_ReadWriteLockBytes (
    170     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt);
    171 
    172 static
    173 NFCSTATUS
    174 phFriNfc_MfUL_UpdateAndWriteLockBits (
    175     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt);
    176 
    177 static
    178 uint8_t
    179 phFriNfc_MfUL_CalcRemainingLockBits (
    180     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt);
    181 
    182 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
    183 
    184 #endif /* #ifdef FRINFC_READONLY_NDEF */
    185 
    186 static int MemCompare1 ( void *s1, void *s2, unsigned int n );
    187 /*The function does a comparision of two strings and returns a non zero value
    188 if two strings are unequal*/
    189 static int MemCompare1 ( void *s1, void *s2, unsigned int n )
    190 {
    191     int8_t   diff = 0;
    192     int8_t *char_1  =(int8_t *)s1;
    193     int8_t *char_2  =(int8_t *)s2;
    194     if(NULL == s1 || NULL == s2)
    195     {
    196         PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare");
    197     }
    198     else
    199     {
    200         for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
    201         {
    202             diff = *char_1 - *char_2;
    203         }
    204     }
    205     return (int)diff;
    206 }
    207 
    208 void phFriNfc_MfUL_Reset(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
    209 {
    210     uint8_t OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES;
    211 
    212     NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0;
    213     (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
    214                 OTPByte,
    215                 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
    216 #ifdef FRINFC_READONLY_NDEF
    217     NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[0] = 0;
    218     NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[1] = 0;
    219     NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] = 0;
    220     NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[3] = 0;
    221 #endif /* #ifdef FRINFC_READONLY_NDEF */
    222 }
    223 
    224 NFCSTATUS phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
    225 {
    226     NFCSTATUS               Result = NFCSTATUS_SUCCESS;
    227     uint8_t                 OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES;
    228 
    229     NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0;
    230     (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
    231                 OTPByte,
    232                 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
    233 
    234     /* Set the state */
    235     NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RD_16BYTES;
    236     /* Initialise current block to the lock bits block */
    237     NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_2;
    238 
    239     /* Start authentication */
    240     Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt);
    241     return Result;
    242 }
    243 
    244 #ifdef FRINFC_READONLY_NDEF
    245 
    246 NFCSTATUS
    247 phFriNfc_MfUL_ConvertToReadOnly (
    248     phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
    249 {
    250     NFCSTATUS               result = NFCSTATUS_SUCCESS;
    251 
    252     NdefSmtCrdFmt->AddInfo.Type2Info.DefaultLockBytesFlag = TRUE;
    253     NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = 0;
    254 
    255     NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_RD_16BYTES;
    256 
    257     result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    258 
    259     return result;
    260 }
    261 
    262 #endif /* #ifdef FRINFC_READONLY_NDEF */
    263 
    264 void phFriNfc_MfUL_Process(void             *Context,
    265                            NFCSTATUS        Status)
    266 {
    267     phFriNfc_sNdefSmtCrdFmt_t  *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
    268 
    269     if(Status == NFCSTATUS_SUCCESS)
    270     {
    271         switch(NdefSmtCrdFmt->State)
    272         {
    273         case PH_FRINFC_MFUL_FMT_RD_16BYTES:
    274             Status = phFriNfc_MfUL_H_ProRd16Bytes(NdefSmtCrdFmt);
    275             break;
    276 
    277         case PH_FRINFC_MFUL_FMT_WR_OTPBYTES:
    278             Status = phFriNfc_MfUL_H_ProWrOTPBytes(NdefSmtCrdFmt);
    279             break;
    280 
    281         case PH_FRINFC_MFUL_FMT_WR_TLV:
    282 #ifdef PH_NDEF_MIFARE_ULC
    283             if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD)
    284             {
    285                 /* Write NDEF TLV in block number 5 */
    286                 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
    287                                                         PH_FRINFC_MFUL_FMT_VAL_5;
    288                 /* Card already have the OTP bytes so write TLV */
    289                 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV1;
    290 
    291                 Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    292             }
    293 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
    294 
    295             break;
    296 
    297 #ifdef FRINFC_READONLY_NDEF
    298 
    299         case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES:
    300         {
    301             if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength)
    302             {
    303                 uint8_t         otp_lock_page_size = 0;
    304                 uint8_t         i = 0;
    305 
    306                 otp_lock_page_size = sizeof (NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes);
    307                 (void)memcpy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes,
    308                             (void *)NdefSmtCrdFmt->SendRecvBuf,
    309                             sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes));
    310 
    311                 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] = (uint8_t)
    312                                     (NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2]
    313                                     | MIFARE_UL_LOCK_BYTE1_VALUE);
    314                 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[3] = MIFARE_UL_LOCK_BYTE2_VALUE;
    315                 i = (uint8_t)(i + otp_lock_page_size);
    316 
    317                 otp_lock_page_size = sizeof (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes);
    318 
    319                 (void)memcpy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
    320                             (void *)(NdefSmtCrdFmt->SendRecvBuf + i),
    321                             sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
    322 
    323                 NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[(otp_lock_page_size - 1)] =
    324                                                         READ_ONLY_VALUE_IN_OTP;
    325 
    326                 switch (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION])
    327                 {
    328                     case TYPE_2_STATIC_MEM_SIZE_VALUE:
    329                     {
    330                         NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES;
    331                         Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    332                         break;
    333                     }
    334 
    335 #ifdef PH_NDEF_MIFARE_ULC
    336                     case TYPE_2_DYNAMIC_MEM_SIZE_VALUE:
    337                     {
    338                         NdefSmtCrdFmt->State =
    339                                 PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES;
    340 
    341                         /* Start reading from block 4 */
    342                         NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 4;
    343                         Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    344                         break;
    345                     }
    346 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
    347 
    348                     default:
    349                     {
    350                         Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    351                                             NFCSTATUS_INVALID_DEVICE_REQUEST);
    352                         break;
    353                     }
    354                 }
    355             }
    356             else
    357             {
    358                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    359                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
    360             }
    361             break;
    362         }
    363 
    364         case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES:
    365         {
    366             switch (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION])
    367             {
    368                 case TYPE_2_STATIC_MEM_SIZE_VALUE:
    369 #ifdef PH_NDEF_MIFARE_ULC
    370                 case TYPE_2_DYNAMIC_MEM_SIZE_VALUE:
    371 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
    372                 {
    373                     NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES;
    374                     Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    375                     break;
    376                 }
    377 
    378                 default:
    379                 {
    380                     Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    381                                         NFCSTATUS_INVALID_DEVICE_REQUEST);
    382                     break;
    383                 }
    384             }
    385             break;
    386         }
    387 
    388 #ifdef PH_NDEF_MIFARE_ULC
    389 
    390         case PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES:
    391         {
    392             if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength)
    393             {
    394                 Status = phFriNfc_MfUL_ParseTLVs (NdefSmtCrdFmt,
    395                                         NdefSmtCrdFmt->SendRecvBuf,
    396                                         (uint8_t)*NdefSmtCrdFmt->SendRecvLength);
    397 
    398                 if (!Status)
    399                 {
    400                     NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
    401                         NdefSmtCrdFmt->AddInfo.Type2Info.LockBlockNumber;
    402                     Status = phFriNfc_MfUL_ReadWriteLockBytes (NdefSmtCrdFmt);
    403                 }
    404             }
    405             else
    406             {
    407                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    408                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
    409             }
    410             break;
    411         }
    412 
    413         case PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES:
    414         {
    415             if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength)
    416             {
    417                 (void)memcpy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.ReadData,
    418                             (void *)NdefSmtCrdFmt->SendRecvBuf,
    419                             sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.ReadData));
    420 
    421                 NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = 0;
    422 
    423                 Status = phFriNfc_MfUL_UpdateAndWriteLockBits (NdefSmtCrdFmt);
    424 
    425             }
    426             else
    427             {
    428                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    429                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
    430             }
    431             break;
    432         }
    433 
    434         case PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES:
    435         {
    436             NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = (uint8_t)
    437                                     (NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex +
    438                                     MFUL_BLOCK_SIZE_IN_BYTES);
    439 
    440             if (!phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt))
    441             {
    442                 /* There is no lock bits to write, then write OTP bytes */
    443                 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES;
    444                 Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    445             }
    446             else if ((NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex <
    447                 MIFARE_UL_READ_MAX_SIZE)
    448                 && (phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt)))
    449             {
    450                 /* If remaining lock bits has to be written and the data is already read */
    451                 Status = phFriNfc_MfUL_UpdateAndWriteLockBits (NdefSmtCrdFmt);
    452             }
    453             else
    454             {
    455                 /* Increment current block by 4 because if a data is read then 16
    456                     bytes will be given which is 4 blocks */
    457                 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = (uint8_t)
    458                             (NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock + 4);
    459                 Status = phFriNfc_MfUL_ReadWriteLockBytes (NdefSmtCrdFmt);
    460             }
    461             break;
    462         }
    463 
    464 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
    465 
    466         case PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES:
    467         {
    468             /* Do nothing */
    469             break;
    470         }
    471 
    472 #endif /* #ifdef FRINFC_READONLY_NDEF */
    473 
    474 #ifdef PH_NDEF_MIFARE_ULC
    475         case PH_FRINFC_MFUL_FMT_WR_TLV1:
    476 
    477         break;
    478 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
    479 
    480         default:
    481             Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    482                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
    483             break;
    484         }
    485     }
    486     /* Status is not success then call completion routine */
    487     if(Status != NFCSTATUS_PENDING)
    488     {
    489         phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status);
    490     }
    491 }
    492 
    493 #ifdef FRINFC_READONLY_NDEF
    494 
    495 #ifdef PH_NDEF_MIFARE_ULC
    496 
    497 static
    498 uint8_t
    499 phFriNfc_MfUL_GetSkipSize (
    500     phFriNfc_sNdefSmtCrdFmt_t       *NdefSmtCrdFmt,
    501     uint8_t                         block_number,
    502     uint8_t                         byte_number)
    503 {
    504     uint8_t                     skip_size = 0;
    505     phFriNfc_Type2_AddInfo_t    *ps_type2_info =
    506                                 &NdefSmtCrdFmt->AddInfo.Type2Info;
    507 
    508     /* This check is added, because the default lock bits is always
    509         present after the DATA AREA.
    510         So, default lock bytes doesnt have any skip size */
    511     if (!ps_type2_info->DefaultLockBytesFlag)
    512     {
    513         /* Only check for the lock control TLV */
    514         if ((block_number == ps_type2_info->LockBlockNumber)
    515             && (byte_number == ps_type2_info->LockByteNumber))
    516         {
    517             skip_size = MFUL_CONVERT_BITS_TO_BYTES(ps_type2_info->NoOfLockBits);
    518         }
    519     }
    520 
    521     return skip_size;
    522 }
    523 
    524 static
    525 NFCSTATUS
    526 phFriNfc_MfUL_GetLockBytesInfo (
    527     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt)
    528 {
    529     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
    530     phFriNfc_Type2_AddInfo_t        *ps_type2_info =
    531                                     &(NdefSmtCrdFmt->AddInfo.Type2Info);
    532     uint8_t                         page_address = 0;
    533     uint8_t                         bytes_offset = 0;
    534     uint8_t                         lock_index = 0;
    535 
    536 
    537     page_address = (uint8_t)(ps_type2_info->DynLockBytes[lock_index] >> MFUL_NIBBLE_SIZE);
    538     bytes_offset = (uint8_t)(ps_type2_info->DynLockBytes[lock_index] & MFUL_NIBBLE_MASK);
    539 
    540     lock_index = (lock_index + 1);
    541     ps_type2_info->NoOfLockBits = ps_type2_info->DynLockBytes[lock_index];
    542 
    543     lock_index = (lock_index + 1);
    544     ps_type2_info->LockBytesPerPage =
    545                             (ps_type2_info->DynLockBytes[lock_index] & MFUL_NIBBLE_MASK);
    546     ps_type2_info->BytesLockedPerLockBit =
    547                             (ps_type2_info->DynLockBytes[lock_index] >> MFUL_NIBBLE_SIZE);
    548 
    549     /* Apply the formula to calculate byte address
    550         ByteAddr = ((PageAddr * (2 ^ BytesPerPage)) + ByteOffset)
    551     */
    552     ps_type2_info->LockByteNumber = (uint8_t)((page_address
    553                                 * (1 << ps_type2_info->LockBytesPerPage))
    554                                 + bytes_offset);
    555 
    556     ps_type2_info->LockBlockNumber = (uint8_t)(ps_type2_info->LockByteNumber /
    557                                                 MFUL_BLOCK_SIZE_IN_BYTES);
    558     ps_type2_info->LockByteNumber = (uint8_t)(ps_type2_info->LockByteNumber %
    559                                                 MFUL_BLOCK_SIZE_IN_BYTES);
    560 
    561 #if 0
    562     if (
    563         /* Out of bound memory check */
    564         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) >
    565         (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] *
    566         TOPAZ_BYTES_PER_BLOCK)) ||
    567 
    568         /* Check the static lock and reserved areas memory blocks */
    569         ((ps_locktlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) &&
    570         (ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) ||
    571         (((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) >=
    572         TOPAZ_STATIC_LOCK_RES_START) &&
    573         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) <
    574         TOPAZ_STATIC_LOCK_RES_END))
    575         )
    576     {
    577         ps_locktlv_info->ByteAddr = 0;
    578         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    579                             NFCSTATUS_NO_NDEF_SUPPORT);
    580     }
    581     else
    582     {
    583         ps_locktlv_info->BlkNum = (ps_locktlv_info->ByteAddr /
    584                                     TOPAZ_BYTES_PER_BLOCK);
    585         ps_locktlv_info->ByteNum = (ps_locktlv_info->ByteAddr %
    586                                     TOPAZ_BYTES_PER_BLOCK);
    587     }
    588 #endif /* #if 0 */
    589 
    590     return result;
    591 }
    592 
    593 static
    594 uint8_t
    595 phFriNfc_MfUL_CalcRemainingLockBits (
    596     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt)
    597 {
    598     uint8_t                         lock_bits_remaining = 0;
    599     phFriNfc_Type2_AddInfo_t        *ps_type2_info =
    600                                     &(NdefSmtCrdFmt->AddInfo.Type2Info);
    601 
    602     lock_bits_remaining = (uint8_t)(ps_type2_info->NoOfLockBits -
    603                                     ps_type2_info->LockBitsWritten);
    604 
    605     return lock_bits_remaining;
    606 }
    607 
    608 static
    609 NFCSTATUS
    610 phFriNfc_MfUL_UpdateAndWriteLockBits (
    611     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt)
    612 {
    613     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
    614     phFriNfc_Type2_AddInfo_t        *ps_type2_info =
    615                                     &(NdefSmtCrdFmt->AddInfo.Type2Info);
    616     uint8_t                         byte_index = 0;
    617     uint8_t                         no_of_bits_left_in_block = 0;
    618     uint8_t                         remaining_lock_bits = 0;
    619     uint8_t                         remaining_lock_bytes = 0;
    620     /* Array of 3 is used because the lock bits with 4 bytes in a block
    621         is handled in the function phFriNfc_MfUL_ReadWriteLockBytes
    622         So use this function only if lock bytes doesnt use the entire block */
    623     uint8_t                         lock_bytes_value[MFUL_BLOCK_SIZE_IN_BYTES] = {0};
    624     uint8_t                         lock_byte_index = 0;
    625 
    626     (void)memcpy ((void *)lock_bytes_value,
    627                 (void*)(ps_type2_info->ReadData + ps_type2_info->ReadDataIndex),
    628                 sizeof (ps_type2_info->DynLockBytes));
    629     remaining_lock_bits = phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt);
    630 
    631     if (ps_type2_info->CurrentBlock == ps_type2_info->LockBlockNumber)
    632     {
    633         /* 1st write to lock bits, so byte_index is updated */
    634         byte_index = ps_type2_info->LockByteNumber;
    635     }
    636 
    637     no_of_bits_left_in_block = (uint8_t)((MFUL_BLOCK_SIZE_IN_BYTES - byte_index) *
    638                                 MFUL_BYTE_SIZE_IN_BITS);
    639 
    640     if (no_of_bits_left_in_block >= remaining_lock_bits)
    641     {
    642         /* Entire lock bits can be written
    643             if block size is more than number of lock bits.
    644             so allocate the lock bits with value 1b and
    645             dont change the remaining bits */
    646         if (remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS)
    647         {
    648             /* mod operation has resulted in a value, means lock bits ends in between a byte */
    649             uint8_t         mod_value = 0;
    650 
    651             remaining_lock_bytes = ((remaining_lock_bits /
    652                                     MFUL_BYTE_SIZE_IN_BITS) + 1);
    653 
    654             /* mod_value is used to fill the only partial bits and
    655                 remaining bits shall be untouched */
    656             mod_value = (uint8_t)(remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS);
    657             if (remaining_lock_bits > MFUL_BYTE_SIZE_IN_BITS)
    658             {
    659                 /* lock bits to write is greater than 8 bits */
    660                 while (lock_byte_index < (remaining_lock_bytes - 1))
    661                 {
    662                     /* Set 1b to all bits left in the block */
    663                     lock_bytes_value[byte_index] = 0xFF;
    664                     lock_byte_index = (uint8_t)(lock_byte_index + 1);
    665                     byte_index = (uint8_t)(byte_index + 1);
    666                 }
    667                 /* Last byte of the lock bits shall be filled partially,
    668                     Set only the remaining lock bits and dont change
    669                     the other bit value */
    670                 lock_bytes_value[byte_index] = 0;
    671                 lock_bytes_value[byte_index] = (uint8_t)
    672                         SET_BITS8 (lock_bytes_value[byte_index], 0,
    673                                     mod_value, 1);
    674             }
    675             else
    676             {
    677                 /* lock bits to write is less than 8 bits, so
    678                     there is only one byte to write.
    679                     Set only the remaining lock bits and dont change
    680                     the other bit value */
    681                 lock_bytes_value[0] = (uint8_t)SET_BITS8 (lock_bytes_value[0], 0,
    682                                                         mod_value, 1);
    683             }
    684         } /* if (remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS) */
    685         else
    686         {
    687             /* MOD operation is 00, that means entire byte value shall be 0xFF, means
    688             every bit shall be to 1 */
    689             remaining_lock_bytes = (remaining_lock_bits /
    690                                     MFUL_BYTE_SIZE_IN_BITS);
    691 
    692             while (lock_byte_index < remaining_lock_bytes)
    693             {
    694                 /* Set 1b to all bits left in the block */
    695                 lock_bytes_value[byte_index] = 0xFF;
    696                 lock_byte_index = (uint8_t)(lock_byte_index + 1);
    697                 byte_index = (uint8_t)(byte_index + 1);
    698             }
    699         } /* else of if (remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS) */
    700         ps_type2_info->LockBitsWritten = (uint8_t)(ps_type2_info->LockBitsWritten +
    701                                             remaining_lock_bits);
    702     } /* if (no_of_bits_left_in_block >= remaining_lock_bits) */
    703     else
    704     {
    705         /* Update till the left bits in the block and then carry
    706             out next operation after this write */
    707         while (lock_byte_index < (no_of_bits_left_in_block / MFUL_BYTE_SIZE_IN_BITS))
    708         {
    709             /* Set 1b to all bits left in the block */
    710             lock_bytes_value[byte_index] = 0xFF;
    711             lock_byte_index = (uint8_t)(lock_byte_index + 1);
    712             byte_index = (uint8_t)(byte_index + 1);
    713         }
    714         ps_type2_info->LockBitsWritten = (uint8_t)(ps_type2_info->LockBitsWritten +
    715                                             no_of_bits_left_in_block);
    716     } /* else of if (no_of_bits_left_in_block >= remaining_lock_bits) */
    717 
    718 
    719     /* Copy the values back to the DynLockBytes structure member */
    720     (void)memcpy ((void*)ps_type2_info->DynLockBytes,
    721                 (void *)lock_bytes_value,
    722                 sizeof (ps_type2_info->DynLockBytes));
    723 
    724 
    725     NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES;
    726     result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    727 
    728     return result;
    729 }
    730 
    731 static
    732 NFCSTATUS
    733 phFriNfc_MfUL_ReadWriteLockBytes (
    734     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt)
    735 {
    736     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
    737     phFriNfc_Type2_AddInfo_t        *ps_type2_info =
    738                                     &(NdefSmtCrdFmt->AddInfo.Type2Info);
    739     uint8_t                         write_flag = FALSE;
    740 
    741     if (/* Lock bytes starts from the beginning of the block */
    742         (0 == ps_type2_info->LockByteNumber)
    743         /* To make sure this is the first read */
    744         && (ps_type2_info->CurrentBlock == ps_type2_info->LockBlockNumber)
    745         /* Lock bytes are greater than or equal to the block size, i.e., 4 bytes */
    746         && (phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt)
    747         >= (MFUL_BLOCK_SIZE_IN_BYTES * MFUL_BYTE_SIZE_IN_BITS)))
    748     {
    749         /* Then directly write the lock bytes, dont waste time for read  */
    750         (void)memset ((void *)ps_type2_info->DynLockBytes, 0xFF,
    751                         sizeof (ps_type2_info->DynLockBytes));
    752         write_flag = TRUE;
    753     }
    754     else if (ps_type2_info->CurrentBlock == ps_type2_info->LockBlockNumber)
    755     {
    756         /* Read is mandatory, First read and then update the block,
    757             because chances are there that lock byte may start in between
    758             the block */
    759     }
    760     else if (/* check if remaining bytes exceeds or same as the block size */
    761         (phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt)
    762         >= (MFUL_BLOCK_SIZE_IN_BYTES * MFUL_BYTE_SIZE_IN_BITS)))
    763     {
    764         /* Then directly write the lock bytes, dont waste time for read */
    765         (void)memset ((void *)ps_type2_info->DynLockBytes, 0xFF,
    766                         sizeof (ps_type2_info->DynLockBytes));
    767         write_flag = TRUE;
    768     }
    769     else
    770     {
    771         /* Read is mandatory, First read and then update the block */
    772     }
    773 
    774     if (write_flag)
    775     {
    776         NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES;
    777         result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    778     }
    779     else
    780     {
    781         NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES;
    782         result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
    783     }
    784 
    785     return result;
    786 }
    787 
    788 static
    789 NFCSTATUS
    790 phFriNfc_MfUL_GetDefaultLockBytesInfo (
    791     phFriNfc_sNdefSmtCrdFmt_t          *NdefSmtCrdFmt)
    792 {
    793     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
    794     phFriNfc_Type2_AddInfo_t        *ps_type2_info =
    795                                     &(NdefSmtCrdFmt->AddInfo.Type2Info);
    796     uint16_t                        lock_byte_start_addr = 0;
    797 
    798     /*  The position of the dynamic lock bits starts from
    799         the first byte after the data area */
    800     lock_byte_start_addr = (uint16_t)(MFUL_INITIAL_BYTES_IGNORED +
    801                         (ps_type2_info->OTPBytes[TYPE_2_MEM_SIZE_POSITION] * 8));
    802 
    803     ps_type2_info->LockBlockNumber = (uint8_t)(lock_byte_start_addr /
    804                                                 MFUL_BLOCK_SIZE_IN_BYTES);
    805     ps_type2_info->LockByteNumber = (uint8_t)(lock_byte_start_addr %
    806                                                 MFUL_BLOCK_SIZE_IN_BYTES);
    807     /* Default settings
    808        NoOfLockBits = [(DataAreaSize - 48)/8] */
    809     ps_type2_info->NoOfLockBits = (uint8_t)
    810         (((ps_type2_info->OTPBytes[TYPE_2_MEM_SIZE_POSITION] * 8) - 48)/8);
    811 
    812     return result;
    813 }
    814 
    815 static
    816 NFCSTATUS
    817 phFriNfc_MfUL_ParseTLVs (
    818     phFriNfc_sNdefSmtCrdFmt_t       *NdefSmtCrdFmt,
    819     uint8_t                         *data_to_parse,
    820     uint8_t                         size_to_parse)
    821 {
    822     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
    823     static uint8_t                  lock_mem_ndef_index = 0;
    824     static uint8_t                  skip_lock_mem_size = 0;
    825     static uint16_t                 card_size_remaining = 0;
    826     static uint16_t                 ndef_data_size = 0;
    827     static phFriNfc_MfUL_Parse_t    parse_tlv = LOCK_TLV_T;
    828     uint8_t                         parse_index = 0;
    829 
    830     if ((0 == card_size_remaining) && (0 == parse_index))
    831     {
    832         /* card size is calculated only once */
    833         card_size_remaining = (uint16_t)
    834             (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION] * 8);
    835     }
    836 
    837     while ((parse_index < size_to_parse)
    838         && (NFCSTATUS_SUCCESS == result)
    839         && (NDEF_TLV_V != parse_tlv)
    840         && (0 != card_size_remaining))
    841     {
    842         if (0 == skip_lock_mem_size)
    843         {
    844             /* Skip the lock TLVs, so get the lock bits */
    845             skip_lock_mem_size = phFriNfc_MfUL_GetSkipSize (NdefSmtCrdFmt,
    846                                         NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock,
    847                                         parse_index);
    848         }
    849 
    850         if (0 != skip_lock_mem_size)
    851         {
    852             if (skip_lock_mem_size >= (size_to_parse - parse_index))
    853             {
    854                 /* if skip size is more than the size to parse, then  */
    855                 card_size_remaining = (uint16_t)(card_size_remaining -
    856                                     (size_to_parse - parse_index));
    857                 skip_lock_mem_size = (uint8_t)(skip_lock_mem_size -
    858                                             ((size_to_parse - parse_index)));
    859                 parse_index = size_to_parse;
    860             }
    861             else
    862             {
    863                 card_size_remaining = (uint16_t)(card_size_remaining -
    864                                         skip_lock_mem_size);
    865 
    866                 parse_index = (uint8_t)(parse_index + skip_lock_mem_size);
    867                 skip_lock_mem_size = 0;
    868             }
    869         }
    870         else
    871         {
    872             switch (parse_tlv)
    873             {
    874                 case LOCK_TLV_T:
    875                 {
    876                     switch (*(data_to_parse + parse_index))
    877                     {
    878                         case MFUL_NULL_TLV:
    879                         {
    880                             /* Do nothing, parse further */
    881                             break;
    882                         }
    883 
    884                         case LOCK_CTRL_TYPE_IN_TLV:
    885                         {
    886                             parse_tlv = LOCK_TLV_L;
    887                             break;
    888                         }
    889 
    890                         case NDEF_TYPE_IN_TLV:
    891                         {
    892                             parse_tlv = NDEF_TLV_L;
    893                             /* Default lock bytes shall be taken */
    894                             NdefSmtCrdFmt->AddInfo.Type2Info.DefaultLockBytesFlag =
    895                                                                             TRUE;
    896                             result = phFriNfc_MfUL_GetDefaultLockBytesInfo (NdefSmtCrdFmt);
    897                             break;
    898                         }
    899 
    900                         default:
    901                         {
    902                             parse_tlv = LOCK_TLV_T;
    903                             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    904                                                 NFCSTATUS_NO_NDEF_SUPPORT);
    905                             break;
    906                         }
    907                     }
    908                     break;
    909                 }
    910 
    911                 case LOCK_TLV_L:
    912                 {
    913                     if (LOCK_CTRL_LEN_IN_TLV == *(data_to_parse + parse_index))
    914                     {
    915                         parse_tlv = LOCK_TLV_V;
    916                     }
    917                     else
    918                     {
    919                         skip_lock_mem_size = 0;
    920                         parse_tlv = LOCK_TLV_T;
    921                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    922                                                 NFCSTATUS_NO_NDEF_SUPPORT);
    923                     }
    924                     break;
    925                 }
    926 
    927                 case LOCK_TLV_V:
    928                 {
    929                     switch (lock_mem_ndef_index)
    930                     {
    931                         case 0:
    932                         case 1:
    933                         {
    934                             NdefSmtCrdFmt->AddInfo.Type2Info.DefaultLockBytesFlag =
    935                                                                                 FALSE;
    936                             NdefSmtCrdFmt->AddInfo.Type2Info.DynLockBytes[lock_mem_ndef_index] =
    937                                             *(data_to_parse + parse_index);
    938                             lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
    939                             break;
    940                         }
    941 
    942                         case 2:
    943                         {
    944                             NdefSmtCrdFmt->AddInfo.Type2Info.DynLockBytes[lock_mem_ndef_index] =
    945                                             *(data_to_parse + parse_index);
    946                             parse_tlv = NDEF_TLV_T;
    947                             lock_mem_ndef_index = 0;
    948                             result = phFriNfc_MfUL_GetLockBytesInfo (NdefSmtCrdFmt);
    949                             break;
    950                         }
    951 
    952                         default:
    953                         {
    954                             skip_lock_mem_size = 0;
    955                             parse_tlv = LOCK_TLV_T;
    956                             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    957                                                 NFCSTATUS_NO_NDEF_SUPPORT);
    958                             break;
    959                         }
    960                     }
    961                     break;
    962                 } /* switch (lock_mem_ndef_index) in case LOCK_TLV_V */
    963 
    964                 case NDEF_TLV_T:
    965                 {
    966                     switch (*(data_to_parse + parse_index))
    967                     {
    968                         case MFUL_NULL_TLV:
    969                         {
    970                             /* Do nothing, parse further */
    971                             break;
    972                         }
    973 
    974                         case NDEF_TYPE_IN_TLV:
    975                         {
    976                             parse_tlv = NDEF_TLV_L;
    977                             break;
    978                         }
    979 
    980                         default:
    981                         {
    982                             skip_lock_mem_size = 0;
    983                             parse_tlv = LOCK_TLV_T;
    984                             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
    985                                                 NFCSTATUS_NO_NDEF_SUPPORT);
    986                             break;
    987                         }
    988                     }
    989                     break;
    990                 } /* switch (*(data_to_parse + parse_index)) in case NDEF_TLV_T */
    991 
    992                 case NDEF_TLV_L:
    993                 {
    994                     switch (lock_mem_ndef_index)
    995                     {
    996                         case 0:
    997                         {
    998                             if (THREE_BYTE_LENGTH_FIELD == *(data_to_parse + parse_index))
    999                             {
   1000                                 lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
   1001                             }
   1002                             else
   1003                             {
   1004                                 ndef_data_size = *(data_to_parse + parse_index);
   1005                                 parse_tlv = NDEF_TLV_V;
   1006                                 lock_mem_ndef_index = 0;
   1007                             }
   1008                             break;
   1009                         }
   1010 
   1011                         case 1:
   1012                         {
   1013                             ndef_data_size = (uint16_t)(*(data_to_parse + parse_index) << 8);
   1014                             break;
   1015                         }
   1016 
   1017                         case 2:
   1018                         {
   1019                             ndef_data_size = (uint16_t)(ndef_data_size |
   1020                                                         *(data_to_parse + parse_index));
   1021                             parse_tlv = NDEF_TLV_V;
   1022                             lock_mem_ndef_index = 0;
   1023                             break;
   1024                         }
   1025                     } /* switch (lock_mem_ndef_index) in case NDEF_TLV_L */
   1026                     break;
   1027                 }
   1028 
   1029                 case NDEF_TLV_V:
   1030                 {
   1031                     break;
   1032                 }
   1033 
   1034                 default:
   1035                 {
   1036                     skip_lock_mem_size = 0;
   1037                     parse_tlv = LOCK_TLV_T;
   1038                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
   1039                                         NFCSTATUS_NO_NDEF_SUPPORT);
   1040                     break;
   1041                 }
   1042             } /* switch (parse_tlv) */
   1043 
   1044         } /* else part of if (0 != skip_lock_mem_size) */
   1045 
   1046         if (0 == card_size_remaining)
   1047         {
   1048             skip_lock_mem_size = 0;
   1049             parse_tlv = LOCK_TLV_T;
   1050             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
   1051                                 NFCSTATUS_NO_NDEF_SUPPORT);
   1052         }
   1053         else if (NDEF_TLV_V != parse_tlv)
   1054         {
   1055             /* Increment the index */
   1056             parse_index = (uint8_t)(parse_index + 1);
   1057             /* card size is decremented as the memory area is parsed  */
   1058             card_size_remaining = (uint16_t)(card_size_remaining - 1);
   1059         }
   1060         else
   1061         {
   1062             /* L field of the NDEF TLV
   1063                 L field can have 1 byte or also 3 bytes
   1064                */
   1065             uint8_t length_to_deduct = 1;
   1066 
   1067             if ((NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION]
   1068                 * 8) >= THREE_BYTE_LENGTH_FIELD)
   1069             {
   1070                 length_to_deduct = 3;
   1071             }
   1072             /* parse_tlv has reached the VALUE field of the NDEF TLV */
   1073             if ((card_size_remaining - length_to_deduct) < ndef_data_size)
   1074             {
   1075                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
   1076                                     NFCSTATUS_NO_NDEF_SUPPORT);
   1077             }
   1078 
   1079             lock_mem_ndef_index = 0;
   1080             skip_lock_mem_size = 0;
   1081             card_size_remaining = 0;
   1082         }
   1083     } /* while ((parse_index < size_to_parse)
   1084         && (NFCSTATUS_SUCCESS != result)
   1085         && (NDEF_TLV_V != parse_tlv)
   1086         && (0 != card_size_remaining)) */
   1087 
   1088     if ((NDEF_TLV_V == parse_tlv) || (NFCSTATUS_SUCCESS != result))
   1089     {
   1090         parse_tlv = LOCK_TLV_T;
   1091     }
   1092     else
   1093     {
   1094         NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES;
   1095         NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
   1096                         (NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock + 4);
   1097 
   1098         result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt);
   1099     }
   1100 
   1101     if (NFCSTATUS_PENDING != result)
   1102     {
   1103         lock_mem_ndef_index = 0;
   1104         skip_lock_mem_size = 0;
   1105         card_size_remaining = 0;
   1106     }
   1107     return result;
   1108 }
   1109 
   1110 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1111 
   1112 #endif /* #ifdef FRINFC_READONLY_NDEF */
   1113 
   1114 static NFCSTATUS phFriNfc_MfUL_H_WrRd( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
   1115 {
   1116     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
   1117 
   1118     /* Fill the send buffer */
   1119     phFriNfc_MfUL_H_fillSendBuf(NdefSmtCrdFmt,
   1120                             NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock);
   1121 
   1122     /* Call transceive */
   1123     Result = phFriNfc_MfUL_H_Transceive (NdefSmtCrdFmt);
   1124 
   1125     return Result;
   1126 }
   1127 
   1128 static NFCSTATUS phFriNfc_MfUL_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
   1129 {
   1130     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
   1131 
   1132     /* set the data for additional data exchange*/
   1133     NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
   1134     NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0;
   1135     NdefSmtCrdFmt->psDepAdditionalInfo.NAD = 0;
   1136 
   1137     /*set the completion routines for the card operations*/
   1138     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process;
   1139     NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt;
   1140 
   1141     *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
   1142 
   1143     /* Call the Overlapped HAL Transceive function */
   1144     Result = phFriNfc_OvrHal_Transceive(    NdefSmtCrdFmt->LowerDevice,
   1145                                             &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
   1146                                             NdefSmtCrdFmt->psRemoteDevInfo,
   1147                                             NdefSmtCrdFmt->Cmd,
   1148                                             &NdefSmtCrdFmt->psDepAdditionalInfo,
   1149                                             NdefSmtCrdFmt->SendRecvBuf,
   1150                                             NdefSmtCrdFmt->SendLength,
   1151                                             NdefSmtCrdFmt->SendRecvBuf,
   1152                                             NdefSmtCrdFmt->SendRecvLength);
   1153     return Result;
   1154 }
   1155 
   1156 static void phFriNfc_MfUL_H_fillSendBuf( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
   1157                                  uint8_t                    BlockNo)
   1158 {
   1159 #ifdef PH_NDEF_MIFARE_ULC
   1160     uint8_t     NDEFTLV1[4] = {0x01, 0x03, 0xA0, 0x10};
   1161     uint8_t     NDEFTLV2[4] = {0x44, 0x03, 0x00, 0xFE};
   1162 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1163     uint8_t     NDEFTLV[4] = {0x03, 0x00, 0xFE, 0x00};
   1164 
   1165 
   1166 
   1167 
   1168     /* First byte for send buffer is always the block number */
   1169     NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_0] = (uint8_t)BlockNo;
   1170     switch(NdefSmtCrdFmt->State)
   1171     {
   1172 #ifdef FRINFC_READONLY_NDEF
   1173 
   1174         case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES:
   1175         {
   1176 #ifdef PH_HAL4_ENABLE
   1177             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
   1178 #else
   1179         /* Read command */
   1180             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
   1181 #endif /* #ifdef PH_HAL4_ENABLE */
   1182             *NdefSmtCrdFmt->SendRecvBuf = RD_LOCK_OTP_BLOCK_NUMBER;
   1183             /* Send length for read command is always one */
   1184             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1;
   1185             break;
   1186         }
   1187 
   1188 #ifdef PH_NDEF_MIFARE_ULC
   1189 
   1190         case PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES:
   1191         {
   1192 #ifdef PH_HAL4_ENABLE
   1193             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
   1194 #else
   1195         /* Read command */
   1196             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
   1197 #endif /* #ifdef PH_HAL4_ENABLE */
   1198             *NdefSmtCrdFmt->SendRecvBuf =
   1199                     NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock;
   1200             /* Send length for read command is always one */
   1201             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1;
   1202             break;
   1203         }
   1204 
   1205         case PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES:
   1206         {
   1207 #ifdef PH_HAL4_ENABLE
   1208             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
   1209 #else
   1210         /* Read command */
   1211             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
   1212 #endif /* #ifdef PH_HAL4_ENABLE */
   1213             *NdefSmtCrdFmt->SendRecvBuf = NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock;
   1214             /* Send length for read command is always one */
   1215             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1;
   1216             break;
   1217         }
   1218 
   1219         case PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES:
   1220         {
   1221 #ifdef PH_HAL4_ENABLE
   1222             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
   1223 #else
   1224             /* Write command */
   1225             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4;
   1226 #endif /* #ifdef PH_HAL4_ENABLE */
   1227 
   1228             /* Send length for read command is always one */
   1229             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
   1230             *NdefSmtCrdFmt->SendRecvBuf = NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock;
   1231             (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1232                          NdefSmtCrdFmt->AddInfo.Type2Info.DynLockBytes,
   1233                          PH_FRINFC_MFUL_FMT_VAL_4);
   1234             break;
   1235         }
   1236 
   1237 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1238 
   1239         case PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES:
   1240         {
   1241 #ifdef PH_HAL4_ENABLE
   1242             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
   1243 #else
   1244             /* Read command */
   1245             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4;
   1246 #endif /* #ifdef PH_HAL4_ENABLE */
   1247 
   1248             /* Send length for read command is always one */
   1249             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
   1250             *NdefSmtCrdFmt->SendRecvBuf = RD_LOCK_OTP_BLOCK_NUMBER;
   1251             (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1252                          NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes,
   1253                          PH_FRINFC_MFUL_FMT_VAL_4);
   1254             break;
   1255         }
   1256 
   1257         case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES:
   1258         {
   1259 #ifdef PH_HAL4_ENABLE
   1260             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
   1261 #else
   1262             /* Read command */
   1263             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4;
   1264 #endif /* #ifdef PH_HAL4_ENABLE */
   1265 
   1266             /* Send length for read command is always one */
   1267             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
   1268             *NdefSmtCrdFmt->SendRecvBuf = OTP_BLOCK_NUMBER;
   1269             (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1270                          NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
   1271                          PH_FRINFC_MFUL_FMT_VAL_4);
   1272             break;
   1273         }
   1274 
   1275 #endif /* #ifdef FRINFC_READONLY_NDEF */
   1276 
   1277     case PH_FRINFC_MFUL_FMT_RD_16BYTES:
   1278 #ifdef PH_HAL4_ENABLE
   1279         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
   1280 #else
   1281         /* Read command */
   1282         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
   1283 #endif /* #ifdef PH_HAL4_ENABLE */
   1284         /* Send length for read command is always one */
   1285         NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1;
   1286         break;
   1287 
   1288     case PH_FRINFC_MFUL_FMT_WR_OTPBYTES:
   1289         /* Send length for read command is always Five */
   1290         NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
   1291         /* Write command */
   1292 #ifdef PH_HAL4_ENABLE
   1293         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
   1294 #else
   1295         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4;
   1296 #endif /* #ifdef PH_HAL4_ENABLE */
   1297         /* Copy the OTP bytes */
   1298         (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1299                     NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
   1300                     PH_FRINFC_MFUL_FMT_VAL_4);
   1301         break;
   1302 
   1303     case PH_FRINFC_MFUL_FMT_WR_TLV:
   1304 #ifndef PH_NDEF_MIFARE_ULC
   1305     default:
   1306 #endif /* #ifndef PH_NDEF_MIFARE_ULC */
   1307         /* Send length for read command is always Five */
   1308         NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
   1309         /* Write command */
   1310 #ifdef PH_HAL4_ENABLE
   1311         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
   1312 #else
   1313         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4;
   1314 #endif /* #ifdef PH_HAL4_ENABLE */
   1315         /* Copy the NDEF TLV */
   1316 #ifdef PH_NDEF_MIFARE_ULC
   1317 
   1318         if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD)
   1319         {
   1320             (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1321                     NDEFTLV1,
   1322                     PH_FRINFC_MFUL_FMT_VAL_4);
   1323         }
   1324         else if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD)
   1325         {
   1326             (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1327                 NDEFTLV,
   1328                 PH_FRINFC_MFUL_FMT_VAL_4);
   1329         }
   1330         else
   1331         {
   1332         }
   1333 #else
   1334         (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1335                     NDEFTLV,
   1336                     PH_FRINFC_MFUL_FMT_VAL_4);
   1337 
   1338 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1339 
   1340         break;
   1341 
   1342 #ifdef PH_NDEF_MIFARE_ULC
   1343     case PH_FRINFC_MFUL_FMT_WR_TLV1:
   1344         if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD)
   1345         {
   1346             /* Send length for write command is always Five */
   1347             NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5;
   1348             /* Write command */
   1349             NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4;
   1350             (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1],
   1351                         NDEFTLV2,
   1352                         PH_FRINFC_MFUL_FMT_VAL_4);
   1353         }
   1354         break;
   1355     default:
   1356         break;
   1357 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1358 
   1359 
   1360     }
   1361 }
   1362 
   1363 static NFCSTATUS phFriNfc_MfUL_H_ProRd16Bytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
   1364 {
   1365     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
   1366                                     NFCSTATUS_FORMAT_ERROR);
   1367     uint32_t    memcompare = PH_FRINFC_MFUL_FMT_VAL_0;
   1368     uint8_t     ZeroBuf[] = {0x00, 0x00, 0x00, 0x00};
   1369 
   1370 #ifdef PH_NDEF_MIFARE_ULC
   1371     uint8_t                 OTPByteUL[] = PH_FRINFC_MFUL_FMT_OTP_BYTES;
   1372     uint8_t                 OTPByteULC[] = PH_FRINFC_MFULC_FMT_OTP_BYTES;
   1373 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1374 
   1375     /* Check the lock bits (byte number 2 and 3 of block number 2) */
   1376     if ((NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_2] ==
   1377         PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL) &&
   1378         (NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_3] ==
   1379         PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL))
   1380     {
   1381 
   1382 #ifdef PH_NDEF_MIFARE_ULC
   1383 
   1384         if (NdefSmtCrdFmt->SendRecvBuf[8] == 0x02 &&
   1385             NdefSmtCrdFmt->SendRecvBuf[9] == 0x00)
   1386         {
   1387             NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD;
   1388 
   1389             (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
   1390                         OTPByteULC,
   1391                         sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
   1392         }
   1393         else if (NdefSmtCrdFmt->SendRecvBuf[8] == 0xFF &&
   1394                 NdefSmtCrdFmt->SendRecvBuf[9] == 0xFF)
   1395         {
   1396             NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD;
   1397 
   1398             (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
   1399                         OTPByteUL,
   1400                         sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes));
   1401         }
   1402         else
   1403         {
   1404             NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD;
   1405         }
   1406 
   1407 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1408 
   1409         memcompare = (uint32_t)
   1410                     MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4],
   1411                             NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes,
   1412                             PH_FRINFC_MFUL_FMT_VAL_4);
   1413 
   1414         if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0)
   1415         {
   1416             /* Write NDEF TLV in block number 4 */
   1417             NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
   1418                                                 PH_FRINFC_MFUL_FMT_VAL_4;
   1419             /* Card already have the OTP bytes so write TLV */
   1420             NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV;
   1421         }
   1422         else
   1423         {
   1424             /* IS the card new, OTP bytes = {0x00, 0x00, 0x00, 0x00} */
   1425             memcompare = (uint32_t)MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4],
   1426                                 ZeroBuf,
   1427                                 PH_FRINFC_MFUL_FMT_VAL_4);
   1428             /* If OTP bytes are Zero then the card is Zero */
   1429             if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0)
   1430             {
   1431                 /* Write OTP bytes in block number 3 */
   1432                 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
   1433                                                 PH_FRINFC_MFUL_FMT_VAL_3;
   1434                 /* Card already have the OTP bytes so write TLV */
   1435                 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_OTPBYTES;
   1436             }
   1437         }
   1438     }
   1439 
   1440 
   1441 
   1442 #ifdef PH_NDEF_MIFARE_ULC
   1443     if(
   1444         ((NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_TLV) ||
   1445         (NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_OTPBYTES)) &&
   1446         ((NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) ||
   1447         (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD))
   1448         )
   1449 #else
   1450     if((NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_TLV) ||
   1451         (NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_OTPBYTES))
   1452 #endif /* #ifdef PH_NDEF_MIFARE_ULC */
   1453     {
   1454         Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt);
   1455     }
   1456     return Result;
   1457 }
   1458 
   1459 static NFCSTATUS phFriNfc_MfUL_H_ProWrOTPBytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
   1460 {
   1461     NFCSTATUS   Result = NFCSTATUS_SUCCESS;
   1462     /* Card already have the OTP bytes so write TLV */
   1463     NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV;
   1464 
   1465     /* Write NDEF TLV in block number 4 */
   1466     NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock =
   1467                                 PH_FRINFC_MFUL_FMT_VAL_4;
   1468 
   1469     Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt);
   1470     return Result;
   1471 }
   1472 
   1473