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_TopazDynamicMap.c
     19 * \brief NFC Ndef Mapping For Remote Devices.
     20 *
     21 * Project: NFC-FRI
     22 *
     23 * $Date: Wed Oct 27 10:21:29 2010 $
     24 * $Author: ing02260 $
     25 * $Revision: 1.41 $
     26 * $Aliases:  $
     27 *
     28 */
     29 
     30 
     31 
     32 #include <phFriNfc_NdefMap.h>
     33 #include <phFriNfc_TopazMap.h>
     34 #include <phFriNfc_MapTools.h>
     35 #include <phFriNfc_OvrHal.h>
     36 
     37 #if !(defined(PH_FRINFC_MAP_TOPAZ_DISABLED ) || defined (PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED ))
     38 
     39 /*! \ingroup grp_file_attributes
     40 *  \name NDEF Mapping
     41 *
     42 * File: \ref phFriNfcNdefMap.c
     43 *
     44 */
     45 /*@{*/
     46 #define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.41 $"
     47 #define PHFRINFCTOPAZMAP_FILEALIASES  "$Aliases:  $"
     48 /*@}*/
     49 /*!
     50 * \name Topaz Mapping - Helper data structures and macros
     51 *
     52 */
     53 /*@{*/
     54 
     55 /********************************** Start of data structures *********************************/
     56 #ifdef FRINFC_READONLY_NDEF
     57 
     58     #define DYN_CC_BLOCK_NUMBER                                     (0x01U)
     59     #define DYN_STATIC_LOCK_BLOCK_NUM                               (0x0EU)
     60 
     61     #define DYN_STATIC_LOCK0_BYTE_NUM                               (0x00U)
     62     #define DYN_STATIC_LOCK0_BYTE_VALUE                             (0xFFU)
     63 
     64     #define DYN_STATIC_LOCK1_BYTE_NUM                               (0x01U)
     65     #define DYN_STATIC_LOCK1_BYTE_VALUE                             (0x7FU)
     66 
     67     #define DYN_CC_RWA_BYTE_NUMBER                                  (0x03U)
     68     #define DYN_CC_READ_ONLY_VALUE                                  (0x0FU)
     69 
     70 #endif /* #ifdef FRINFC_READONLY_NDEF */
     71 
     72 /*!
     73 * \brief \copydoc page_ovr enum for the topaz sequence of execution.
     74 */
     75 typedef enum phFriNfc_Tpz_ParseSeq
     76 {
     77     LOCK_T_TLV,
     78     LOCK_L_TLV,
     79     LOCK_V_TLV,
     80     MEM_T_TLV,
     81     MEM_L_TLV,
     82     MEM_V_TLV,
     83     NDEF_T_TLV,
     84     NDEF_L_TLV,
     85     NDEF_V_TLV
     86 }phFriNfc_Tpz_ParseSeq_t;
     87 
     88 typedef enum phFriNfc_Tpz_WrSeq
     89 {
     90     WR_NDEF_T_TLV,
     91     WR_NMN_0,
     92     WR_LEN_1_0,
     93     WR_LEN_2_0,
     94     WR_LEN_3_0,
     95     WR_DATA,
     96     WR_DATA_READ_REQD,
     97     WR_LEN_1_VALUE,
     98     WR_LEN_2_VALUE,
     99     WR_LEN_3_VALUE,
    100     WR_NMN_E1
    101 }phFriNfc_Tpz_WrSeq_t;
    102 
    103 #ifdef FRINFC_READONLY_NDEF
    104 
    105 typedef enum phFriNfc_Tpz_RO_Seq
    106 {
    107     WR_READONLY_CC,
    108     RD_LOCK_BYTES,
    109     WR_LOCK_BYTES,
    110     RD_STATIC_LOCK_BYTE0,
    111     WR_STATIC_LOCK_BYTE0,
    112     WR_STATIC_LOCK_BYTE1
    113 }phFriNfc_Tpz_RO_Seq_t;
    114 
    115 #endif /* #ifdef FRINFC_READONLY_NDEF  */
    116 
    117 /********************************** End of data structures *********************************/
    118 
    119 /********************************** Start of Macros *********************************/
    120 /* New state for TOPAZ dynamic  card*/
    121 #define PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF            (0x10U)
    122 
    123 #ifdef FRINFC_READONLY_NDEF
    124     #define PH_FRINFC_TOPAZ_STATE_READ_ONLY             (0x11U)
    125 #endif /* #ifdef FRINFC_READONLY_NDEF */
    126 
    127 #define NIBBLE_SIZE                                     (0x04U)
    128 /* Byte shifting for the topaz */
    129 #define TOPAZ_BYTE_SHIFT                                (0x08U)
    130 /* Lock and memory control TLV length. Always 3 bytes */
    131 #define TOPAZ_MEM_LOCK_TLV_LENGTH                       (0x03U)
    132 /* UID byte length */
    133 #define TOPAZ_UID_BYTES_LENGTH                          (0x08U)
    134 
    135 /* Number os static lock and reserved bytes */
    136 #define TOPAZ_STATIC_LOCK_RES_BYTES                     (0x18U)
    137 /* Number of static lock and reserved memory. This value is 3 (because
    138     block number D, E and F are lock and reserved blocks */
    139 #define TOPAZ_STATIC_LOCK_BLOCK_AREAS                   (0x03U)
    140 /* First lock or reserved block in the static area of the card */
    141 #define TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO                (0x0DU)
    142 /* First lock or reserved byte number in the static area of the card */
    143 #define TOPAZ_STATIC_LOCK_RES_START                     (0x68U)
    144 /* End lock or reserved byte number in the static area of the card */
    145 #define TOPAZ_STATIC_LOCK_RES_END                       (0x78U)
    146 
    147 /* CC byte length */
    148 #define TOPAZ_CC_BYTES_LENGTH                           (0x04U)
    149 
    150 /* In TOPAZ card each block has 8 bytes */
    151 #define TOPAZ_BYTES_PER_BLOCK                           (0x08U)
    152 /* Each byte has 8 bites */
    153 #define TOPAZ_BYTE_SIZE_IN_BITS                         (0x08U)
    154 
    155 /* This mask is to get the least significant NIBBLE from a BYTE */
    156 #define TOPAZ_NIBBLE_MASK                               (0x0FU)
    157 /* This is used to mask the least significant BYTE from a TWO BYTE value */
    158 #define TOPAZ_BYTE_LENGTH_MASK                          (0x00FFU)
    159 
    160 /* Total segments in TOPAZ 512 bytes card. Each segment = 128 bytes,
    161 so there are 4 segements in the card */
    162 #define TOPAZ_TOTAL_SEG_TO_READ                         (0x04U)
    163 /* SPEC version value shall be 0x10 as per the TYPE 1 specification */
    164 #define TOPAZ_SPEC_VERSION                              (0x10U)
    165 
    166 /* Response length for READ SEGMENT command is 128 bytes */
    167 #define TOPAZ_SEGMENT_READ_LENGTH                       (0x80U)
    168 /* Response length for WRITE-1E command is 1 byte */
    169 #define TOPAZ_WRITE_1_RESPONSE                          (0x01U)
    170 /* Response length for WRITE-8E command is 8 bytes */
    171 #define TOPAZ_WRITE_8_RESPONSE                          (0x08U)
    172 /* Response length for READ-8 command is 8 bytes */
    173 #define TOPAZ_READ_8_RESPONSE                           (0x08U)
    174 
    175 /* Data bytes that can be written for the WRITE-8E command is 8 bytes */
    176 #define TOPAZ_WRITE_8_DATA_LENGTH                       (0x08U)
    177 
    178 /* Get the exact byte address of the card from the segment number
    179     and the parse index of each segment */
    180 #define TOPAZ_BYTE_ADR_FROM_SEG(seg, parse_index) \
    181     (((seg) * TOPAZ_SEGMENT_READ_LENGTH) + (parse_index))
    182 
    183 /* Get the segment number of the card from the byte address */
    184 #define TOPAZ_SEG_FROM_BYTE_ADR(byte_addr) \
    185     ((byte_addr) / TOPAZ_SEGMENT_READ_LENGTH)
    186 /* Get the block number of the card from the byte address */
    187 #define TOPAZ_BLK_FROM_BYTE_ADR(byte_addr) \
    188     ((byte_addr) / TOPAZ_BYTES_PER_BLOCK)
    189 /* Get the block offset of a block number of the card from the byte address */
    190 #define TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR(byte_addr) \
    191     ((byte_addr) % TOPAZ_BYTES_PER_BLOCK)
    192 /* Get the exact byte address of the card from the block number
    193     and the byte offset of the block number */
    194 #define TOPAZ_BYTE_ADR_FROM_BLK(block_no, byte_offset) \
    195     (((block_no) * TOPAZ_BYTES_PER_BLOCK) + (byte_offset))
    196 /* To increment the block number and if block number overlaps with the
    197     static lock and reserved blocks, then skip the blocks */
    198 #define TOPAZ_INCREMENT_SKIP_STATIC_BLOCK(block_no) \
    199     ((((block_no) + 1) == TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO) ? \
    200     (((block_no) + 1) + TOPAZ_STATIC_LOCK_BLOCK_AREAS) : \
    201     ((block_no) + 1))
    202 
    203 #ifdef FRINFC_READONLY_NDEF
    204 
    205 #define TOPAZ_CONVERT_BITS_TO_BYTES(bits_to_bytes) \
    206             (((bits_to_bytes % TOPAZ_BYTE_SIZE_IN_BITS) > 0) ? \
    207             ((bits_to_bytes / TOPAZ_BYTE_SIZE_IN_BITS) + 1) : \
    208             (bits_to_bytes / TOPAZ_BYTE_SIZE_IN_BITS))
    209 
    210 #endif /* #ifdef FRINFC_READONLY_NDEF */
    211 /********************************** End of Macros *********************************/
    212 
    213 /*@}*/
    214 
    215 
    216 /*!
    217 * \name Topaz Mapping - Helper Functions
    218 *
    219 */
    220 /*@{*/
    221 
    222 /*!
    223 * \brief \copydoc page_ovr Helper function for Topaz. This function shall read defined
    224 * bytes from the card.
    225 */
    226 static
    227 NFCSTATUS
    228 phFriNfc_Tpz_H_NxpRead (
    229     phFriNfc_NdefMap_t          *psNdefMap);
    230 
    231 /*!
    232 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
    233 * received read id command.
    234 */
    235 static
    236 NFCSTATUS
    237 phFriNfc_Tpz_H_ChkReadID (
    238     phFriNfc_NdefMap_t          *psNdefMap);
    239 
    240 
    241 /*!
    242 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
    243 * read response.
    244 */
    245 static
    246 NFCSTATUS
    247 phFriNfc_Tpz_H_ProReadResp (
    248     phFriNfc_NdefMap_t  *psNdefMap);
    249 
    250 /*!
    251 * \brief \copydoc page_ovr Helper function for Topaz. This function calls the
    252 * completion routine
    253 */
    254 static
    255 void
    256 phFriNfc_Tpz_H_Complete (
    257     phFriNfc_NdefMap_t  *NdefMap,
    258     NFCSTATUS           Status);
    259 
    260 
    261 /*!
    262 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
    263 * the lock bits and set a card state
    264 */
    265 static
    266 NFCSTATUS
    267 phFriNfc_Tpz_H_ChkLockBits (
    268     phFriNfc_NdefMap_t  *psNdefMap);
    269 
    270 /*!
    271 * \brief \copydoc page_ovr Helper function for Topaz. This function writes defined
    272 * bytes into the card
    273 */
    274 static
    275 NFCSTATUS
    276 phFriNfc_Tpz_H_NxpWrite (
    277     phFriNfc_NdefMap_t          *psNdefMap,
    278     uint8_t                     *p_write_data,
    279     uint8_t                     wr_data_len);
    280 
    281 
    282 /*!
    283 * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
    284 * till the NDEF TLV is found. Also, it returns error if it founds wrong TLVs.
    285 */
    286 static
    287 NFCSTATUS
    288 phFriNfc_Tpz_H_ParseTLVs (
    289     phFriNfc_NdefMap_t          *psNdefMap);
    290 
    291 /*!
    292  * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
    293  * till the TYPE of the LOCK control TLV is found.
    294  * Also, it returns error if it founds wrong TYPE.
    295  */
    296 static
    297 NFCSTATUS
    298 phFriNfc_Tpz_H_ParseLockTLVType (
    299     phFriNfc_NdefMap_t          *psNdefMap,
    300     uint8_t                     *p_parse_data,
    301     uint16_t                    *p_parse_index,
    302     uint16_t                    total_len_to_parse,
    303     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute);
    304 
    305 /*!
    306  * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
    307  * till the TYPE of the MEMORY control TLV is found.
    308  * Also, it returns error if it founds wrong TYPE.
    309  */
    310 static
    311 NFCSTATUS
    312 phFriNfc_Tpz_H_ParseMemTLVType (
    313     phFriNfc_NdefMap_t          *psNdefMap,
    314     uint8_t                     *p_parse_data,
    315     uint16_t                    *p_parse_index,
    316     uint16_t                    total_len_to_parse,
    317     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute);
    318 
    319 /*!
    320  * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
    321  * till the TYPE of the NDEF control TLV is found.
    322  * Also, it returns error if it founds wrong TYPE.
    323  */
    324 static
    325 NFCSTATUS
    326 phFriNfc_Tpz_H_ParseNdefTLVType (
    327     phFriNfc_NdefMap_t          *psNdefMap,
    328     uint8_t                     *p_parse_data,
    329     uint16_t                    *p_parse_index,
    330     uint16_t                    total_len_to_parse,
    331     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute);
    332 
    333 /*!
    334  * \brief \copydoc page_ovr Helper function for Topaz. This function gets the lock bytes
    335  * information.
    336  */
    337 static
    338 NFCSTATUS
    339 phFriNfc_Tpz_H_GetLockBytesInfo (
    340     phFriNfc_NdefMap_t          *psNdefMap,
    341     uint8_t                     *p_lock_info);
    342 
    343 /*!
    344  * \brief \copydoc page_ovr Helper function for Topaz. This function gets the reserved bytes
    345  * information.
    346  */
    347 static
    348 NFCSTATUS
    349 phFriNfc_Tpz_H_GetMemBytesInfo (
    350     phFriNfc_NdefMap_t          *psNdefMap,
    351     uint8_t                     *p_mem_info);
    352 
    353 /*!
    354  * \brief \copydoc page_ovr Helper function for Topaz. This function copies and checks the CC bytes.
    355  * This function checks for the lock bytes value and card state also.
    356  */
    357 static
    358 NFCSTATUS
    359 phFriNfc_Tpz_H_CheckCCBytes (
    360     phFriNfc_NdefMap_t          *psNdefMap);
    361 
    362 /*!
    363  * \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC bytes.
    364  * If .
    365  */
    366 static
    367 NFCSTATUS
    368 phFriNfc_Tpz_H_CheckCCBytesForWrite (
    369     phFriNfc_NdefMap_t          *psNdefMap);
    370 
    371 
    372 /*!
    373  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the read bytes.
    374  * This function also checks for the lock and reserved bytes and skips the bytes before copying it
    375  * in the buffer.
    376  */
    377 static
    378 NFCSTATUS
    379 phFriNfc_Tpz_H_CopyReadData (
    380     phFriNfc_NdefMap_t          *psNdefMap);
    381 
    382 /*!
    383  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the stored read bytes.
    384  * This function is used only for the offset " PH_FRINFC_NDEFMAP_SEEK_CUR ".
    385  */
    386 static
    387 NFCSTATUS
    388 phFriNfc_Tpz_H_RemainingReadDataCopy (
    389     phFriNfc_NdefMap_t          *psNdefMap);
    390 
    391 /*!
    392  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the exact byte address
    393  * of the value field after the NDEF TYPE field
    394  */
    395 static
    396 uint16_t
    397 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
    398     phFriNfc_NdefMap_t          *psNdefMap);
    399 
    400 /*!
    401  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the exact byte address
    402  * of the value field after the NDEF TYPE field
    403  */
    404 static
    405 uint16_t
    406 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (
    407     phFriNfc_NdefMap_t          *psNdefMap,
    408     uint16_t                     size_to_write);
    409 
    410 /*!
    411  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the number of bytes to skip.
    412  * This function checks the input byte address and checks if any lock or reserved bytes matches with the
    413  * given address. if yes, then it will return number od bytes to skip.
    414  */
    415 static
    416 uint16_t
    417 phFriNfc_Tpz_H_GetSkipSize (
    418     phFriNfc_NdefMap_t          *psNdefMap,
    419     uint16_t                    byte_adr_card);
    420 
    421 /*!
    422  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the actual data that can
    423  * be read and written in the card.
    424  * This function checks for the lock and reserved bytes and subtracts the remaining size to give the
    425  * actual size.
    426  */
    427 static
    428 NFCSTATUS
    429 phFriNfc_Tpz_H_ActualCardSize (
    430     phFriNfc_NdefMap_t          *psNdefMap);
    431 
    432 /*!
    433  * \brief \copydoc page_ovr Helper function for Topaz. This function processes the response for
    434  * the write data
    435  */
    436 static
    437 NFCSTATUS
    438 phFriNfc_Tpz_H_ProWrResp (
    439     phFriNfc_NdefMap_t          *psNdefMap);
    440 
    441 /*!
    442  * \brief \copydoc page_ovr Helper function for Topaz. This function processes the read 8 commands,
    443  * that is required for writing the data
    444  */
    445 static
    446 NFCSTATUS
    447 phFriNfc_Tpz_H_ProRdForWrResp (
    448     phFriNfc_NdefMap_t          *psNdefMap);
    449 
    450 /*!
    451  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the user data to the
    452  * write buffer and writes the data to the card. If the lock or memory blocks are in between the
    453  * write data, then read the current block
    454  */
    455 static
    456 NFCSTATUS
    457 phFriNfc_Tpz_H_CopySendWrData (
    458     phFriNfc_NdefMap_t          *psNdefMap);
    459 
    460 /*!
    461  * \brief \copydoc page_ovr Helper function for Topaz. This function compares the input block
    462  * number with lock bytes block number and returns the p_skip_size which is the lock bytes
    463  * size
    464  */
    465 static
    466 uint16_t
    467 phFriNfc_Tpz_H_CompareLockBlocks (
    468     phFriNfc_NdefMap_t          *psNdefMap,
    469     uint8_t                     block_no,
    470     uint16_t                    *p_skip_size);
    471 
    472 /*!
    473  * \brief \copydoc page_ovr Helper function for Topaz. This function compares the input block
    474  * number with reserved bytes block number and returns the p_skip_size which is the reserved bytes
    475  * size
    476  */
    477 static
    478 uint16_t
    479 phFriNfc_Tpz_H_CompareMemBlocks (
    480     phFriNfc_NdefMap_t          *psNdefMap,
    481     uint8_t                     block_no,
    482     uint16_t                    *p_skip_size);
    483 
    484 /*!
    485  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the read data and update
    486  * the user bytes by skipping lock or memory control areas. Also, used while updating the value field
    487  * skips the initial bytes and to start at the proper value field byte offset of the block
    488  */
    489 static
    490 NFCSTATUS
    491 phFriNfc_Tpz_H_CopyReadDataAndWrite (
    492     phFriNfc_NdefMap_t          *psNdefMap);
    493 
    494 
    495 /*!
    496  * \brief \copydoc page_ovr Helper function for Topaz. This function reads the required block for writing,
    497  * as some of the bytes shall not be overwritten
    498  */
    499 static
    500 NFCSTATUS
    501 phFriNfc_Tpz_H_RdForWrite (
    502     phFriNfc_NdefMap_t          *psNdefMap);
    503 
    504 /*!
    505  * \brief \copydoc page_ovr Helper function for Topaz. This function reads the length block for writing,
    506  * updates the length bytes with 0
    507  */
    508 static
    509 NFCSTATUS
    510 phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (
    511     phFriNfc_NdefMap_t          *psNdefMap);
    512 
    513 /*!
    514  * \brief \copydoc page_ovr Helper function for Topaz. This function reads the length block for writing,
    515  * updates the length bytes with exact bytes that was written in the card
    516  */
    517 static
    518 NFCSTATUS
    519 phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (
    520     phFriNfc_NdefMap_t          *psNdefMap);
    521 
    522 /*!
    523  * \brief \copydoc page_ovr Helper function for Topaz. This function writes the NDEF TYPE of the
    524  * NDEF TLV to the specific byte address. This function is called only if the previous write is
    525  * failed or there is no NDEF TLV with correct CC bytes
    526  */
    527 static
    528 NFCSTATUS
    529 phFriNfc_Tpz_H_UpdateNdefTypeField (
    530     phFriNfc_NdefMap_t          *psNdefMap);
    531 
    532 #ifdef FRINFC_READONLY_NDEF
    533 
    534 static
    535 NFCSTATUS
    536 phFriNfc_Tpz_H_ProcessReadOnly (
    537     phFriNfc_NdefMap_t          *psNdefMap);
    538 
    539 static
    540 NFCSTATUS
    541 phFriNfc_Tpz_H_UpdateAndWriteLockBits (
    542     phFriNfc_NdefMap_t          *psNdefMap);
    543 
    544 
    545 #endif /* #ifdef FRINFC_READONLY_NDEF */
    546 
    547 
    548 /*!
    549 * \brief Check whether a particular Remote Device is NDEF compliant.
    550 *
    551 * The function checks whether the peer device is NDEF compliant.
    552 *
    553 * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t
    554 *                    structure describing the component context.
    555 *
    556 * \retval  NFCSTATUS_PENDING   The action has been successfully triggered.
    557 * \retval  Others              An error has occurred.
    558 *
    559 */
    560 NFCSTATUS  phFriNfc_TopazDynamicMap_ChkNdef( phFriNfc_NdefMap_t     *NdefMap)
    561 {
    562     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    563         NFCSTATUS_INVALID_PARAMETER);
    564     if ( NdefMap != NULL)
    565     {
    566         /* Update the previous operation */
    567         NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
    568         /* Update the CR index to know from which operation completion
    569         routine has to be called */
    570         NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
    571         NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
    572         NdefMap->TopazContainer.CurrentSeg = 0;
    573         NdefMap->TopazContainer.NdefTLVByteAddress = 0;
    574         NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
    575 
    576         NdefMap->TopazContainer.CurrentBlock = 0;
    577         NdefMap->TopazContainer.WriteSeq = 0;
    578         NdefMap->TopazContainer.ExpectedSeq = 0;
    579 
    580         (void)memset ((void *)&(NdefMap->LockTlv), 0,
    581                         sizeof (phFriNfc_LockCntrlTLVCont_t));
    582 
    583         (void)memset ((void *)&(NdefMap->MemTlv), 0,
    584                     sizeof (phFriNfc_ResMemCntrlTLVCont_t));
    585 
    586         /* Set card state */
    587         NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_DYNAMIC_CARD;
    588 
    589         /* Change the state to Read */
    590         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
    591 
    592         NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_DYNAMIC_INIT_CHK_NDEF;
    593 #ifdef TOPAZ_RAW_SUPPORT
    594 
    595         *NdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
    596 
    597 #else
    598 
    599 #ifdef PH_HAL4_ENABLE
    600         NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
    601 #else
    602         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
    603 #endif
    604 
    605 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
    606 
    607         Result = phFriNfc_Tpz_H_NxpRead(NdefMap);
    608 
    609       }
    610     return Result;
    611 }
    612 
    613 
    614 /*!
    615 * \brief Initiates Reading of NDEF information from the Remote Device.
    616 *
    617 * The function initiates the reading of NDEF information from a Remote Device.
    618 * It performs a reset of the state and starts the action (state machine).
    619 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
    620 * has been triggered.
    621 */
    622 
    623 NFCSTATUS phFriNfc_TopazDynamicMap_RdNdef( phFriNfc_NdefMap_t           *NdefMap,
    624                                         uint8_t                         *PacketData,
    625                                         uint32_t                        *PacketDataLength,
    626                                         uint8_t                         Offset)
    627 {
    628     NFCSTATUS               Result =    NFCSTATUS_SUCCESS;
    629 
    630     /* Copy user buffer to the context */
    631     NdefMap->ApduBuffer = PacketData;
    632     /* Copy user length to the context */
    633     NdefMap->ApduBufferSize = *PacketDataLength;
    634     /* Update the user memory size to a context variable */
    635     NdefMap->NumOfBytesRead = PacketDataLength;
    636     /* Number of bytes read from the card is zero.
    637     This variable returns the number of bytes read
    638     from the card. */
    639     *NdefMap->NumOfBytesRead = 0;
    640     /* Index to know the length read */
    641     NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;
    642     /* Store the offset in the context */
    643     NdefMap->Offset = Offset;
    644     /* Update the CR index to know from which operation completion
    645     routine has to be called */
    646     NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
    647     NdefMap->TopazContainer.SkipLockBlkFlag = 0;
    648 
    649     NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
    650     if ((PH_FRINFC_NDEFMAP_SEEK_CUR == Offset) &&
    651         (TRUE == NdefMap->TopazContainer.ReadWriteCompleteFlag))
    652     {
    653         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    654                             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
    655     }
    656     else if ((PH_NDEFMAP_CARD_STATE_INITIALIZED ==
    657             NdefMap->CardState) ||
    658             (0 == NdefMap->TopazContainer.ActualNDEFMsgSize))
    659     {
    660         /* Length field of NDEF TLV is 0, so read cannot proceed */
    661         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    662                             NFCSTATUS_READ_FAILED);
    663     }
    664     else if ((PH_FRINFC_NDEFMAP_SEEK_BEGIN == Offset) ||
    665         (PH_FRINFC_NDEFMAP_READ_OPE != NdefMap->PrevOperation))
    666     {
    667         /* If previous operation is not read then the read shall
    668         start from BEGIN */
    669         NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
    670         /* Initialise byte number */
    671         NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
    672 
    673         NdefMap->TopazContainer.RemainingReadSize = 0;
    674         NdefMap->TopazContainer.ReadBufferSize = 0;
    675         NdefMap->TopazContainer.ReadWriteCompleteFlag = FALSE;
    676         NdefMap->TopazContainer.CurrentBlock = 0;
    677         NdefMap->TopazContainer.WriteSeq = 0;
    678 
    679         NdefMap->TopazContainer.CurrentSeg = (uint8_t)TOPAZ_SEG_FROM_BYTE_ADR (
    680                         phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (NdefMap));
    681 
    682          /* Change the state to Read ID */
    683         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID;
    684         /*Change the state to Read ID*/
    685         NdefMap->TopazContainer.ReadWriteCompleteFlag = 0;
    686 #ifdef TOPAZ_RAW_SUPPORT
    687 
    688         NdefMap->SendRecvBuf[0] = PH_FRINFC_TOPAZ_CMD_READID;
    689 
    690 #else
    691 
    692 #ifdef PH_HAL4_ENABLE
    693         NdefMap->Cmd.JewelCmd = phHal_eJewel_RID;
    694 #else
    695         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid;
    696 #endif
    697 
    698 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
    699         Result =  phFriNfc_Tpz_H_NxpRead(NdefMap);
    700 
    701     }
    702     else
    703     {
    704          /* Change the state to Read */
    705           NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
    706           Result = phFriNfc_Tpz_H_RemainingReadDataCopy (NdefMap);
    707     }
    708 
    709 
    710     return Result;
    711 }
    712 
    713 #ifdef FRINFC_READONLY_NDEF
    714 
    715 NFCSTATUS
    716 phFriNfc_TopazDynamicMap_ConvertToReadOnly (
    717     phFriNfc_NdefMap_t     *psNdefMap)
    718 {
    719     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    720     uint8_t                     cc_read_only_byte = 0x0FU;
    721 
    722     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_READ_ONLY;
    723 
    724     psNdefMap->TopazContainer.read_only_seq = 0;
    725 
    726 
    727 
    728     psNdefMap->TopazContainer.CurrentBlock = 0x01U;
    729     psNdefMap->TopazContainer.ByteNumber = 0x03U;
    730 
    731 #ifdef TOPAZ_RAW_SUPPORT
    732     *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
    733 #else
    734     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
    735 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
    736 
    737     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &cc_read_only_byte,
    738                                     1);
    739 
    740     if (NFCSTATUS_PENDING == result)
    741     {
    742         psNdefMap->TopazContainer.read_only_seq = (uint8_t)WR_READONLY_CC;
    743     }
    744 
    745 
    746     return result;
    747 }
    748 
    749 #endif /* #ifdef FRINFC_READONLY_NDEF */
    750 
    751 /*!
    752 * \brief Initiates Writing of NDEF information to the Remote Device.
    753 *
    754 * The function initiates the writing of NDEF information to a Remote Device.
    755 * It performs a reset of the state and starts the action (state machine).
    756 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
    757 * has been triggered.
    758 */
    759 NFCSTATUS phFriNfc_TopazDynamicMap_WrNdef( phFriNfc_NdefMap_t     *NdefMap,
    760                                    uint8_t                 *PacketData,
    761                                    uint32_t                *PacketDataLength,
    762                                    uint8_t                 Offset)
    763 {
    764     NFCSTATUS                   Result = NFCSTATUS_SUCCESS;
    765 
    766     /* Copy user buffer to the context */
    767     NdefMap->ApduBuffer = PacketData;
    768     /* Copy user length to the context */
    769     NdefMap->ApduBufferSize = *PacketDataLength;
    770     /* Index to know the length written */
    771     NdefMap->ApduBuffIndex = 0;
    772     /* Update the user memory size to a context variable */
    773     NdefMap->WrNdefPacketLength = PacketDataLength;
    774     /* Number of bytes written to the card is zero.
    775     This variable returns the number of bytes written
    776     to the card. */
    777     *NdefMap->WrNdefPacketLength = 0;
    778     /* Update the CR index to know from which operation completion
    779     routine has to be called */
    780     NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
    781     /* Store the offset in the context */
    782     NdefMap->Offset = Offset;
    783 
    784     /* Update the previous operation to write operation */
    785     NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
    786 
    787     if (PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState)
    788     {
    789         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    790                             NFCSTATUS_WRITE_FAILED);
    791     }
    792     else if ((PH_FRINFC_NDEFMAP_SEEK_CUR == Offset) &&
    793         (TRUE == NdefMap->TopazContainer.ReadWriteCompleteFlag))
    794     {
    795         /* Offset = Current, but the read has reached the End of Card */
    796         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    797                             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
    798     }
    799     else if (0 == NdefMap->TopazContainer.NdefTLVByteAddress)
    800     {
    801         /* No NDEF TLV found in the card, so write not possible */
    802         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    803                             NFCSTATUS_NO_NDEF_SUPPORT);
    804     }
    805     else if ((PH_FRINFC_NDEFMAP_SEEK_BEGIN == Offset) ||
    806         (PH_FRINFC_NDEFMAP_WRITE_OPE != NdefMap->PrevOperation))
    807     {
    808         NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
    809         /* Initialise byte number */
    810         NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
    811         /* State has to be changed */
    812         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
    813         NdefMap->TopazContainer.ReadWriteCompleteFlag = FALSE;
    814 
    815         NdefMap->TopazContainer.CurrentSeg = 0;
    816         NdefMap->TopazContainer.CurrentBlock = 1;
    817         NdefMap->TopazContainer.WriteSeq = 0;
    818 
    819 #ifdef TOPAZ_RAW_SUPPORT
    820 
    821         *NdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
    822 
    823 #else
    824 
    825         /* Topaz command = Jewel Nxp Read */
    826 #ifdef PH_HAL4_ENABLE
    827         NdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
    828 #else
    829         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
    830 #endif
    831 
    832         NdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
    833 
    834 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
    835         /* Call read segment */
    836         Result = phFriNfc_Tpz_H_NxpRead (NdefMap);
    837     }
    838     else
    839     {
    840 #if 0
    841         /* This part is to handle the Current offset,
    842         Current offset is not yet validated */
    843         Result = phFriNfc_Tpz_H_NxpWrite(NdefMap);
    844 #endif /* #if 0 */
    845     }
    846 
    847     return Result;
    848 }
    849 
    850 
    851 /*!
    852 * \brief Completion Routine, Processing function, needed to avoid long blocking.
    853 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
    854 *       Routine in order to be able to notify the component that an I/O has finished and data are
    855 *       ready to be processed.
    856 *
    857 */
    858 
    859 void phFriNfc_TopazDynamicMap_Process( void       *Context,
    860                                NFCSTATUS   Status)
    861 {
    862 
    863     phFriNfc_NdefMap_t      *NdefMap;
    864 
    865     NdefMap = (phFriNfc_NdefMap_t *)Context;
    866 
    867 
    868     if((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
    869     {
    870         switch(NdefMap->State)
    871         {
    872             case PH_FRINFC_TOPAZ_STATE_READ:
    873             {
    874                 Status = phFriNfc_Tpz_H_ProReadResp (NdefMap);
    875                 break;
    876             }
    877 
    878             case PH_FRINFC_TOPAZ_STATE_WRITE:
    879             {
    880                 Status =  phFriNfc_Tpz_H_ProWrResp (NdefMap);
    881                 break;
    882             }
    883 
    884             case PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF:
    885             {
    886                 Status =  phFriNfc_Tpz_H_ProRdForWrResp (NdefMap);
    887                 break;
    888             }
    889 
    890             case PH_FRINFC_TOPAZ_STATE_READID:
    891             {
    892                 Status = phFriNfc_Tpz_H_ChkReadID(NdefMap);
    893                 break;
    894             }
    895 
    896 #ifdef FRINFC_READONLY_NDEF
    897             case PH_FRINFC_TOPAZ_STATE_READ_ONLY:
    898             {
    899                 Status = phFriNfc_Tpz_H_ProcessReadOnly (NdefMap);
    900                 break;
    901             }
    902 #endif /* #ifdef FRINFC_READONLY_NDEF */
    903 
    904             default:
    905             {
    906                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    907                                     NFCSTATUS_INVALID_DEVICE_REQUEST);
    908                 break;
    909             }
    910         }
    911     }
    912 
    913     /* Call for the Completion Routine*/
    914     if(Status != NFCSTATUS_PENDING)
    915     {
    916         phFriNfc_Tpz_H_Complete(NdefMap, Status);
    917     }
    918 }
    919 
    920 #ifdef FRINFC_READONLY_NDEF
    921 
    922 static
    923 NFCSTATUS
    924 phFriNfc_Tpz_H_UpdateAndWriteLockBits (
    925     phFriNfc_NdefMap_t          *psNdefMap)
    926 {
    927     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
    928     phFriNfc_TopazCont_t            *ps_tpz_info = NULL;
    929     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
    930     uint8_t                         remaining_lock_bits = 0;
    931     uint8_t                         byte_index = 0;
    932     uint8_t                         lock_bytes_value[TOPAZ_BYTES_PER_BLOCK] = {0};
    933     uint8_t                         lock_byte_index = 0;
    934     uint8_t                         no_of_bits_left_in_block = 0;
    935 
    936     ps_tpz_info = &(psNdefMap->TopazContainer);
    937     ps_locktlv_info = &(psNdefMap->LockTlv);
    938 
    939     (void)memcpy ((void *)lock_bytes_value, (void *)psNdefMap->SendRecvBuf,
    940                     TOPAZ_BYTES_PER_BLOCK);
    941 
    942     if (ps_tpz_info->CurrentBlock == ps_locktlv_info->BlkNum)
    943     {
    944         /* Get the lock bits that has to locked */
    945         remaining_lock_bits = ps_locktlv_info->LockTlvBuff[1];
    946         byte_index = (uint8_t)ps_locktlv_info->ByteNum;
    947     }
    948     else
    949     {
    950         /* This condition applies only for the lock bits not ending with
    951         " ps_locktlv_info->BlkNum ".
    952         Calculate the remaining lock bits */
    953         remaining_lock_bits = (uint8_t)(ps_locktlv_info->LockTlvBuff[1] -
    954                     ps_tpz_info->lock_bytes_written);
    955     }
    956 
    957     no_of_bits_left_in_block = (uint8_t)((TOPAZ_BYTES_PER_BLOCK - byte_index) *
    958                                 TOPAZ_BYTE_SIZE_IN_BITS);
    959 
    960     if (no_of_bits_left_in_block >= remaining_lock_bits)
    961     {
    962         /* Entire lock bits can be written */
    963         uint8_t                 mod_value = 0;
    964 
    965         mod_value = (uint8_t)(remaining_lock_bits % TOPAZ_BYTES_PER_BLOCK);
    966 
    967         if (mod_value)
    968         {
    969             /* The lock bits ends in between of a byte */
    970             /* lock bits to write is greater than 8 bits */
    971             if (mod_value > TOPAZ_BYTE_SIZE_IN_BITS)
    972             {
    973                 while (lock_byte_index <
    974                     (TOPAZ_CONVERT_BITS_TO_BYTES(remaining_lock_bits) - 1))
    975                 {
    976                     /* Set 1b to all bits left in the block */
    977                     lock_bytes_value[byte_index] = 0xFF;
    978                     lock_byte_index = (uint8_t)(lock_byte_index + 1);
    979                     byte_index = (uint8_t)(byte_index + 1);
    980                 }
    981                 /* Last byte of the lock bits shall be filled partially,
    982                     Set only the remaining lock bits and dont change
    983                     the other bit value */
    984                 lock_bytes_value[byte_index] = 0;
    985                 lock_bytes_value[byte_index] = (uint8_t)
    986                         SET_BITS8 (lock_bytes_value[byte_index], 0,
    987                                     mod_value, 1);
    988             }
    989             else
    990             {
    991                 /* lock bits to write is less than 8 bits, so
    992                     there is only one byte to write.
    993                     Set only the remaining lock bits and dont change
    994                     the other bit value */
    995                 lock_bytes_value[0] = (uint8_t)
    996                         SET_BITS8 (lock_bytes_value[0], 0,
    997                                     mod_value, 1);
    998             }
    999         } /* if (mod_value) */
   1000         else
   1001         {
   1002             /* The lock bits exactly ends at a byte
   1003             MOD operation is 00, that means entire byte value shall be 0xFF, means
   1004             every bit shall be to 1 */
   1005 
   1006             while (lock_byte_index < TOPAZ_CONVERT_BITS_TO_BYTES(remaining_lock_bits))
   1007             {
   1008                 /* Set 1b to all bits left in the block */
   1009                 lock_bytes_value[byte_index] = 0xFF;
   1010                 lock_byte_index = (uint8_t)(lock_byte_index + 1);
   1011                 byte_index = (uint8_t)(byte_index + 1);
   1012             }
   1013         } /* else of if (mod_value) */
   1014         ps_tpz_info->lock_bytes_written = remaining_lock_bits;
   1015     }
   1016     else /* if (no_of_bits_left_in_block >= remaining_lock_bits) */
   1017     {
   1018         /* Partial lock bits can be written. use next read to write
   1019             the remaining lock bits  */
   1020         while (lock_byte_index <  (no_of_bits_left_in_block /
   1021                             TOPAZ_BYTES_PER_BLOCK))
   1022         {
   1023             /* Set 1b to all bits left in the block */
   1024             lock_bytes_value[byte_index] = 0xFF;
   1025             lock_byte_index = (uint8_t)(lock_byte_index + 1);
   1026             byte_index = (uint8_t)(byte_index + 1);
   1027         }
   1028         ps_tpz_info->lock_bytes_written = (uint8_t)(no_of_bits_left_in_block /
   1029                             TOPAZ_BYTES_PER_BLOCK);
   1030     } /* else of if (no_of_bits_left_in_block >= remaining_lock_bits) */
   1031 
   1032 #ifdef TOPAZ_RAW_SUPPORT
   1033     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
   1034 #else
   1035     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
   1036 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1037 
   1038     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, lock_bytes_value,
   1039                                     sizeof (lock_bytes_value));
   1040     return result;
   1041 }
   1042 
   1043 static
   1044 NFCSTATUS
   1045 phFriNfc_Tpz_H_ProcessReadOnly (
   1046     phFriNfc_NdefMap_t          *psNdefMap)
   1047 {
   1048     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   1049     phFriNfc_Tpz_RO_Seq_t               e_readonly_seq = RD_LOCK_BYTES;
   1050     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   1051     phFriNfc_LockCntrlTLVCont_t         *ps_locktlv_info = NULL;
   1052     static uint8_t                      static_lock_bytes[2] = {0};
   1053 
   1054     ps_tpz_info = &(psNdefMap->TopazContainer);
   1055     ps_locktlv_info = &(psNdefMap->LockTlv);
   1056     e_readonly_seq = (phFriNfc_Tpz_RO_Seq_t)psNdefMap->TopazContainer.read_only_seq;
   1057 
   1058     switch (e_readonly_seq)
   1059     {
   1060         case WR_READONLY_CC:
   1061         {
   1062             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
   1063             {
   1064                 psNdefMap->TopazContainer.CurrentBlock = (uint8_t)
   1065                                 psNdefMap->LockTlv.BlkNum;
   1066 
   1067                 e_readonly_seq = RD_LOCK_BYTES;
   1068 #ifdef TOPAZ_RAW_SUPPORT
   1069 
   1070                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
   1071 
   1072 #else
   1073 
   1074         /* Topaz command = Jewel Nxp Read */
   1075 #ifdef PH_HAL4_ENABLE
   1076                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
   1077 #else
   1078                 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
   1079 #endif
   1080 
   1081                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
   1082 
   1083 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1084                 /* Call read segment */
   1085                 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   1086             }
   1087             else
   1088             {
   1089                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1090                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1091             }
   1092             break;
   1093         }
   1094 
   1095         case RD_LOCK_BYTES:
   1096         {
   1097             if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
   1098             {
   1099                 result = phFriNfc_Tpz_H_UpdateAndWriteLockBits (psNdefMap);
   1100 
   1101                 if (NFCSTATUS_PENDING == result)
   1102                 {
   1103                     e_readonly_seq = WR_LOCK_BYTES;
   1104                 }
   1105             }
   1106             else
   1107             {
   1108                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1109                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1110             }
   1111             break;
   1112         }
   1113 
   1114         case WR_LOCK_BYTES:
   1115         {
   1116             if (TOPAZ_WRITE_8_RESPONSE == *psNdefMap->SendRecvLength)
   1117             {
   1118                 ps_tpz_info->CurrentBlock = (uint8_t)
   1119                                         (ps_tpz_info->CurrentBlock + 1);
   1120                 if (ps_locktlv_info->LockTlvBuff[1] -
   1121                     ps_tpz_info->lock_bytes_written)
   1122                 {
   1123 #ifdef TOPAZ_RAW_SUPPORT
   1124 
   1125                     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
   1126 
   1127 #else
   1128 
   1129                     /* Topaz command = Jewel Nxp Read */
   1130 #ifdef PH_HAL4_ENABLE
   1131                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
   1132 #else
   1133                     psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
   1134 #endif
   1135 
   1136                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
   1137 
   1138 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1139                     /* Call read segment */
   1140                     result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   1141                     e_readonly_seq = RD_LOCK_BYTES;
   1142                 }
   1143                 else
   1144                 {
   1145                     ps_tpz_info->CurrentBlock = (uint8_t)
   1146                                         DYN_STATIC_LOCK_BLOCK_NUM;
   1147                     ps_tpz_info->ByteNumber = (uint8_t)
   1148                                         DYN_STATIC_LOCK0_BYTE_NUM;
   1149 #ifdef TOPAZ_RAW_SUPPORT
   1150 
   1151                     *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_READ8;
   1152 
   1153 #else
   1154 
   1155                     /* Topaz command = Jewel Nxp Read */
   1156 #ifdef PH_HAL4_ENABLE
   1157                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
   1158 #else
   1159                     psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
   1160 #endif
   1161 
   1162                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
   1163 
   1164 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1165                     /* Call read segment */
   1166                     result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   1167                     e_readonly_seq = RD_STATIC_LOCK_BYTE0;
   1168 
   1169                 }
   1170             }
   1171             else
   1172             {
   1173                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1174                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1175             }
   1176             break;
   1177         }
   1178 
   1179         case RD_STATIC_LOCK_BYTE0:
   1180         {
   1181             if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
   1182             {
   1183                 uint8_t                 lock_byte_value = 0;
   1184 
   1185                 (void)memcpy ((void *)static_lock_bytes,
   1186                             (void *)(psNdefMap->SendRecvBuf +
   1187                                 ps_tpz_info->ByteNumber),
   1188                             sizeof (static_lock_bytes));
   1189 
   1190 
   1191                 lock_byte_value = (uint8_t)(static_lock_bytes[0] |
   1192                                     DYN_STATIC_LOCK0_BYTE_VALUE);
   1193 
   1194 #ifdef TOPAZ_RAW_SUPPORT
   1195                     *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
   1196 #else
   1197                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
   1198 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1199 
   1200                 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &lock_byte_value,
   1201                                                     1);
   1202 
   1203                     if (NFCSTATUS_PENDING == result)
   1204                     {
   1205                     e_readonly_seq = (uint8_t)WR_STATIC_LOCK_BYTE0;
   1206                     }
   1207                 }
   1208             else
   1209             {
   1210                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1211                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1212             }
   1213             break;
   1214         }
   1215 
   1216         case WR_STATIC_LOCK_BYTE0:
   1217         {
   1218             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
   1219             {
   1220                 uint8_t                 lock_byte_value =
   1221                                         (static_lock_bytes[1] |
   1222                                         DYN_STATIC_LOCK1_BYTE_VALUE);
   1223 
   1224                 ps_tpz_info->CurrentBlock = (uint8_t)
   1225                                     DYN_STATIC_LOCK_BLOCK_NUM;
   1226                 ps_tpz_info->ByteNumber = (uint8_t)
   1227                                     DYN_STATIC_LOCK1_BYTE_NUM;
   1228 #ifdef TOPAZ_RAW_SUPPORT
   1229                 *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
   1230 #else
   1231                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
   1232 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1233 
   1234                 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &lock_byte_value,
   1235                                                     1);
   1236 
   1237                 if (NFCSTATUS_PENDING == result)
   1238                 {
   1239                     e_readonly_seq = (uint8_t)WR_STATIC_LOCK_BYTE1;
   1240                 }
   1241             }
   1242             else
   1243             {
   1244                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1245                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1246             }
   1247             break;
   1248         }
   1249 
   1250         case WR_STATIC_LOCK_BYTE1:
   1251         {
   1252             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
   1253             {
   1254                 /* READ ONLY successful */
   1255             }
   1256             else
   1257             {
   1258                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1259                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1260             }
   1261             break;
   1262         }
   1263 
   1264         default:
   1265         {
   1266             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1267                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1268             break;
   1269         }
   1270     }
   1271 
   1272     psNdefMap->TopazContainer.read_only_seq = (uint8_t)e_readonly_seq;
   1273     return result;
   1274 }
   1275 
   1276 #endif /* #ifdef FRINFC_READONLY_NDEF */
   1277 
   1278 static
   1279 NFCSTATUS
   1280 phFriNfc_Tpz_H_ProWrResp (
   1281     phFriNfc_NdefMap_t          *psNdefMap)
   1282 {
   1283     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   1284     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   1285     phFriNfc_Tpz_WrSeq_t                write_seq;
   1286     uint8_t                             write_buf[] = {0x00};
   1287     uint8_t                             write_index = 0;
   1288     uint16_t                            write_len = 0;
   1289     uint16_t                            len_byte_addr = 0;
   1290 
   1291     ps_tpz_info = &(psNdefMap->TopazContainer);
   1292     write_seq = (phFriNfc_Tpz_WrSeq_t)(ps_tpz_info->WriteSeq);
   1293     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
   1294                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
   1295 
   1296     switch (write_seq)
   1297     {
   1298         case WR_NDEF_T_TLV:
   1299         {
   1300             /* TYPE field of the NDEF TLV write is complete */
   1301             if (TOPAZ_WRITE_8_RESPONSE == *psNdefMap->SendRecvLength)
   1302             {
   1303                 psNdefMap->State = (uint8_t)
   1304                                     PH_FRINFC_TOPAZ_STATE_WRITE;
   1305 
   1306                 /* Now, Write 0 to the magic number byte */
   1307                 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_0;
   1308                 write_seq = WR_NMN_0;
   1309                 ps_tpz_info->CurrentBlock = 1;
   1310                 ps_tpz_info->ByteNumber = 0;
   1311 
   1312 #ifdef TOPAZ_RAW_SUPPORT
   1313                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
   1314 #else
   1315                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
   1316 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1317                 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
   1318                                                 sizeof (write_buf));
   1319             }
   1320             else
   1321             {
   1322                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1323                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1324             }
   1325             break;
   1326         }
   1327 
   1328         case WR_NMN_0:
   1329         {
   1330             /* Magic number set to 0 write is complete */
   1331             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
   1332             {
   1333                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
   1334                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
   1335                 /* Now the sequence = WR_LEN_1_0, so Length block is read,
   1336                     and only length bytes are made 0, before writing data to 0
   1337                 */
   1338                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1339             }
   1340             else
   1341             {
   1342                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1343                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1344             }
   1345             break;
   1346         }
   1347 
   1348         case WR_LEN_1_0:
   1349         {
   1350             /* Length field is updated with the value 0 */
   1351             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
   1352             {
   1353                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1354                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1355             }
   1356             else if (write_len >= 0xFF)
   1357             {
   1358                 ps_tpz_info->ByteNumber = 0;
   1359 
   1360                 ps_tpz_info->CurrentBlock = (uint8_t)
   1361                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
   1362                                     ps_tpz_info->CurrentBlock);
   1363 
   1364                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
   1365                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
   1366                 /* Now the sequence = WR_LEN_1_1, so Length block is read,
   1367                     and only length bytes are made 0, before writing data to 0
   1368                 */
   1369                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1370             }
   1371             else
   1372             {
   1373                 /* NDEF data length < 0xFF */
   1374                 len_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite
   1375                                                 (psNdefMap, write_len);
   1376                 ps_tpz_info->CurrentBlock = (uint8_t)
   1377                         TOPAZ_BLK_FROM_BYTE_ADR (len_byte_addr);
   1378                 ps_tpz_info->ByteNumber = (uint8_t)
   1379                         TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (len_byte_addr);
   1380 
   1381 
   1382                 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
   1383                 write_seq = WR_DATA;
   1384 
   1385                 if (0 != ps_tpz_info->ByteNumber)
   1386                 {
   1387                     /* If data starts in between the block then read
   1388                         the data */
   1389                     result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1390                 }
   1391                 else
   1392                 {
   1393                     /* Data starts at the beginning of the block, so start
   1394                         writing the user data */
   1395                     result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
   1396                 }
   1397             }
   1398             break;
   1399         }
   1400 
   1401         case WR_LEN_2_0:
   1402         case WR_LEN_2_VALUE:
   1403         {
   1404             /* 2nd length field is updated with the value 0 or the correct
   1405                 written value */
   1406             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
   1407             {
   1408                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1409                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1410             }
   1411             else
   1412             {
   1413                 ps_tpz_info->ByteNumber = 0;
   1414                 ps_tpz_info->CurrentBlock = (uint8_t)
   1415                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
   1416                                     ps_tpz_info->CurrentBlock);
   1417                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
   1418                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
   1419                 /* If length byte starts in between the block then read
   1420                     the length block */
   1421                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1422             }
   1423             break;
   1424         }
   1425 
   1426         case WR_LEN_3_0:
   1427         {
   1428             /* 3rd length field is updated with the value 0 */
   1429             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
   1430             {
   1431                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1432                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1433             }
   1434             else
   1435             {
   1436                 len_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite
   1437                                                 (psNdefMap, write_len);
   1438                 ps_tpz_info->CurrentBlock = (uint8_t)
   1439                         TOPAZ_BLK_FROM_BYTE_ADR (len_byte_addr);
   1440                 ps_tpz_info->ByteNumber = (uint8_t)
   1441                         TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (len_byte_addr);
   1442 
   1443                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
   1444                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
   1445 
   1446                 if (0 != ps_tpz_info->ByteNumber)
   1447                 {
   1448                     /* If data starts in between the block then read
   1449                         the data */
   1450                     result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1451                 }
   1452                 else
   1453                 {
   1454                     /* Data starts at the beginning of the block, so start
   1455                         writing the user data */
   1456                     result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
   1457                 }
   1458             }
   1459             break;
   1460         }
   1461 
   1462         case WR_DATA:
   1463         {
   1464             /* Data is written from the input buffer */
   1465             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
   1466             {
   1467                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1468                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1469             }
   1470             else if (write_len == psNdefMap->ApduBuffIndex)
   1471             {
   1472                 /* Data to be written is completely written to the card */
   1473                 *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex;
   1474                 ps_tpz_info->WriteSeq = (uint8_t)WR_LEN_1_VALUE;
   1475                 write_seq = WR_LEN_1_VALUE;
   1476                 /* To write the first length byte, it has to be read and then
   1477                     the length has to be updated */
   1478                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1479             }
   1480             else
   1481             {
   1482                 ps_tpz_info->ByteNumber = 0;
   1483                 /* Go to the next block */
   1484                 ps_tpz_info->CurrentBlock = (uint8_t)
   1485                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
   1486                                     ps_tpz_info->CurrentBlock);
   1487                 /* Copy and write the user data */
   1488                 result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
   1489             }
   1490             break;
   1491         }
   1492 
   1493         case WR_DATA_READ_REQD:
   1494         {
   1495             /* This sequence is executed, if the first read has some
   1496                 lock or reserved blocks bytes and the lock or reserved
   1497                 blocks are extended to the next block  */
   1498             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
   1499             {
   1500                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1501                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1502             }
   1503             else
   1504             {
   1505                 ps_tpz_info->ByteNumber = 0;
   1506                 /* Go to the next block */
   1507                 ps_tpz_info->CurrentBlock = (uint8_t)
   1508                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
   1509                                     ps_tpz_info->CurrentBlock);
   1510                 /* Write is complete for one block, now because lock bytes are
   1511                     shifted to next blocks, the next block is read and update
   1512                     the written data by skipping the lock or reserved memory bytes */
   1513                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1514             }
   1515             break;
   1516         }
   1517 
   1518         case WR_LEN_3_VALUE:
   1519         {
   1520             /* 3rd LENGTH field byte is updated with correct written value */
   1521             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
   1522             {
   1523                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1524                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1525             }
   1526             else
   1527             {
   1528 #ifdef TOPAZ_RAW_SUPPORT
   1529                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
   1530 #else
   1531                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
   1532 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1533 
   1534                 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
   1535 
   1536                 write_buf[write_index] = PH_FRINFC_TOPAZ_CC_BYTE0;
   1537                 write_index = (uint8_t)(write_index + 1);
   1538 
   1539                 ps_tpz_info->ByteNumber = 0;
   1540                 ps_tpz_info->CurrentBlock = 1;
   1541 
   1542                 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_E1;
   1543                 write_seq = WR_NMN_E1;
   1544 
   1545                 /* Length byte write is complete, so now update the magic
   1546                     number byte with value 0xE1 */
   1547                 result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf,
   1548                                                 write_index);
   1549             }
   1550             break;
   1551         }
   1552 
   1553         case WR_LEN_1_VALUE:
   1554         {
   1555             /* 1st LENGTH field byte is updated */
   1556             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
   1557             {
   1558                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1559                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1560             }
   1561             else if (write_len < 0xFF)
   1562             {
   1563                 /* Total length to write is less than 0xFF, so LENGTH field has
   1564                     only one byte, then update the magic number byte with
   1565                     value 0xE1 */
   1566 #ifdef TOPAZ_RAW_SUPPORT
   1567                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
   1568 #else
   1569                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
   1570 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1571                 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
   1572 
   1573                 write_buf[write_index] = PH_FRINFC_TOPAZ_CC_BYTE0;
   1574                 write_index = (uint8_t)(write_index + 1);
   1575 
   1576                 ps_tpz_info->ByteNumber = 0;
   1577                 ps_tpz_info->CurrentBlock = 1;
   1578 
   1579                 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_E1;
   1580                 write_seq = WR_NMN_E1;
   1581                 result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf,
   1582                                                 write_index);
   1583             }
   1584             else
   1585             {
   1586                 /* 2nd byte of the LENGTH field has to be updated so,
   1587                     read the block, before updating it */
   1588                 ps_tpz_info->ByteNumber = 0;
   1589                 ps_tpz_info->CurrentBlock = (uint8_t)
   1590                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
   1591                                     ps_tpz_info->CurrentBlock);
   1592                 ps_tpz_info->WriteSeq = (uint8_t)WR_LEN_2_VALUE;
   1593                 write_seq = WR_LEN_2_VALUE;
   1594                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   1595             }
   1596             break;
   1597         }
   1598 
   1599         case WR_NMN_E1:
   1600         {
   1601             /* Magic number is written, so update the actual ndef length.  */
   1602             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
   1603             {
   1604                 *psNdefMap->WrNdefPacketLength = (uint32_t)
   1605                                                 psNdefMap->ApduBuffIndex;
   1606                 ps_tpz_info->ActualNDEFMsgSize = (uint16_t)
   1607                                                 psNdefMap->ApduBuffIndex;
   1608             }
   1609             else
   1610             {
   1611                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1612                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1613             }
   1614             break;
   1615         }
   1616 
   1617         default:
   1618         {
   1619             break;
   1620         }
   1621     }
   1622 
   1623     return result;
   1624 }
   1625 
   1626 static
   1627 NFCSTATUS
   1628 phFriNfc_Tpz_H_UpdateNdefTypeField (
   1629     phFriNfc_NdefMap_t          *psNdefMap)
   1630 {
   1631     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   1632     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   1633     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
   1634 
   1635     ps_tpz_info = &(psNdefMap->TopazContainer);
   1636 
   1637     (void)memcpy ((void *)write_buf, (void *)
   1638                 psNdefMap->SendRecvBuf, TOPAZ_WRITE_8_DATA_LENGTH);
   1639 
   1640     /* Update the TYPE field of the NDEF TLV */
   1641     write_buf[ps_tpz_info->ByteNumber] = PH_FRINFC_TOPAZ_NDEF_T;
   1642 
   1643     psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
   1644 
   1645 #ifdef TOPAZ_RAW_SUPPORT
   1646     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
   1647 #else
   1648     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
   1649 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1650     result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf,
   1651                                     sizeof (write_buf));
   1652 
   1653     return result;
   1654 }
   1655 
   1656 static
   1657 NFCSTATUS
   1658 phFriNfc_Tpz_H_ProRdForWrResp (
   1659     phFriNfc_NdefMap_t          *psNdefMap)
   1660 {
   1661     /* This function is used during the write operation */
   1662     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   1663     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   1664 
   1665     ps_tpz_info = &(psNdefMap->TopazContainer);
   1666 
   1667     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
   1668 
   1669     if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
   1670     {
   1671         switch ((phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq)
   1672         {
   1673             case WR_NDEF_T_TLV:
   1674             {
   1675                 /* Read bytes are for updating the TYPE field of the NDEF TLV */
   1676                 result = phFriNfc_Tpz_H_UpdateNdefTypeField (psNdefMap);
   1677                 break;
   1678             }
   1679 
   1680             case WR_LEN_1_0:
   1681             case WR_LEN_2_0:
   1682             case WR_LEN_3_0:
   1683             {
   1684                 /* Read bytes are for updating the LENGTH field to 0 of the NDEF TLV and
   1685                 also to update the data from the user buffer */
   1686                 result = phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (psNdefMap);
   1687                 break;
   1688             }
   1689 
   1690             case WR_DATA:
   1691             case WR_DATA_READ_REQD:
   1692             {
   1693                 /* Read bytes are for skipping the lock and reserved bytes */
   1694                 result = phFriNfc_Tpz_H_CopyReadDataAndWrite (psNdefMap);
   1695                 break;
   1696             }
   1697 
   1698             case WR_LEN_1_VALUE:
   1699             case WR_LEN_2_VALUE:
   1700             case WR_LEN_3_VALUE:
   1701             {
   1702                 /* Read bytes are for updating the LENGTH field to the correct values
   1703                     of the NDEF TLV */
   1704                 result = phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (psNdefMap);
   1705                 break;
   1706             }
   1707 
   1708             default:
   1709             {
   1710                 /* Code must not come come here */
   1711                 break;
   1712             }
   1713         }
   1714     }
   1715     else
   1716     {
   1717         /* Error in the length, wither the HW has sent wrong response length or
   1718             the response length byte is corrupted */
   1719         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1720                             NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1721     }
   1722 
   1723 
   1724     return result;
   1725 }
   1726 
   1727 static
   1728 NFCSTATUS
   1729 phFriNfc_Tpz_H_ChkReadID(
   1730     phFriNfc_NdefMap_t      *psNdefMap)
   1731 {
   1732     NFCSTATUS   result = NFCSTATUS_SUCCESS;
   1733     int         compare_result = 0;
   1734     uint8_t     recv_index = 0;
   1735 
   1736 
   1737     if (PH_FRINFC_TOPAZ_VAL6 == *psNdefMap->SendRecvLength)
   1738     {
   1739         if (((psNdefMap->SendRecvBuf[recv_index] &
   1740             PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_DYNAMIC_HEADROM0_VAL))
   1741         {
   1742             /* Copy UID to the context*/
   1743             compare_result = phOsalNfc_MemCompare (
   1744                                 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid,
   1745                                 &psNdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
   1746                                 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
   1747             if (0 == compare_result)
   1748             {
   1749                 /* State has to be changed */
   1750                 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
   1751 
   1752                 /* Topaz command = READSEG */
   1753 #ifdef TOPAZ_RAW_SUPPORT
   1754 
   1755                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
   1756 
   1757 #else
   1758 
   1759 #ifdef PH_HAL4_ENABLE
   1760                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
   1761 #else
   1762                 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
   1763 #endif
   1764                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
   1765 
   1766 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1767                 /* Read bytes from the card */
   1768                 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   1769             }
   1770             else
   1771             {
   1772                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1773                                     NFCSTATUS_NO_NDEF_SUPPORT);
   1774 
   1775             }
   1776         }
   1777     }
   1778     else
   1779     {
   1780         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1781                             NFCSTATUS_INVALID_RECEIVE_LENGTH);
   1782     }
   1783 
   1784     return result;
   1785 }
   1786 
   1787 #define TOPAZ_READ_ID_ZERO_LENGTH                   (0x06U)
   1788 static
   1789 NFCSTATUS
   1790 phFriNfc_Tpz_H_NxpRead (
   1791     phFriNfc_NdefMap_t          *psNdefMap)
   1792 {
   1793     NFCSTATUS           result = NFCSTATUS_SUCCESS;
   1794     uint8_t             send_index = 0;
   1795 #ifdef TOPAZ_RAW_SUPPORT
   1796     uint8_t             read_append[] = { 0x00, 0x00, 0x00, 0x00,
   1797                                         0x00, 0x00, 0x00, 0x00};
   1798 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1799 
   1800     /* set the data for additional data exchange*/
   1801     psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
   1802     psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
   1803     psNdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
   1804 
   1805     psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazDynamicMap_Process;
   1806     psNdefMap->MapCompletionInfo.Context = psNdefMap;
   1807 
   1808     *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
   1809 
   1810     /* Depending on the jewel command, the send length is decided */
   1811 #ifdef TOPAZ_RAW_SUPPORT
   1812 
   1813     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
   1814     /* " send_index " is incremented because already received buffer is filled with
   1815         TOPAZ command */
   1816     send_index = (uint8_t)(send_index + 1);
   1817 
   1818     switch (*psNdefMap->SendRecvBuf)
   1819 #else
   1820     switch(psNdefMap->Cmd.JewelCmd)
   1821 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1822     {
   1823 #ifdef TOPAZ_RAW_SUPPORT
   1824 
   1825         case PH_FRINFC_TOPAZ_CMD_READID:
   1826         {
   1827             (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
   1828                         (void *)read_append, TOPAZ_READ_ID_ZERO_LENGTH);
   1829             send_index = (uint8_t)(send_index + TOPAZ_READ_ID_ZERO_LENGTH);
   1830             break;
   1831         }
   1832 
   1833         case PH_FRINFC_TOPAZ_CMD_READ8:
   1834         {
   1835             psNdefMap->SendRecvBuf[send_index] =
   1836                                     psNdefMap->TopazContainer.CurrentBlock;
   1837             send_index = (uint8_t)(send_index + 1);
   1838             break;
   1839         }
   1840 
   1841         case PH_FRINFC_TOPAZ_CMD_RSEG:
   1842         {
   1843             psNdefMap->SendRecvBuf[send_index] = (uint8_t)
   1844                                             (psNdefMap->TopazContainer.CurrentSeg
   1845                                              << NIBBLE_SIZE);
   1846             send_index = (uint8_t)(send_index + 1);
   1847             break;
   1848         }
   1849 
   1850 #else /* #ifdef TOPAZ_RAW_SUPPORT */
   1851 
   1852 #ifdef PH_HAL4_ENABLE
   1853         case phHal_eJewel_RID:
   1854         case phHal_eJewel_ReadAll:
   1855 #else
   1856         case phHal_eJewelCmdListJewelRid:
   1857         case phHal_eJewelCmdListJewelReadAll:
   1858 #endif
   1859         {
   1860             /* For READ ID and READ ALL, send length is 0 */
   1861             psNdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
   1862             break;
   1863         }
   1864 
   1865 #ifdef PH_HAL4_ENABLE
   1866         case phHal_eJewel_Read:
   1867 #else
   1868         case phHal_eJewelCmdListJewelRead:
   1869 #endif
   1870         {
   1871             /* Need to check the User data size request*/
   1872 
   1873             psNdefMap->SendLength = PH_FRINFC_TOPAZ_VAL3;
   1874             break;
   1875         }
   1876 
   1877         case phHal_eJewel_ReadSeg:
   1878         {
   1879             psNdefMap->SendRecvBuf[send_index] = (uint8_t)
   1880                                             (psNdefMap->TopazContainer.CurrentSeg
   1881                                              << NIBBLE_SIZE);
   1882             send_index = (uint8_t)(send_index + 1);
   1883             psNdefMap->SendLength = send_index;
   1884             break;
   1885         }
   1886 
   1887         case phHal_eJewel_Read8:
   1888         {
   1889             psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read4;
   1890             psNdefMap->SendRecvBuf[send_index] = psNdefMap->TopazContainer.CurrentBlock;
   1891             send_index = (uint8_t)(send_index + 1);
   1892             psNdefMap->SendLength = send_index;
   1893             break;
   1894         }
   1895 
   1896 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1897 
   1898         default:
   1899         {
   1900             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1901                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
   1902             break;
   1903         }
   1904     }
   1905     if(result == NFCSTATUS_SUCCESS)
   1906     {
   1907 #ifdef TOPAZ_RAW_SUPPORT
   1908 
   1909         if (PH_FRINFC_TOPAZ_CMD_READID != *psNdefMap->SendRecvBuf)
   1910         {
   1911             (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
   1912                             (void *)read_append, sizeof (read_append));
   1913             send_index = (uint8_t)(send_index + sizeof (read_append));
   1914 
   1915             (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
   1916                         (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid,
   1917                         TOPAZ_UID_LENGTH_FOR_READ_WRITE);
   1918             send_index = (uint8_t)(send_index +
   1919                         TOPAZ_UID_LENGTH_FOR_READ_WRITE);
   1920         }
   1921 
   1922         psNdefMap->SendLength = send_index;
   1923 
   1924 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1925         /* Call the Overlapped HAL Transceive function */
   1926         result = phFriNfc_OvrHal_Transceive(    psNdefMap->LowerDevice,
   1927                                                 &psNdefMap->MapCompletionInfo,
   1928                                                 psNdefMap->psRemoteDevInfo,
   1929                                                 psNdefMap->Cmd,
   1930                                                 &psNdefMap->psDepAdditionalInfo,
   1931                                                 psNdefMap->SendRecvBuf,
   1932                                                 psNdefMap->SendLength,
   1933                                                 psNdefMap->SendRecvBuf,
   1934                                                 psNdefMap->SendRecvLength);
   1935     }
   1936     return result;
   1937 }
   1938 
   1939 
   1940 static
   1941 NFCSTATUS
   1942 phFriNfc_Tpz_H_NxpWrite(
   1943     phFriNfc_NdefMap_t          *psNdefMap,
   1944     uint8_t                     *p_write_data,
   1945     uint8_t                     wr_data_len)
   1946 {
   1947     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   1948     phFriNfc_TopazCont_t        *ps_tpz_info = NULL;
   1949     uint8_t                     send_index = 0;
   1950 
   1951     ps_tpz_info = &(psNdefMap->TopazContainer);
   1952 
   1953     /* set the data for additional data exchange*/
   1954     psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
   1955     psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
   1956     psNdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
   1957 
   1958     psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazDynamicMap_Process;
   1959     psNdefMap->MapCompletionInfo.Context = psNdefMap;
   1960 
   1961     *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
   1962 
   1963 #ifdef TOPAZ_RAW_SUPPORT
   1964     /* " send_index " is incremented because already received buffer is filled with
   1965         TOPAZ command */
   1966     send_index = (uint8_t)(send_index + 1);
   1967     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
   1968 
   1969     switch (*psNdefMap->SendRecvBuf)
   1970 
   1971 #else /* #ifdef TOPAZ_RAW_SUPPORT */
   1972 
   1973     switch (psNdefMap->Cmd.JewelCmd)
   1974 
   1975 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   1976     {
   1977 #ifdef TOPAZ_RAW_SUPPORT
   1978 
   1979         case PH_FRINFC_TOPAZ_CMD_WRITE_1E:
   1980         {
   1981             psNdefMap->SendRecvBuf[send_index] = (uint8_t)((ps_tpz_info->CurrentBlock
   1982                                                 << (NIBBLE_SIZE - 1)) |
   1983                                                 ps_tpz_info->ByteNumber);
   1984             send_index = (uint8_t)(send_index + 1);
   1985             break;
   1986         }
   1987 
   1988         case PH_FRINFC_TOPAZ_CMD_WRITE_E8:
   1989         {
   1990             psNdefMap->SendRecvBuf[send_index] = ps_tpz_info->CurrentBlock;
   1991             send_index = (uint8_t)(send_index + 1);
   1992             break;
   1993         }
   1994 
   1995 #else /* #ifdef TOPAZ_RAW_SUPPORT */
   1996 
   1997         case phHal_eJewel_Write1E:
   1998         {
   1999             psNdefMap->SendRecvBuf[send_index] = (uint8_t)((ps_tpz_info->CurrentBlock
   2000                                                 << (NIBBLE_SIZE - 1)) |
   2001                                                 ps_tpz_info->ByteNumber);
   2002             send_index = (uint8_t)(send_index + 1);
   2003 
   2004 
   2005             break;
   2006         }
   2007 
   2008         case phHal_eJewel_Write8E:
   2009         {
   2010             psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write4E;
   2011             psNdefMap->SendRecvBuf[send_index] = ps_tpz_info->CurrentBlock;
   2012             send_index = (uint8_t)(send_index + 1);
   2013             break;
   2014         }
   2015 
   2016 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   2017 
   2018         default:
   2019         {
   2020             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2021                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
   2022             break;
   2023         }
   2024     }
   2025 
   2026 
   2027     if (NFCSTATUS_SUCCESS == result)
   2028     {
   2029         (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
   2030                     (void *)p_write_data, wr_data_len);
   2031 
   2032         send_index = (uint8_t)(send_index + wr_data_len);
   2033 
   2034 #ifdef TOPAZ_RAW_SUPPORT
   2035 
   2036         (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
   2037                     (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid,
   2038                     TOPAZ_UID_LENGTH_FOR_READ_WRITE);
   2039         send_index = (uint8_t)(send_index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
   2040 
   2041 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   2042 
   2043         psNdefMap->SendLength = send_index;
   2044 
   2045         /* Call the Overlapped HAL Transceive function */
   2046         result = phFriNfc_OvrHal_Transceive(    psNdefMap->LowerDevice,
   2047                                                 &psNdefMap->MapCompletionInfo,
   2048                                                 psNdefMap->psRemoteDevInfo,
   2049                                                 psNdefMap->Cmd,
   2050                                                 &psNdefMap->psDepAdditionalInfo,
   2051                                                 psNdefMap->SendRecvBuf,
   2052                                                 psNdefMap->SendLength,
   2053                                                 psNdefMap->SendRecvBuf,
   2054                                                 psNdefMap->SendRecvLength);
   2055     }
   2056     return result;
   2057 }
   2058 
   2059 static
   2060 NFCSTATUS
   2061 phFriNfc_Tpz_H_ProReadResp(
   2062     phFriNfc_NdefMap_t          *psNdefMap)
   2063 {
   2064     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   2065     phFriNfc_TopazCont_t        *ps_tpz_info = NULL;
   2066     uint8_t                     write_buffer[] = {0x00};
   2067 
   2068     ps_tpz_info = &(psNdefMap->TopazContainer);
   2069 
   2070     switch (psNdefMap->PrevOperation)
   2071     {
   2072         case  PH_FRINFC_NDEFMAP_CHECK_OPE:
   2073         {
   2074             if (PH_FRINFC_TOPAZ_DYNAMIC_READSEG_RESP ==
   2075                 *psNdefMap->SendRecvLength)
   2076             {
   2077                 if (0 == ps_tpz_info->CurrentSeg)
   2078                 {
   2079                     result = phFriNfc_Tpz_H_CheckCCBytes (psNdefMap);
   2080                 }
   2081 
   2082                 if (NFCSTATUS_SUCCESS == result)
   2083                 {
   2084                     result = phFriNfc_Tpz_H_ParseTLVs (psNdefMap);
   2085                 }
   2086             }
   2087             else
   2088             {
   2089                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2090                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   2091             }
   2092             break;
   2093         }
   2094 
   2095         case  PH_FRINFC_NDEFMAP_READ_OPE:
   2096         {
   2097             if (PH_FRINFC_TOPAZ_DYNAMIC_READSEG_RESP ==
   2098                 *psNdefMap->SendRecvLength)
   2099             {
   2100                 /* call the data bytes to internal buffer*/
   2101                 result = phFriNfc_Tpz_H_CopyReadData (psNdefMap);
   2102             }
   2103             else
   2104             {
   2105                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2106                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   2107             }
   2108             break;
   2109         }
   2110 
   2111         case  PH_FRINFC_NDEFMAP_WRITE_OPE:
   2112         {
   2113             /* read the bytes for cheking the CC bytes and lock bit status*/
   2114             if(TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
   2115             {
   2116                 (void)memcpy ((void *)ps_tpz_info->CCByteBuf,
   2117                             (void *)(psNdefMap->SendRecvBuf),
   2118                             TOPAZ_CC_BYTES_LENGTH);
   2119 
   2120                 result = phFriNfc_Tpz_H_CheckCCBytesForWrite (psNdefMap);
   2121                 if (NFCSTATUS_SUCCESS == result)
   2122                 {
   2123                     if ((0x00 == *ps_tpz_info->CCByteBuf) ||
   2124                         (NDEF_T_TLV == ps_tpz_info->ExpectedSeq))
   2125                     {
   2126                         /* This statement is for getting the new
   2127                             NDEF TLV byte address, because 1st CC byte is
   2128                             corrupted or no NDEF TLV in the card
   2129 
   2130                             If the 1st CC byte (NDEF magic number) in the
   2131                             card is 0, means that previous write has failed,
   2132                             so to write the exact file
   2133                             OR
   2134                             The NDEF TLV is not present in the entire card, and
   2135                             the sequence is NDEF_T_TLV (this means, that lock and
   2136                             memory control TLV is found in the card)
   2137                         */
   2138                         psNdefMap->State = (uint8_t)
   2139                                         PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF;
   2140                         ps_tpz_info->WriteSeq = (uint8_t)WR_NDEF_T_TLV;
   2141 
   2142                         ps_tpz_info->CurrentBlock = (uint8_t)
   2143                                     TOPAZ_BLK_FROM_BYTE_ADR (
   2144                                         ps_tpz_info->NdefTLVByteAddress);
   2145 
   2146                         ps_tpz_info->ByteNumber = (uint8_t)
   2147                                     TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (
   2148                                         ps_tpz_info->NdefTLVByteAddress);
   2149 
   2150 #ifdef TOPAZ_RAW_SUPPORT
   2151                         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
   2152 #else
   2153                         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
   2154 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   2155 
   2156                         result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   2157                     }
   2158                     else
   2159                     {
   2160                         ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_0;
   2161                         ps_tpz_info->CurrentBlock = 1;
   2162                         ps_tpz_info->ByteNumber = 0;
   2163                         psNdefMap->State = (uint8_t)
   2164                                             PH_FRINFC_TOPAZ_STATE_WRITE;
   2165 #ifdef TOPAZ_RAW_SUPPORT
   2166                         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
   2167 #else
   2168                         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
   2169 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   2170 
   2171                         /* Call read 8 */
   2172                         result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buffer,
   2173                                                     sizeof (write_buffer));
   2174                     }
   2175 
   2176                 }
   2177             }
   2178             else
   2179             {
   2180                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2181                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
   2182             }
   2183             break;
   2184         }
   2185 
   2186         default:
   2187         {
   2188             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2189                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
   2190             break;
   2191         }
   2192     }
   2193 
   2194     return result;
   2195 }
   2196 
   2197 
   2198 
   2199 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t  *NdefMap,
   2200                                     NFCSTATUS           Status)
   2201 {
   2202     /* set the state back to the Reset_Init state*/
   2203     NdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
   2204 
   2205     /* set the completion routine*/
   2206     NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex].
   2207         CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
   2208 }
   2209 
   2210 static
   2211 NFCSTATUS
   2212 phFriNfc_Tpz_H_ChkLockBits(
   2213     phFriNfc_NdefMap_t  *psNdefMap)
   2214 {
   2215     NFCSTATUS           result = NFCSTATUS_SUCCESS;
   2216 #ifdef ENABLE_LOCK_BITS_CHECK
   2217     uint8_t             *p_recv_buf = psNdefMap->SendRecvBuf;
   2218 #endif /* #ifdef ENABLE_LOCK_BITS_CHECK */
   2219     psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
   2220 
   2221 #ifdef ENABLE_LOCK_BITS_CHECK
   2222 
   2223     /* Set the card state */
   2224     psNdefMap->CardState =  (uint8_t)
   2225         (((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_0] ==
   2226             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_0) &&
   2227             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_1] ==
   2228             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_1)) &&
   2229             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_2] ==
   2230             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
   2231             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_3] ==
   2232             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
   2233             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_4] ==
   2234             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
   2235             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_5] ==
   2236             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
   2237             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_6] ==
   2238             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7))) &&
   2239             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_7] ==
   2240             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) ?
   2241                 PH_NDEFMAP_CARD_STATE_INITIALIZED :
   2242                 PH_NDEFMAP_CARD_STATE_READ_ONLY);
   2243 
   2244 #endif /* #ifdef ENABLE_LOCK_BITS_CHECK */
   2245 
   2246     /* Set the card state from CC bytes */
   2247     if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
   2248     {
   2249         switch ((psNdefMap->TopazContainer.CCByteBuf[3] & 0xFF))
   2250         {
   2251             case PH_FRINFC_TOPAZ_CC_READWRITE:
   2252             {
   2253                 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
   2254                 break;
   2255             }
   2256 
   2257             case PH_FRINFC_TOPAZ_CC_READONLY:
   2258             {
   2259                 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
   2260                 break;
   2261             }
   2262 
   2263             default:
   2264             {
   2265                 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
   2266                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2267                                     NFCSTATUS_NO_NDEF_SUPPORT);
   2268                 break;
   2269             }
   2270         }
   2271     }
   2272 
   2273     return result;
   2274 }
   2275 
   2276 static
   2277 NFCSTATUS
   2278 phFriNfc_Tpz_H_CheckCCBytes (
   2279     phFriNfc_NdefMap_t          *psNdefMap)
   2280 {
   2281     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
   2282     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
   2283     uint8_t                         *p_recv_buf = psNdefMap->SendRecvBuf;
   2284     uint16_t                        parse_index = 0;
   2285 
   2286     parse_index = (uint16_t)(parse_index + TOPAZ_UID_BYTES_LENGTH);
   2287 
   2288     (void)memcpy ((void *)ps_tpz_info->CCByteBuf,
   2289                 (void *)(p_recv_buf + parse_index),
   2290                 TOPAZ_CC_BYTES_LENGTH);
   2291 
   2292     p_recv_buf = ps_tpz_info->CCByteBuf;
   2293     parse_index = 0;
   2294 
   2295 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
   2296     /* 1st CC byte value = 0 or 0xE1 */
   2297     if ((PH_FRINFC_TOPAZ_CC_BYTE0 == p_recv_buf[parse_index])
   2298 #ifdef TOPAZ_MAGIC_NO_0_CHK_ENABLE
   2299         || (0 == p_recv_buf[parse_index])
   2300 #endif /* #if TOPAZ_MAGIC_NO_0_CHK_ENABLE */
   2301         )
   2302 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
   2303     {
   2304         parse_index = (uint16_t)(parse_index + 1);
   2305         /* 2nd CC byte value = 0x10 */
   2306         result = phFriNfc_Tpz_H_ChkSpcVer (psNdefMap, p_recv_buf[parse_index]);
   2307     }
   2308 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
   2309     else
   2310     {
   2311         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2312                             NFCSTATUS_NO_NDEF_SUPPORT);
   2313     }
   2314 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
   2315 
   2316     if (NFCSTATUS_SUCCESS == result)
   2317     {
   2318         parse_index = (uint16_t)(parse_index + 1);
   2319         /* 3rd CC byte value = 0x3F for 512 card */
   2320         if (PH_FRINFC_TOPAZ_DYNAMIC_CC_BYTE2_MMSIZE == p_recv_buf[parse_index])
   2321         {
   2322             /* Card size calculated as ((3rd CC byte * 8) - 4 CC bytes) */
   2323             psNdefMap->CardMemSize = (uint16_t)((p_recv_buf[parse_index] *
   2324                                     TOPAZ_BYTES_PER_BLOCK) -
   2325                                     TOPAZ_CC_BYTES_LENGTH);
   2326             ps_tpz_info->RemainingSize = (uint16_t)(psNdefMap->CardMemSize +
   2327                                         TOPAZ_UID_BYTES_LENGTH +
   2328                                         TOPAZ_CC_BYTES_LENGTH);
   2329             result = phFriNfc_Tpz_H_ChkLockBits (psNdefMap);
   2330         }
   2331         else
   2332         {
   2333             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2334                                 NFCSTATUS_NO_NDEF_SUPPORT);
   2335         }
   2336     }
   2337 
   2338     if (NFCSTATUS_SUCCESS != result)
   2339     {
   2340         psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
   2341     }
   2342 
   2343     return result;
   2344 }
   2345 
   2346 static
   2347 NFCSTATUS
   2348 phFriNfc_Tpz_H_CheckCCBytesForWrite (
   2349     phFriNfc_NdefMap_t          *psNdefMap)
   2350 {
   2351     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   2352     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   2353     uint8_t                             check_cc_rw[] = {TOPAZ_SPEC_VERSION,
   2354                                         PH_FRINFC_TOPAZ_DYNAMIC_CC_BYTE2_MMSIZE,
   2355                                         PH_FRINFC_TOPAZ_CC_READWRITE};
   2356     uint8_t                             check_index = 0;
   2357 
   2358     ps_tpz_info = &(psNdefMap->TopazContainer);
   2359 
   2360 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
   2361     if (
   2362         (PH_FRINFC_TOPAZ_CC_BYTE0 == ps_tpz_info->CCByteBuf[check_index])
   2363 #if TOPAZ_MAGIC_NO_0_CHK_ENABLE
   2364         || (0 == ps_tpz_info->CCByteBuf[check_index])
   2365 #endif /* #if TOPAZ_MAGIC_NO_0_CHK_ENABLE */
   2366         )
   2367 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
   2368     {
   2369         check_index = (uint8_t)(check_index + 1);
   2370 
   2371         if ((check_cc_rw[0] != ps_tpz_info->CCByteBuf[1]) ||
   2372             (check_cc_rw[1] != ps_tpz_info->CCByteBuf[2]) ||
   2373             (check_cc_rw[2] != ps_tpz_info->CCByteBuf[3]))
   2374         {
   2375             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2376                                 NFCSTATUS_NO_NDEF_SUPPORT);
   2377         }
   2378     }
   2379 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
   2380     else
   2381     {
   2382         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2383                             NFCSTATUS_NO_NDEF_SUPPORT);
   2384     }
   2385 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
   2386     return result;
   2387 }
   2388 
   2389 static
   2390 uint16_t
   2391 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
   2392     phFriNfc_NdefMap_t          *psNdefMap)
   2393 {
   2394     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
   2395     uint16_t                        skip_size = 0;
   2396     uint16_t                        byte_addr = 0;
   2397     uint8_t                         exit_index = 0;
   2398 
   2399     byte_addr = ps_tpz_info->NdefTLVByteAddress;
   2400 
   2401     while (exit_index < ((ps_tpz_info->ActualNDEFMsgSize >= 0xFF) ? 3 : 1))
   2402     {
   2403         byte_addr = (uint16_t)(byte_addr + 1);
   2404         if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
   2405         {
   2406             byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
   2407         }
   2408         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   2409 
   2410         byte_addr = (uint16_t)(byte_addr + skip_size);
   2411         exit_index = (uint8_t)(exit_index + 1);
   2412     }
   2413 
   2414     byte_addr = (uint16_t)(byte_addr + 1);
   2415     if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
   2416     {
   2417         byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
   2418     }
   2419     skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   2420 
   2421     byte_addr = (uint16_t)(byte_addr + skip_size);
   2422 
   2423     return byte_addr;
   2424 }
   2425 
   2426 static
   2427 uint16_t
   2428 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (
   2429     phFriNfc_NdefMap_t          *psNdefMap,
   2430     uint16_t                    size_to_write)
   2431 {
   2432     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
   2433     uint16_t                        skip_size = 0;
   2434     uint16_t                        byte_addr = 0;
   2435     uint8_t                         exit_index = 0;
   2436 
   2437     byte_addr = ps_tpz_info->NdefTLVByteAddress;
   2438 
   2439     while (exit_index < ((size_to_write >= 0xFF) ? 3 : 1))
   2440     {
   2441         byte_addr = (uint16_t)(byte_addr + 1);
   2442         if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
   2443         {
   2444             byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
   2445         }
   2446         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   2447 
   2448         byte_addr = (uint16_t)(byte_addr + skip_size);
   2449         exit_index = (uint8_t)(exit_index + 1);
   2450     }
   2451 
   2452     byte_addr = (uint16_t)(byte_addr + 1);
   2453     if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
   2454     {
   2455         byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
   2456     }
   2457     skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   2458 
   2459     byte_addr = (uint16_t)(byte_addr + skip_size);
   2460 
   2461     return byte_addr;
   2462 }
   2463 
   2464 
   2465 static
   2466 NFCSTATUS
   2467 phFriNfc_Tpz_H_RemainingReadDataCopy (
   2468     phFriNfc_NdefMap_t          *psNdefMap)
   2469 {
   2470     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
   2471     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
   2472     uint8_t                         copy_temp_buf[PH_FRINFC_NDEFMAP_TOPAZ_MAX_SIZE];
   2473     uint16_t                        copy_length = 0;
   2474     uint16_t                        read_copy_length = 0;
   2475 
   2476 
   2477     if (0 != ps_tpz_info->ReadBufferSize)
   2478     {
   2479         /* Data is already copied, so give it from the stored buffer */
   2480         if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex) >=
   2481             ps_tpz_info->ReadBufferSize)
   2482         {
   2483             read_copy_length = ps_tpz_info->ReadBufferSize;
   2484             (void)memcpy ((void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
   2485                     (void *)ps_tpz_info->ReadBuffer, ps_tpz_info->ReadBufferSize);
   2486         }
   2487         else
   2488         {
   2489             read_copy_length = (uint16_t)(psNdefMap->ApduBufferSize -
   2490                                 psNdefMap->ApduBuffIndex);
   2491 
   2492             copy_length = (uint16_t)(ps_tpz_info->ReadBufferSize -
   2493                             read_copy_length);
   2494 
   2495             /* Copy data to user buffer */
   2496             (void)memcpy ((void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
   2497                     (void *)ps_tpz_info->ReadBuffer, read_copy_length);
   2498 
   2499             /* Copy data from " ReadBuffer " to temporary buffer */
   2500             (void)memcpy ((void *)copy_temp_buf,
   2501                     (void *)(ps_tpz_info->ReadBuffer + read_copy_length),
   2502                     copy_length);
   2503 
   2504             /* Copy data from temporary buffer to " ReadBuffer " */
   2505             (void)memcpy ((void *)ps_tpz_info->ReadBuffer,
   2506                     (void *)copy_temp_buf, copy_length);
   2507 
   2508         }
   2509 
   2510         psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
   2511                                     read_copy_length);
   2512         ps_tpz_info->ReadBufferSize = (uint8_t)
   2513                             (ps_tpz_info->ReadBufferSize -
   2514                             read_copy_length);
   2515         ps_tpz_info->RemainingReadSize = (uint16_t)(
   2516                             ps_tpz_info->RemainingReadSize - read_copy_length);
   2517     }
   2518 
   2519     if (0 == ps_tpz_info->RemainingReadSize)
   2520     {
   2521         /* No data to read, so return */
   2522         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
   2523         ps_tpz_info->ReadBufferSize = 0;
   2524         ps_tpz_info->ReadWriteCompleteFlag = TRUE;
   2525     }
   2526     else if (psNdefMap->ApduBuffIndex == psNdefMap->ApduBufferSize)
   2527     {
   2528         /* User data length is read completely */
   2529         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
   2530     }
   2531     else
   2532     {
   2533         /* Stored data is not enough, so continue reading the next segment */
   2534         ps_tpz_info->CurrentSeg = (uint8_t)
   2535                             (ps_tpz_info->CurrentSeg + 1);
   2536 #ifdef TOPAZ_RAW_SUPPORT
   2537 
   2538         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
   2539 
   2540 #else
   2541 
   2542         psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
   2543 
   2544 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   2545         result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   2546     }
   2547 
   2548     return result;
   2549 }
   2550 
   2551 static
   2552 NFCSTATUS
   2553 phFriNfc_Tpz_H_CopyReadData (
   2554     phFriNfc_NdefMap_t          *psNdefMap)
   2555 {
   2556     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
   2557     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
   2558     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
   2559     phFriNfc_ResMemCntrlTLVCont_t   *ps_memtlv_info = NULL;
   2560     uint16_t                        copy_index = 0;
   2561     uint16_t                        copy_length = 0;
   2562     uint16_t                        recv_length = 0;
   2563     static uint16_t                 skip_size = 0;
   2564     /* byte address read */
   2565     uint16_t                        copy_till_address = 0;
   2566     uint16_t                        exact_copy_length = 0;
   2567     uint16_t                        actual_ndef_length = 0;
   2568 
   2569 
   2570     recv_length = *(psNdefMap->SendRecvLength);
   2571 
   2572     actual_ndef_length = ps_tpz_info->ActualNDEFMsgSize;
   2573     if (PH_FRINFC_NDEFMAP_SEEK_CUR == psNdefMap->Offset)
   2574     {
   2575         actual_ndef_length = (uint16_t)(
   2576                             ps_tpz_info->RemainingReadSize +
   2577                             psNdefMap->ApduBuffIndex);
   2578     }
   2579 
   2580     exact_copy_length = (uint16_t)((psNdefMap->ApduBufferSize >
   2581                             actual_ndef_length) ? actual_ndef_length :
   2582                             psNdefMap->ApduBufferSize);
   2583 
   2584     if (0 == ps_tpz_info->CurrentSeg)
   2585     {
   2586         /* Skip copying the UID bytes, CC bytes, and lock and reserved memory bytes
   2587              */
   2588         recv_length = (*(psNdefMap->SendRecvLength) - TOPAZ_STATIC_LOCK_RES_BYTES);
   2589     }
   2590 
   2591     if (TOPAZ_SEG_FROM_BYTE_ADR (
   2592         phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (psNdefMap)) ==
   2593         ps_tpz_info->CurrentSeg)
   2594     {
   2595         copy_index = (uint16_t)(copy_index + (
   2596                     phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
   2597                         psNdefMap) % TOPAZ_SEGMENT_READ_LENGTH));
   2598         skip_size = 0;
   2599     }
   2600 
   2601     if (0 != skip_size)
   2602     {
   2603         copy_index = (copy_index + skip_size);
   2604         skip_size = 0;
   2605     }
   2606 
   2607     while (copy_index < recv_length)
   2608     {
   2609         copy_length = (uint16_t)(recv_length - copy_index);
   2610         copy_till_address = 0;
   2611         /* IF MORE THAN ONE TLV EXISTS THEN ADD A WHILE LOOP HERE, AND PLACE THE
   2612             IF STATEMENT INSIDE THE WHILE LOOP. ALSO,
   2613             ps_locktlv_info = &(psNdefMap->LockTlv) change this to
   2614             ps_locktlv_info = &(psNdefMap->LockTlv[index])
   2615             */
   2616         ps_locktlv_info = &(psNdefMap->LockTlv);
   2617         if (
   2618             /* Check the lock bytes belong to this segment */
   2619             (ps_tpz_info->CurrentSeg ==
   2620             (ps_locktlv_info->ByteAddr / TOPAZ_SEGMENT_READ_LENGTH)) &&
   2621             /* Now to check if the copy_index has surpassed the lock byte address */
   2622             (TOPAZ_BYTE_ADR_FROM_SEG(ps_tpz_info->CurrentSeg, copy_index)
   2623             <= ps_locktlv_info->ByteAddr)
   2624             )
   2625         {
   2626             if ((ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_START) ||
   2627                 (ps_locktlv_info->ByteAddr >= (TOPAZ_STATIC_LOCK_RES_END + 8)))
   2628             {
   2629                 copy_till_address = ps_locktlv_info->ByteAddr;
   2630             }
   2631             skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
   2632                                                         ps_locktlv_info->ByteAddr);
   2633         }
   2634 
   2635         /* IF MORE THAN ONE TLV EXISTS THEN ADD A WHILE LOOP HERE, AND PLACE THE
   2636             IF STATEMENT INSIDE THE WHILE LOOP. ALSO,
   2637             ps_memtlv_info = &(psNdefMap->MemTlv) change this to
   2638             ps_memtlv_info = &(psNdefMap->MemTlv[index])
   2639             */
   2640         ps_memtlv_info = &(psNdefMap->MemTlv);
   2641         if (
   2642             /* Check the reserved bytes belong to this segment */
   2643             (ps_tpz_info->CurrentSeg ==
   2644             (ps_memtlv_info->ByteAddr / TOPAZ_SEGMENT_READ_LENGTH)) &&
   2645             /* Now to check if the copy_index has surpassed the reserved byte address */
   2646             (TOPAZ_BYTE_ADR_FROM_SEG(ps_tpz_info->CurrentSeg, copy_index)
   2647             <= ps_memtlv_info->ByteAddr)
   2648             )
   2649         {
   2650             if ((ps_memtlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_START) ||
   2651                 (ps_memtlv_info->ByteAddr >= (TOPAZ_STATIC_LOCK_RES_END + 8)))
   2652             {
   2653                 copy_till_address = (uint16_t)
   2654                             (((ps_memtlv_info->ByteAddr < copy_till_address) ||
   2655                                 (0 == copy_till_address))?
   2656                             ps_memtlv_info->ByteAddr : copy_till_address);
   2657             }
   2658 
   2659             if (copy_till_address == ps_memtlv_info->ByteAddr)
   2660             {
   2661                 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
   2662                                                             ps_memtlv_info->ByteAddr);
   2663             }
   2664         }
   2665 
   2666 
   2667         copy_length = (uint16_t) ((copy_till_address == 0) ? copy_length :
   2668                     ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
   2669                     copy_index));
   2670 
   2671         /* After lock bytes, there are immediate reserved bytes, so " copy_length "
   2672             can be 0 */
   2673         if (0 != copy_length)
   2674         {
   2675             /* If complete user buffer is not filled and the
   2676                 read data is greater than the user data buffer, then get the
   2677                 remaining size that should be copied.
   2678                 The below " if " statement is used for the above scenario */
   2679             if ((copy_length > (uint16_t)
   2680                 (exact_copy_length - psNdefMap->ApduBuffIndex)) &&
   2681                 (exact_copy_length != psNdefMap->ApduBuffIndex))
   2682             {
   2683                 copy_length = (uint16_t)(exact_copy_length -
   2684                                         psNdefMap->ApduBuffIndex);
   2685             }
   2686 
   2687             if (exact_copy_length != psNdefMap->ApduBuffIndex)
   2688             {
   2689                 (void)memcpy ((void *)(psNdefMap->ApduBuffer +
   2690                         psNdefMap->ApduBuffIndex),
   2691                         (void *)(psNdefMap->SendRecvBuf + copy_index),
   2692                         copy_length);
   2693 #if 0
   2694                 if (((copy_till_address == 0) ? copy_length :
   2695                     ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
   2696                     copy_index)) > (uint16_t)
   2697                     (exact_copy_length - psNdefMap->ApduBuffIndex))
   2698                 {
   2699                     /* Copy remaining buffer in the static memory */
   2700                     (void)memcpy ((void *)(ps_tpz_info->ReadBuffer +
   2701                             ps_tpz_info->ReadBufferSize),
   2702                             (void *)(psNdefMap->SendRecvBuf + copy_index),
   2703                             (((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
   2704                             copy_index) - copy_length));
   2705 
   2706                     ps_tpz_info->ReadBufferSize = (uint16_t)(((copy_till_address %
   2707                                                     TOPAZ_SEGMENT_READ_LENGTH) -
   2708                                                     copy_index) - copy_length);
   2709 
   2710                     /* Copy the data in the user buffer */
   2711                     copy_index = (uint16_t)(copy_index +
   2712                                 ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
   2713                                 copy_index));
   2714                 }
   2715                 else
   2716 #endif /* #if 0 */
   2717                 {
   2718                     /* Copy the data in the user buffer */
   2719                     copy_index = (uint16_t)(copy_index + copy_length);
   2720                 }
   2721 
   2722                 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
   2723                                             copy_length);
   2724 
   2725 
   2726             }
   2727             else
   2728             {
   2729                 copy_length = (uint16_t) ((copy_till_address == 0) ? copy_length :
   2730                             ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
   2731                             copy_index));
   2732 
   2733                 /* Actual NDEF message size is greater than the last index copied in
   2734                     the user buffer */
   2735                 if (actual_ndef_length > (psNdefMap->ApduBuffIndex +
   2736                     ps_tpz_info->ReadBufferSize))
   2737                 {
   2738                     /* The statement is correct, check the remaining length */
   2739                     copy_length = ((copy_length > (actual_ndef_length -
   2740                                 psNdefMap->ApduBuffIndex)) ?
   2741                                 (actual_ndef_length -
   2742                                 psNdefMap->ApduBuffIndex) :
   2743                                 copy_length);
   2744 
   2745                     /* Copy remaining buffer in the static memory */
   2746                     (void)memcpy ((void *)(ps_tpz_info->ReadBuffer +
   2747                                 ps_tpz_info->ReadBufferSize),
   2748                                 (void *)(psNdefMap->SendRecvBuf + copy_index),
   2749                                 copy_length);
   2750 
   2751                     ps_tpz_info->ReadBufferSize = (uint8_t)(
   2752                                                     ps_tpz_info->ReadBufferSize +
   2753                                                     copy_length);
   2754                 }
   2755 
   2756                 /* Copy the data in the user buffer */
   2757                 copy_index = (uint16_t)(copy_index + copy_length);
   2758             }
   2759         }
   2760 
   2761         if (copy_index != copy_till_address)
   2762         {
   2763             skip_size = 0;
   2764         }
   2765 
   2766         if ((copy_index + skip_size) <= recv_length)
   2767         {
   2768             copy_index = (uint16_t)(copy_index + skip_size);
   2769             skip_size = 0;
   2770         }
   2771         else
   2772         {
   2773             skip_size = (uint16_t)((skip_size > 0) ?
   2774                                     (recv_length - copy_index) : 0);
   2775             copy_index = (uint16_t)recv_length;
   2776         }
   2777     }
   2778 
   2779     if (exact_copy_length != psNdefMap->ApduBuffIndex)
   2780     {
   2781         ps_tpz_info->CurrentSeg = (uint8_t)
   2782                             (ps_tpz_info->CurrentSeg + 1);
   2783 #ifdef TOPAZ_RAW_SUPPORT
   2784 
   2785         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
   2786 
   2787 #else
   2788 
   2789         psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
   2790 
   2791 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   2792         result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   2793     }
   2794     else
   2795     {
   2796         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
   2797         if (psNdefMap->ApduBuffIndex == actual_ndef_length)
   2798         {
   2799             ps_tpz_info->ReadBufferSize = 0;
   2800             ps_tpz_info->ReadWriteCompleteFlag = TRUE;
   2801         }
   2802         else
   2803         {
   2804             ps_tpz_info->RemainingReadSize = (actual_ndef_length -
   2805                                         psNdefMap->ApduBuffIndex);
   2806         }
   2807     }
   2808     return result;
   2809 }
   2810 
   2811 
   2812 static
   2813 NFCSTATUS
   2814 phFriNfc_Tpz_H_ParseTLVs (
   2815     phFriNfc_NdefMap_t          *psNdefMap)
   2816 {
   2817     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   2818     phFriNfc_TopazCont_t        *ps_tpz_info = &(psNdefMap->TopazContainer);
   2819     uint8_t                     *p_recv_buf = NULL;
   2820     uint16_t                    recv_length = 0;
   2821     uint16_t                    parse_index = 0;
   2822     phFriNfc_Tpz_ParseSeq_t     expected_seq = (phFriNfc_Tpz_ParseSeq_t)
   2823                                 ps_tpz_info->ExpectedSeq;
   2824     uint16_t                    byte_addr = 0;
   2825     /* This variable is kept static because if the size to skip LOCK or RESERVED
   2826     bytes extends to next read then it shall be stored and used to skip the next
   2827     read the bytes
   2828     */
   2829     static uint16_t             skip_size = 0;
   2830     /* This variable is kept static because if the bytes extends from the read segment,
   2831         then the index shall be stored
   2832     This is to store index copied from the
   2833     1. lock memory VALUE field bytes in the LOCK and MEMORY CONTROL TLV.
   2834     2. Also, LENGTH field of the NDEF TLV */
   2835     static uint8_t              lock_mem_ndef_index = 0;
   2836     /* This variable is kept static because if the bytes extends from the read segment,
   2837         then it has to stored
   2838     This is to store the
   2839     1. lock memory VALUE field bytes in the LOCK and MEMORY CONTROL TLV.
   2840     2. Also, LENGTH field of the NDEF TLV */
   2841     static uint8_t              lock_mem_buf[TOPAZ_MEM_LOCK_TLV_LENGTH] = {0};
   2842     /* This is used in case if there is no MAGIC NUMBER found
   2843                         OR
   2844         TYPE field is not found after reading entire card */
   2845     static uint16_t             ndef_tlv_byte_addr = 0;
   2846 
   2847     p_recv_buf = psNdefMap->SendRecvBuf;
   2848     recv_length = *psNdefMap->SendRecvLength;
   2849 
   2850     if (0 == ps_tpz_info->CurrentSeg)
   2851     {
   2852         /* First read, so reset all the static variables */
   2853         lock_mem_ndef_index = 0;
   2854         skip_size = 0;
   2855         ndef_tlv_byte_addr = 0;
   2856 
   2857         /* Skip copying the UID bytes and CC bytes, which is first 12 bytes */
   2858         parse_index = (uint16_t)(TOPAZ_UID_BYTES_LENGTH +
   2859                                 TOPAZ_CC_BYTES_LENGTH);
   2860         /* Delete the lock and reserved memory bytes
   2861             (which are the last 24 bytes in the card) */
   2862         recv_length = (uint16_t)(*(psNdefMap->SendRecvLength) -
   2863                                 TOPAZ_STATIC_LOCK_RES_BYTES);
   2864     }
   2865 
   2866     while ((parse_index < recv_length) && (NFCSTATUS_SUCCESS == result) &&
   2867         (NDEF_V_TLV != expected_seq))
   2868     {
   2869         if (0 == skip_size)
   2870         {
   2871             /* Macro used to get the exact byte address of the card.
   2872                 This is done by using the current segment and the parse index */
   2873             byte_addr = TOPAZ_BYTE_ADR_FROM_SEG (ps_tpz_info->CurrentSeg, parse_index);
   2874             /* Skip size is to skip the lock or memory reserved bytes  */
   2875             skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   2876         }
   2877 
   2878         if (0 != skip_size)
   2879         {
   2880             if ((recv_length - parse_index) >= skip_size)
   2881             {
   2882                 parse_index = (uint16_t)(parse_index + skip_size);
   2883                 skip_size = 0;
   2884             }
   2885             else
   2886             {
   2887                 parse_index = (uint16_t)(parse_index + (recv_length -
   2888                                 parse_index));
   2889                 skip_size = (uint16_t)(skip_size - (recv_length -
   2890                                 parse_index));
   2891             }
   2892         }
   2893         else
   2894         {
   2895             switch (expected_seq)
   2896             {
   2897                 case LOCK_T_TLV:
   2898                 {
   2899                     /* Parse the bytes till TYPE field of LOCK TLV is found, Once the
   2900                         TYPE field is found then change the sequence to LOCK_L_TLV */
   2901                     result = phFriNfc_Tpz_H_ParseLockTLVType (psNdefMap, p_recv_buf,
   2902                                             &parse_index, recv_length, &expected_seq);
   2903 
   2904                     break;
   2905                 }
   2906 
   2907                 case LOCK_L_TLV:
   2908                 {
   2909                     /* Parse the length field of LOCK TLV. Length field value of the
   2910                         LOCK TLV is always 3 */
   2911                     if (TOPAZ_MEM_LOCK_TLV_LENGTH != p_recv_buf[parse_index])
   2912                     {
   2913                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2914                                             NFCSTATUS_NO_NDEF_SUPPORT);
   2915                     }
   2916                     else
   2917                     {
   2918                         parse_index = (uint16_t)(parse_index + 1);
   2919                         expected_seq = LOCK_V_TLV;
   2920                     }
   2921                     break;
   2922                 }
   2923 
   2924                 case LOCK_V_TLV:
   2925                 {
   2926                     /* Parse the VALUE field of the LOCK TLV */
   2927                     lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
   2928                     parse_index = (uint16_t)(parse_index + 1);
   2929                     lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
   2930 
   2931 
   2932                     /* All the 3 bytes are copied in the local buffer */
   2933                     if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
   2934                     {
   2935 #ifdef FRINFC_READONLY_NDEF
   2936                         (void)memcpy ((void *)psNdefMap->LockTlv.LockTlvBuff,
   2937                                 (void *)lock_mem_buf, sizeof (lock_mem_buf));
   2938 #endif /* #ifdef FRINFC_READONLY_NDEF */
   2939                         /* Calculate the byte address and size of the lock bytes */
   2940                         result = phFriNfc_Tpz_H_GetLockBytesInfo (psNdefMap, lock_mem_buf);
   2941                         lock_mem_ndef_index = 0;
   2942                         expected_seq = MEM_T_TLV;
   2943                     }
   2944                     break;
   2945                 }
   2946 
   2947                 case MEM_T_TLV:
   2948                 {
   2949                     /* Parse the bytes till TYPE field of MEMORY TLV is found, Once the
   2950                         TYPE field is found then change the sequence to MEM_L_TLV */
   2951                     result = phFriNfc_Tpz_H_ParseMemTLVType (psNdefMap, p_recv_buf,
   2952                                             &parse_index, recv_length, &expected_seq);
   2953                     break;
   2954                 }
   2955 
   2956                 case MEM_L_TLV:
   2957                 {
   2958                     /* Parse the length field of MEMORY TLV. Length field value of the
   2959                         MEMORY TLV is always 3 */
   2960                     if (TOPAZ_MEM_LOCK_TLV_LENGTH != p_recv_buf[parse_index])
   2961                     {
   2962                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   2963                                             NFCSTATUS_NO_NDEF_SUPPORT);
   2964                     }
   2965                     else
   2966                     {
   2967                         parse_index = (uint16_t)(parse_index + 1);
   2968                         expected_seq = MEM_V_TLV;
   2969                     }
   2970 
   2971                     break;
   2972                 }
   2973 
   2974                 case MEM_V_TLV:
   2975                 {
   2976                     /* Parse the VALUE field of the MEMORY TLV */
   2977                     lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
   2978                     parse_index = (uint16_t)(parse_index + 1);
   2979                     lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
   2980 
   2981                     /* All the 3 bytes are copied in the local buffer */
   2982                     if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
   2983                     {
   2984                         /* Calculate the byte address and size of the lock bytes */
   2985                         ndef_tlv_byte_addr = TOPAZ_BYTE_ADR_FROM_SEG (
   2986                                             ps_tpz_info->CurrentSeg , parse_index);
   2987                         result = phFriNfc_Tpz_H_GetMemBytesInfo (psNdefMap, lock_mem_buf);
   2988                         lock_mem_ndef_index = 0;
   2989                         expected_seq = NDEF_T_TLV;
   2990                     }
   2991 
   2992                     break;
   2993                 }
   2994 
   2995                 case NDEF_T_TLV:
   2996                 {
   2997                     /* Parse the bytes till TYPE field of NDEF TLV is found, Once the
   2998                         TYPE field is found then change the sequence to NDEF_L_TLV */
   2999                     result = phFriNfc_Tpz_H_ParseNdefTLVType (psNdefMap, p_recv_buf,
   3000                                             &parse_index, recv_length, &expected_seq);
   3001 
   3002                     break;
   3003                 }
   3004 
   3005                 case NDEF_L_TLV:
   3006                 {
   3007                     /* Length field of the NDEF TLV */
   3008                     if (0 == lock_mem_ndef_index)
   3009                     {
   3010                         /* This is the 1st time, the loop has entered this case,
   3011                             means that the NDEF byte address has to be updated */
   3012                         ps_tpz_info->NdefTLVByteAddress = (uint16_t)
   3013                                 TOPAZ_BYTE_ADR_FROM_SEG (ps_tpz_info->CurrentSeg,
   3014                                 (parse_index - 1));
   3015                     }
   3016 
   3017                     if (0 != lock_mem_ndef_index)
   3018                     {
   3019                         /* There is already index has been updated, update remaining
   3020                             buffer */
   3021                         lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
   3022                         parse_index = (uint16_t)(parse_index + 1);
   3023                         lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
   3024 
   3025                         if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
   3026                         {
   3027                             lock_mem_ndef_index = 0;
   3028                             ps_tpz_info->ActualNDEFMsgSize = (uint16_t)((lock_mem_buf[1] <<
   3029                                         TOPAZ_BYTE_SHIFT) | lock_mem_buf[2]);
   3030                             expected_seq = NDEF_V_TLV;
   3031                         }
   3032                     }
   3033                     /* Check for remaining size in the card and the actual ndef length */
   3034                     else if (p_recv_buf[parse_index] <=
   3035                             (ps_tpz_info->RemainingSize - (parse_index + 1)))
   3036                     {
   3037                         /* This check is added to see that length field in the TLV is
   3038                             greater than the 1 byte */
   3039                         if (0xFF == p_recv_buf[parse_index])
   3040                         {
   3041                             lock_mem_buf[lock_mem_ndef_index] =
   3042                                                     p_recv_buf[parse_index];
   3043                             lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
   3044                         }
   3045                         else
   3046                         {
   3047                             /* Length field of the TLV is ONE byte, so update the
   3048                             actual ndef size */
   3049                             lock_mem_ndef_index = 0;
   3050                             ps_tpz_info->ActualNDEFMsgSize = (uint16_t)
   3051                                                         p_recv_buf[parse_index];
   3052 
   3053                             expected_seq = NDEF_V_TLV;
   3054                         }
   3055                         parse_index = (uint16_t)(parse_index + 1);
   3056                     }
   3057                     else
   3058                     {
   3059                         /* Wrong length, remaining size in the card is lesser than the actual
   3060                             ndef message length */
   3061                         lock_mem_ndef_index = 0;
   3062                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   3063                                             NFCSTATUS_NO_NDEF_SUPPORT);
   3064                     }
   3065                     break;
   3066                 }
   3067 
   3068                 default:
   3069                 {
   3070                     break;
   3071                 }
   3072             }/* end of switch (expected_seq) */
   3073         } /* end of if (0 != skip_size) */
   3074     } /* while ((parse_index < recv_length) && (NFCSTATUS_SUCCESS != result) &&
   3075         (NDEF_V_TLV != expected_seq)) */
   3076 
   3077     ps_tpz_info->ExpectedSeq = (uint8_t)expected_seq;
   3078 
   3079     if (0 == ps_tpz_info->CurrentSeg)
   3080     {
   3081         /* First segment has the STATIC lock and reserved bytes, so delete it from
   3082             the remaining size */
   3083         ps_tpz_info->RemainingSize = (uint16_t)(ps_tpz_info->RemainingSize -
   3084                                     (parse_index + TOPAZ_STATIC_LOCK_RES_BYTES));
   3085 
   3086     }
   3087     else
   3088     {
   3089         ps_tpz_info->RemainingSize = (uint16_t)(ps_tpz_info->RemainingSize -
   3090                                     parse_index);
   3091     }
   3092 
   3093     if ((NDEF_V_TLV == expected_seq) && (NFCSTATUS_SUCCESS == result))
   3094     {
   3095         /* NDEF TLV found */
   3096         result = phFriNfc_Tpz_H_ActualCardSize (psNdefMap);
   3097 
   3098         if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState) &&
   3099             (0 != ps_tpz_info->ActualNDEFMsgSize))
   3100         {
   3101             /* Check if the card state is READ ONLY or the actual NDEF size is 0
   3102                 if actual NDEF size is 0, then card state is INITIALISED
   3103             */
   3104             psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
   3105         }
   3106     }
   3107 
   3108     if ((NFCSTATUS_SUCCESS == result) && (NDEF_V_TLV != expected_seq))
   3109     {
   3110         ps_tpz_info->CurrentSeg = (uint8_t)(ps_tpz_info->CurrentSeg + 1);
   3111         if (TOPAZ_TOTAL_SEG_TO_READ == ps_tpz_info->CurrentSeg)
   3112         {
   3113             /* Max segment to read reached, so no more read can be done */
   3114             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   3115                                 NFCSTATUS_NO_NDEF_SUPPORT);
   3116         }
   3117         else
   3118         {
   3119 #ifdef TOPAZ_RAW_SUPPORT
   3120 
   3121             *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
   3122 
   3123 #else
   3124 
   3125             psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
   3126 
   3127 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   3128             result = phFriNfc_Tpz_H_NxpRead(psNdefMap);
   3129         }
   3130     }
   3131 
   3132     if ((NFCSTATUS_SUCCESS != result) && (NFCSTATUS_PENDING != result))
   3133     {
   3134         /* Error scenario */
   3135         ps_tpz_info->NdefTLVByteAddress = 0;
   3136         ps_tpz_info->ActualNDEFMsgSize = 0;
   3137     }
   3138 
   3139     if (NFCSTATUS_PENDING != result)
   3140     {
   3141         /* Exit scenario */
   3142         if ((0x00 == *ps_tpz_info->CCByteBuf) ||
   3143             ((NDEF_T_TLV == expected_seq) &&
   3144             (TOPAZ_TOTAL_SEG_TO_READ == ps_tpz_info->CurrentSeg)))
   3145         {
   3146             /* This statement is for getting the new
   3147                 NDEF TLV byte address, because 1st CC byte is corrupted or
   3148                 no NDEF TLV in the card
   3149 
   3150                 If the 1st CC byte (NDEF magic number) in the card is 0, means
   3151                 that previous write has failed, so to write the exact TLV,
   3152                 calculate the byte number
   3153                                             OR
   3154                 The NDEF TLV is not present in the entire card, and the sequence is
   3155                 NDEF_T_TLV (this means, that lock and memory control TLV is found
   3156                 in the card)
   3157                 */
   3158             uint16_t             size_to_skip = 0;
   3159             ps_tpz_info->ActualNDEFMsgSize = 0;
   3160 
   3161             if (0 != ndef_tlv_byte_addr)
   3162             {
   3163                 /* ndef_tlv_byte_addr is updated, only after complete parsing the
   3164                     memory control TLV so the value shall not be 0 */
   3165                 do
   3166                 {
   3167                     /* This loop is added to make sure the lock and reserved bytes are not
   3168                     overwritten */
   3169                     size_to_skip = 0;
   3170                     size_to_skip = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
   3171                                                             ndef_tlv_byte_addr);
   3172 
   3173                     ndef_tlv_byte_addr = (uint16_t)(ndef_tlv_byte_addr +
   3174                                             size_to_skip);
   3175                 }while (0 != size_to_skip);
   3176 
   3177                 /* Update the TLV byte address */
   3178                 ps_tpz_info->NdefTLVByteAddress = ndef_tlv_byte_addr;
   3179 
   3180                 /* Update the remaining size */
   3181                 ps_tpz_info->RemainingSize = (uint16_t)(psNdefMap->CardMemSize +
   3182                                         TOPAZ_UID_BYTES_LENGTH +
   3183                                         TOPAZ_CC_BYTES_LENGTH);
   3184 
   3185                 ps_tpz_info->RemainingSize = (uint16_t)
   3186                                             (ps_tpz_info->RemainingSize -
   3187                                             (ndef_tlv_byte_addr +
   3188                                             TOPAZ_STATIC_LOCK_RES_BYTES));
   3189                 (void)phFriNfc_Tpz_H_ActualCardSize (psNdefMap);
   3190 
   3191                 /* Length byte is subtracted here to get the actual NDEF
   3192                     read and write size */
   3193                 ps_tpz_info->NDEFRWSize = (uint16_t)
   3194                                         (ps_tpz_info->NDEFRWSize - 2);
   3195                 ndef_tlv_byte_addr = 0;
   3196                 result = NFCSTATUS_SUCCESS;
   3197             }
   3198         }
   3199     }
   3200 
   3201     return result;
   3202 }
   3203 
   3204 static
   3205 NFCSTATUS
   3206 phFriNfc_Tpz_H_CopyReadDataAndWrite (
   3207     phFriNfc_NdefMap_t          *psNdefMap)
   3208 {
   3209     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   3210     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   3211     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
   3212     uint16_t                            write_index = 0;
   3213     uint16_t                            write_len = 0;
   3214     uint16_t                            byte_addr = 0;
   3215     static uint16_t                     skip_size = 0;
   3216 
   3217     ps_tpz_info = &(psNdefMap->TopazContainer);
   3218 
   3219     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
   3220                         psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
   3221 
   3222     (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf,
   3223                     TOPAZ_WRITE_8_DATA_LENGTH);
   3224 
   3225     if (ps_tpz_info->CurrentBlock == TOPAZ_BLK_FROM_BYTE_ADR (
   3226         phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (psNdefMap, write_len)))
   3227     {
   3228         skip_size = 0;
   3229     }
   3230 
   3231     /* Byte Number != 0 menas that the VALUE field of the TLV is in between the
   3232         block, so the first few bytes shall be copied and then user data has to
   3233         be copied
   3234         */
   3235     if (0 != ps_tpz_info->ByteNumber)
   3236     {
   3237         write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);
   3238     }
   3239 
   3240 
   3241     if (0 != skip_size)
   3242     {
   3243         write_index = (uint16_t)(write_index + skip_size);
   3244     }
   3245 
   3246     while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) &&
   3247         (write_len != psNdefMap->ApduBuffIndex))
   3248     {
   3249         skip_size = 0;
   3250         byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
   3251                                             ps_tpz_info->ByteNumber);
   3252         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   3253 
   3254         if (0 == skip_size)
   3255         {
   3256             write_buf[write_index] =
   3257                         psNdefMap->ApduBuffer[psNdefMap->ApduBuffIndex];
   3258 
   3259             write_index = (uint16_t)(write_index + 1);
   3260             psNdefMap->ApduBuffIndex = (uint16_t)
   3261                                         (psNdefMap->ApduBuffIndex + 1);
   3262             ps_tpz_info->ByteNumber = (uint8_t)
   3263                                         (ps_tpz_info->ByteNumber + 1);
   3264         }
   3265         else
   3266         {
   3267 
   3268             if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
   3269             {
   3270                 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
   3271                             - write_index));
   3272                 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
   3273             }
   3274             else
   3275             {
   3276                 ps_tpz_info->ByteNumber = (uint8_t)
   3277                             (ps_tpz_info->ByteNumber + skip_size);
   3278                 write_index = (uint16_t)(write_index + skip_size);
   3279                 skip_size = 0;
   3280             }
   3281         }
   3282     }
   3283 
   3284     if (psNdefMap->ApduBuffIndex == write_len)
   3285     {
   3286         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
   3287     }
   3288     else
   3289     {
   3290         if (0 != skip_size)
   3291         {
   3292             ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
   3293 
   3294         }
   3295         else
   3296         {
   3297             ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
   3298         }
   3299     }
   3300 
   3301 #ifdef TOPAZ_RAW_SUPPORT
   3302     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
   3303 #else
   3304     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
   3305 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   3306     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
   3307                                             sizeof (write_buf));
   3308 
   3309     return result;
   3310 
   3311 }
   3312 
   3313 static
   3314 NFCSTATUS
   3315 phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (
   3316     phFriNfc_NdefMap_t          *psNdefMap)
   3317 {
   3318     /* This function is called, only when the LENGTH field has to be updated
   3319         with the correct value */
   3320     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   3321     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   3322     uint16_t                            write_len = 0;
   3323     uint16_t                            write_index = 0;
   3324     uint16_t                            byte_addr = 0;
   3325     phFriNfc_Tpz_WrSeq_t                write_seq;
   3326     /* This variable is kept static because if the size to skip LOCK or RESERVED
   3327     bytes extends to next read then it shall be stored and used to skip the next
   3328     read the bytes
   3329     */
   3330     static uint16_t                     skip_size = 0;
   3331     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
   3332     uint8_t                             exit_while = FALSE;
   3333 
   3334     ps_tpz_info = &(psNdefMap->TopazContainer);
   3335     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
   3336                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
   3337 
   3338     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
   3339 
   3340     (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf,
   3341                     TOPAZ_WRITE_8_DATA_LENGTH);
   3342 
   3343     write_seq = (phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq;
   3344 
   3345     if (WR_LEN_1_VALUE == write_seq)
   3346     {
   3347         /* First LENGTH field is geting updated, so the skip size
   3348             reset is done */
   3349         skip_size = 0;
   3350     }
   3351 
   3352     if (0 != ps_tpz_info->ByteNumber)
   3353     {
   3354         /* Byte Number is not 0, means that some data shall not be overwriteen till
   3355             that position in the block */
   3356         write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);
   3357     }
   3358 
   3359     if (0 != skip_size)
   3360     {
   3361         /* This is possible after updating the FIRST length field
   3362             skip size is skipped because of the pending LOCK or
   3363             RESERVED bytes
   3364         */
   3365         write_index = (uint16_t)(write_index + skip_size);
   3366     }
   3367 
   3368     while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) &&
   3369         (FALSE == exit_while))
   3370     {
   3371         skip_size = 0;
   3372         /* Get the exact byte address from the block number and
   3373             byte number */
   3374         byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
   3375                                             ps_tpz_info->ByteNumber);
   3376         /* Get the skip size */
   3377         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   3378 
   3379         if (0 == skip_size)
   3380         {
   3381             switch (write_seq)
   3382             {
   3383                 case WR_LEN_1_VALUE:
   3384                 {
   3385                     /* First sequenc is always to update 1st LENGTH field of the TLV */
   3386                     if (write_len < 0xFF)
   3387                     {
   3388                         /* This means the LENGTH field is only one BYTE */
   3389                         write_buf[write_index] = (uint8_t)
   3390                                         psNdefMap->ApduBuffIndex;
   3391                         /* Exit the loop */
   3392                         exit_while = TRUE;
   3393                     }
   3394                     else
   3395                     {
   3396                         /* Update the 1st LENGTH field */
   3397                         write_buf[write_index] = (uint8_t)0xFF;
   3398                     }
   3399                     break;
   3400                 }
   3401 
   3402                 case WR_LEN_2_VALUE:
   3403                 {
   3404                     /* Update the 2nd LENGTH field */
   3405                     write_buf[write_index] = (uint8_t)
   3406                                 (psNdefMap->ApduBuffIndex >> BYTE_SIZE);
   3407                     break;
   3408                 }
   3409 
   3410                 case WR_LEN_3_VALUE:
   3411                 {
   3412                     /* Update the 3rd LENGTH field */
   3413                     write_buf[write_index] = (uint8_t)
   3414                                 (psNdefMap->ApduBuffIndex &
   3415                                 TOPAZ_BYTE_LENGTH_MASK);
   3416                     /* Exit the loop */
   3417                     exit_while = TRUE;
   3418                     break;
   3419                 }
   3420 
   3421                 default:
   3422                 {
   3423                     /* Invalid case */
   3424                     break;
   3425                 }
   3426             }
   3427             write_index = (uint16_t)(write_index + 1);
   3428             if (
   3429                 /* As the write is done for 8 bytes, the write index cant
   3430                     go for more than or equal to 8 bytes, if it reaches 8 bytes
   3431                     then sequence shall not be incrmented */
   3432                 (TOPAZ_WRITE_8_DATA_LENGTH != write_index) &&
   3433                 /* If the last length field byte is updated then the
   3434                     write sequence shall not be incremented */
   3435                 (WR_LEN_3_VALUE != write_seq) &&
   3436                 /* Check added if the write length is less than 0xFF.
   3437                     If length is less than 0xFF, then write sequence
   3438                     shall not be incremented */
   3439                 (write_len >= 0xFF)
   3440                 )
   3441             {
   3442                 /* Sequence is incremented to the next level */
   3443                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
   3444             }
   3445             /* Byte number is incremented */
   3446             ps_tpz_info->ByteNumber = (uint8_t)
   3447                             (ps_tpz_info->ByteNumber + 1);
   3448         }
   3449         else
   3450         {
   3451 
   3452             if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
   3453             {
   3454                 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
   3455                             - write_index));
   3456                 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
   3457             }
   3458             else
   3459             {
   3460                 ps_tpz_info->ByteNumber = (uint8_t)
   3461                             (ps_tpz_info->ByteNumber + skip_size);
   3462                 write_index = (uint16_t)(write_index + skip_size);
   3463                 skip_size = 0;
   3464             }
   3465 
   3466         }
   3467     }
   3468 
   3469     ps_tpz_info->WriteSeq = (uint8_t)write_seq;
   3470 
   3471 #ifdef TOPAZ_RAW_SUPPORT
   3472     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
   3473 #else
   3474     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
   3475 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   3476 
   3477     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
   3478                                             sizeof (write_buf));
   3479     return result;
   3480 }
   3481 
   3482 
   3483 
   3484 static
   3485 NFCSTATUS
   3486 phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (
   3487     phFriNfc_NdefMap_t          *psNdefMap)
   3488 {
   3489     /* This function is called, only when the LENGTH field has to be updated
   3490         with the 0 */
   3491     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   3492     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   3493     uint16_t                            write_len = 0;
   3494     uint16_t                            write_index = 0;
   3495     uint16_t                            prev_apdu_index = 0;
   3496     uint16_t                            byte_addr = 0;
   3497     phFriNfc_Tpz_WrSeq_t                write_seq;
   3498     /* This variable is kept static because if the size to skip LOCK or RESERVED
   3499         bytes extends to next read then it shall be stored and used to skip the next
   3500         read bytes
   3501     */
   3502     static uint16_t                     skip_size = 0;
   3503     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
   3504 
   3505     ps_tpz_info = &(psNdefMap->TopazContainer);
   3506     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
   3507                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
   3508 
   3509     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
   3510 
   3511     (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf,
   3512                     TOPAZ_WRITE_8_DATA_LENGTH);
   3513 
   3514     prev_apdu_index = psNdefMap->ApduBuffIndex;
   3515     write_seq = (phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq;
   3516 
   3517     if (WR_LEN_1_0 == write_seq)
   3518     {
   3519          /* First LENGTH field is geting updated, so the skip size
   3520             reset is done */
   3521         skip_size = 0;
   3522     }
   3523 
   3524     if (0 != ps_tpz_info->ByteNumber)
   3525     {
   3526         /* Byte Number is not 0, means that some data shall not be overwriteen till
   3527             that position in the block */
   3528         write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);
   3529         ps_tpz_info->ByteNumber = 0;
   3530     }
   3531 
   3532     if (0 != skip_size)
   3533     {
   3534         /* This is possible after updating the FIRST length field
   3535             skip size is skipped because of the pending LOCK or
   3536             RESERVED bytes
   3537         */
   3538         write_index = (uint16_t)(write_index + skip_size);
   3539     }
   3540 
   3541     while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) &&
   3542         (write_len != psNdefMap->ApduBuffIndex))
   3543     {
   3544         skip_size = 0;
   3545         byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
   3546                                             ps_tpz_info->ByteNumber);
   3547         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
   3548 
   3549         if (0 == skip_size)
   3550         {
   3551             switch (write_seq)
   3552             {
   3553                 case WR_LEN_1_0:
   3554                 {
   3555                     /* First sequence is always to update 1st LENGTH field
   3556                         of the TLV */
   3557                     write_buf[write_index] = 0x00;
   3558                     write_index = (uint16_t)(write_index + 1);
   3559                     if (write_len < 0xFF)
   3560                     {
   3561                         /* LENGTH field is only 1 byte, so update change the sequence to
   3562                             update user data */
   3563                         write_seq = WR_DATA;
   3564                     }
   3565                     else
   3566                     {
   3567                         /* Go to the next LENGTH field to update */
   3568                         write_seq = (phFriNfc_Tpz_WrSeq_t)((TOPAZ_WRITE_8_DATA_LENGTH !=
   3569                                     write_index) ?
   3570                                     (write_seq + 1) : write_seq);
   3571                     }
   3572                     break;
   3573                 }
   3574 
   3575                 case WR_LEN_2_0:
   3576                 case WR_LEN_3_0:
   3577                 {
   3578                     /* Update 2nd and 3rd LEGNTH field */
   3579                     write_buf[write_index] = 0x00;
   3580                     write_index = (uint16_t)(write_index + 1);
   3581                     write_seq = (phFriNfc_Tpz_WrSeq_t)((TOPAZ_WRITE_8_DATA_LENGTH !=
   3582                                 write_index) ?
   3583                                 (write_seq + 1) : write_seq);
   3584                     break;
   3585                 }
   3586 
   3587                 case WR_DATA:
   3588                 default:
   3589                 {
   3590                     /* Update the buffer by the user data */
   3591                     write_buf[write_index] =
   3592                             psNdefMap->ApduBuffer[psNdefMap->ApduBuffIndex];
   3593 
   3594                     write_index = (uint16_t)(write_index + 1);
   3595                     psNdefMap->ApduBuffIndex = (uint16_t)
   3596                                         (psNdefMap->ApduBuffIndex + 1);
   3597                     break;
   3598                 }
   3599 
   3600             }
   3601 
   3602             ps_tpz_info->ByteNumber = (uint8_t)
   3603                             (ps_tpz_info->ByteNumber + 1);
   3604         }
   3605         else
   3606         {
   3607             /* LOCK and MEMORY bytes are found */
   3608             if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
   3609             {
   3610                 /* skip size has exceeded the block number, so calculate the
   3611                 remaining skip size  */
   3612                 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
   3613                             - write_index));
   3614                 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
   3615             }
   3616             else
   3617             {
   3618                 /* skip the LOCK and MEMORY bytes size */
   3619                 ps_tpz_info->ByteNumber = (uint8_t)
   3620                             (ps_tpz_info->ByteNumber + skip_size);
   3621                 write_index = (uint16_t)(write_index + skip_size);
   3622                 skip_size = 0;
   3623             }
   3624         }
   3625     }
   3626 
   3627     if (psNdefMap->ApduBuffIndex == write_len)
   3628     {
   3629         /* User data has been completely copied and it is ready to write, so
   3630             change the sequence */
   3631         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
   3632     }
   3633     else if ((WR_DATA == write_seq) && (prev_apdu_index ==
   3634         psNdefMap->ApduBuffIndex))
   3635     {
   3636         /* The user data has not been written, only the LENGTH field is
   3637             updated */
   3638         ps_tpz_info->WriteSeq = (uint8_t)((write_len < 0xFF) ?
   3639                                 WR_LEN_1_0 : WR_LEN_3_0);
   3640     }
   3641     else
   3642     {
   3643         /*  Update the sequence in the context */
   3644         ps_tpz_info->WriteSeq = (uint8_t)write_seq;
   3645     }
   3646 
   3647     ps_tpz_info->ByteNumber = 0;
   3648 
   3649 #ifdef TOPAZ_RAW_SUPPORT
   3650     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
   3651 #else
   3652     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
   3653 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   3654 
   3655     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
   3656                                             sizeof (write_buf));
   3657     return result;
   3658 }
   3659 
   3660 static
   3661 NFCSTATUS
   3662 phFriNfc_Tpz_H_RdForWrite (
   3663     phFriNfc_NdefMap_t          *psNdefMap)
   3664 {
   3665     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   3666     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   3667     phFriNfc_Tpz_WrSeq_t                write_seq;
   3668     uint16_t                            byte_addr = 0;
   3669     uint8_t                             exit_while = FALSE;
   3670     uint16_t                            skip_size = 0;
   3671 
   3672     ps_tpz_info = &(psNdefMap->TopazContainer);
   3673     write_seq = (phFriNfc_Tpz_WrSeq_t)(ps_tpz_info->WriteSeq);
   3674 
   3675 #ifdef TOPAZ_RAW_SUPPORT
   3676 
   3677     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
   3678 
   3679 #else
   3680 
   3681     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
   3682 
   3683 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   3684 
   3685     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF;
   3686 
   3687     switch (write_seq)
   3688     {
   3689         case WR_LEN_1_0:
   3690         case WR_LEN_1_VALUE:
   3691         {
   3692             byte_addr = (ps_tpz_info->NdefTLVByteAddress + 1);
   3693 
   3694             /* This loop is to skip the lock amd reserved bytes */
   3695             while (FALSE == exit_while)
   3696             {
   3697                 if (TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO ==
   3698                     TOPAZ_BLK_FROM_BYTE_ADR (byte_addr))
   3699                 {
   3700                     byte_addr = (uint16_t)(byte_addr +
   3701                                 TOPAZ_STATIC_LOCK_RES_BYTES);
   3702                 }
   3703                 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
   3704                                                             byte_addr);
   3705                 if (0 != skip_size)
   3706                 {
   3707                     byte_addr = (uint16_t)(byte_addr + skip_size);
   3708 
   3709 
   3710                 }
   3711                 else
   3712                 {
   3713                     exit_while = TRUE;
   3714                 }
   3715             }
   3716             break;
   3717         }
   3718 
   3719         case WR_LEN_2_0:
   3720         case WR_LEN_3_0:
   3721         case WR_LEN_2_VALUE:
   3722         case WR_LEN_3_VALUE:
   3723         {
   3724             byte_addr = (uint16_t)TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
   3725                                                     ps_tpz_info->ByteNumber);
   3726             /* This loop is for to skip the lock amd reserved bytes */
   3727             while (FALSE == exit_while)
   3728             {
   3729                 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
   3730                                                             byte_addr);
   3731                 if (0 != skip_size)
   3732                 {
   3733                     byte_addr = (uint16_t)(byte_addr + skip_size);
   3734                 }
   3735                 else
   3736                 {
   3737                     exit_while = TRUE;
   3738                 }
   3739             }
   3740             break;
   3741         }
   3742 
   3743         case WR_DATA_READ_REQD:
   3744         {
   3745             /* Lock or reserved bytes found bytes */
   3746             byte_addr = (uint16_t)TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
   3747                                                     ps_tpz_info->ByteNumber);
   3748             break;
   3749         }
   3750 
   3751         default:
   3752         {
   3753             break;
   3754         }
   3755     }
   3756 
   3757     ps_tpz_info->CurrentBlock = (uint8_t)
   3758                         TOPAZ_BLK_FROM_BYTE_ADR (byte_addr);
   3759     ps_tpz_info->ByteNumber = (uint8_t)
   3760                         TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (byte_addr);
   3761 
   3762     result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
   3763 
   3764     return result;
   3765 }
   3766 
   3767 static
   3768 uint16_t
   3769 phFriNfc_Tpz_H_CompareLockBlocks (
   3770     phFriNfc_NdefMap_t          *psNdefMap,
   3771     uint8_t                     block_no,
   3772     uint16_t                    *p_skip_size)
   3773 {
   3774     uint16_t                            return_addr = 0;
   3775     phFriNfc_LockCntrlTLVCont_t         *ps_locktlv_info = NULL;
   3776 
   3777     ps_locktlv_info = &(psNdefMap->LockTlv);
   3778 
   3779     if (block_no == ps_locktlv_info->BlkNum)
   3780     {
   3781         /* ps_tpz_info->ByteNumber = (uint8_t)ps_locktlv_info->ByteNum; */
   3782         *p_skip_size = ps_locktlv_info->Size;
   3783         return_addr = ps_locktlv_info->ByteAddr;
   3784     }
   3785 
   3786     return return_addr;
   3787 }
   3788 
   3789 static
   3790 uint16_t
   3791 phFriNfc_Tpz_H_CompareMemBlocks (
   3792     phFriNfc_NdefMap_t          *psNdefMap,
   3793     uint8_t                     block_no,
   3794     uint16_t                    *p_skip_size)
   3795 {
   3796     uint16_t                            return_addr = 0;
   3797     phFriNfc_ResMemCntrlTLVCont_t       *ps_memtlv_info = NULL;
   3798 
   3799     ps_memtlv_info = &(psNdefMap->MemTlv);
   3800 
   3801     if (block_no == ps_memtlv_info->BlkNum)
   3802     {
   3803         /* ps_tpz_info->ByteNumber = (uint8_t)ps_memtlv_info->ByteNum; */
   3804         *p_skip_size = ps_memtlv_info->Size;
   3805         return_addr = ps_memtlv_info->ByteAddr;
   3806     }
   3807 
   3808     return return_addr;
   3809 }
   3810 
   3811 
   3812 static
   3813 NFCSTATUS
   3814 phFriNfc_Tpz_H_CopySendWrData (
   3815     phFriNfc_NdefMap_t          *psNdefMap)
   3816 {
   3817     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   3818     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   3819     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
   3820     uint16_t                            write_len;
   3821     uint8_t                             copy_length;
   3822     uint16_t                            skip_size = 0;
   3823 
   3824     ps_tpz_info = &(psNdefMap->TopazContainer);
   3825     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
   3826                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
   3827 
   3828     if (0 != phFriNfc_Tpz_H_CompareLockBlocks (psNdefMap,
   3829                 ps_tpz_info->CurrentBlock, &skip_size))
   3830     {
   3831         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
   3832         ps_tpz_info->ByteNumber = 0;
   3833         result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   3834     }
   3835     else if (0 != phFriNfc_Tpz_H_CompareMemBlocks (psNdefMap,
   3836                 ps_tpz_info->CurrentBlock, &skip_size))
   3837     {
   3838         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
   3839         ps_tpz_info->ByteNumber = 0;
   3840         result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
   3841     }
   3842     else
   3843     {
   3844 #ifdef TOPAZ_RAW_SUPPORT
   3845         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
   3846 #else
   3847         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
   3848 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   3849         psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
   3850 
   3851         if ((write_len - psNdefMap->ApduBuffIndex) >= (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH)
   3852         {
   3853             copy_length = (uint8_t)TOPAZ_WRITE_8_DATA_LENGTH;
   3854             (void)memcpy ((void *)write_buf,
   3855                     (void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
   3856                     copy_length);
   3857 
   3858             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
   3859                                         copy_length);
   3860         }
   3861         else
   3862         {
   3863             copy_length = (uint8_t)(write_len - psNdefMap->ApduBuffIndex);
   3864 
   3865             (void)memcpy ((void *)write_buf,
   3866                     (void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
   3867                     TOPAZ_WRITE_8_DATA_LENGTH);
   3868 
   3869             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
   3870                                         copy_length);
   3871 
   3872             (void)memset ((void *)(write_buf + copy_length), 0x00,
   3873                         (TOPAZ_WRITE_8_DATA_LENGTH - copy_length));
   3874         }
   3875 
   3876 #ifdef TOPAZ_RAW_SUPPORT
   3877         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
   3878 #else
   3879         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
   3880 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
   3881 
   3882         result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
   3883                                             sizeof (write_buf));
   3884     }
   3885 
   3886 
   3887     return result;
   3888 }
   3889 
   3890 
   3891 static
   3892 NFCSTATUS
   3893 phFriNfc_Tpz_H_ActualCardSize (
   3894     phFriNfc_NdefMap_t          *psNdefMap)
   3895 {
   3896     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
   3897     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
   3898     phFriNfc_LockCntrlTLVCont_t         *ps_locktlv_info = NULL;
   3899     phFriNfc_ResMemCntrlTLVCont_t       *ps_memtlv_info = NULL;
   3900     uint16_t                            ndef_value_byte_addr = 0;
   3901     uint16_t                            ndef_read_write_size = 0;
   3902 
   3903     ps_tpz_info = &(psNdefMap->TopazContainer);
   3904     if (ps_tpz_info->ActualNDEFMsgSize > ps_tpz_info->RemainingSize)
   3905     {
   3906         ps_tpz_info->ActualNDEFMsgSize = 0;
   3907         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   3908                             NFCSTATUS_NO_NDEF_SUPPORT);
   3909     }
   3910     else
   3911     {
   3912         ndef_read_write_size = ps_tpz_info->RemainingSize;
   3913         ndef_value_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead
   3914                                 (psNdefMap);
   3915 
   3916         ps_locktlv_info = &(psNdefMap->LockTlv);
   3917         if (ps_locktlv_info->ByteAddr > ndef_value_byte_addr)
   3918         {
   3919             ndef_read_write_size = (ndef_read_write_size -
   3920                                     ps_locktlv_info->Size);
   3921         }
   3922 
   3923         ps_memtlv_info = &(psNdefMap->MemTlv);
   3924         if (ps_memtlv_info->ByteAddr > ndef_value_byte_addr)
   3925         {
   3926             ndef_read_write_size = (ndef_read_write_size -
   3927                                     ps_memtlv_info->Size);
   3928         }
   3929 
   3930         if (ps_tpz_info->ActualNDEFMsgSize > ndef_read_write_size)
   3931         {
   3932             ps_tpz_info->ActualNDEFMsgSize = 0;
   3933             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   3934                                 NFCSTATUS_NO_NDEF_SUPPORT);
   3935         }
   3936         else
   3937         {
   3938             ps_tpz_info->NDEFRWSize = (uint16_t)
   3939                             ((ps_tpz_info->ActualNDEFMsgSize < 0xFF) ?
   3940                             (ndef_read_write_size - 2) :
   3941                             ndef_read_write_size);
   3942         }
   3943     }
   3944 
   3945     return result;
   3946 }
   3947 
   3948 static
   3949 NFCSTATUS
   3950 phFriNfc_Tpz_H_ParseLockTLVType (
   3951     phFriNfc_NdefMap_t          *psNdefMap,
   3952     uint8_t                     *p_parse_data,
   3953     uint16_t                    *p_parse_index,
   3954     uint16_t                    total_len_to_parse,
   3955     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute)
   3956 {
   3957     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   3958     uint16_t                    parse_index = *p_parse_index;
   3959     phFriNfc_Tpz_ParseSeq_t     expected_seq = *seq_to_execute;
   3960 
   3961     PHNFC_UNUSED_VARIABLE(psNdefMap);
   3962     PHNFC_UNUSED_VARIABLE(total_len_to_parse);
   3963 
   3964     switch (p_parse_data[parse_index])
   3965     {
   3966         case PH_FRINFC_TOPAZ_LOCK_CTRL_T:
   3967         {
   3968             expected_seq = LOCK_L_TLV;
   3969             parse_index = (parse_index + 1);
   3970             break;
   3971         }
   3972 
   3973         case PH_FRINFC_TOPAZ_NULL_T:
   3974         {
   3975             expected_seq = LOCK_T_TLV;
   3976             parse_index = (parse_index + 1);
   3977             break;
   3978         }
   3979 
   3980         default:
   3981         {
   3982             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   3983                                 NFCSTATUS_NO_NDEF_SUPPORT);
   3984             break;
   3985         }
   3986     }
   3987 
   3988 
   3989     *seq_to_execute = expected_seq;
   3990     *p_parse_index = parse_index;
   3991     return result;
   3992 }
   3993 
   3994 static
   3995 NFCSTATUS
   3996 phFriNfc_Tpz_H_ParseMemTLVType (
   3997     phFriNfc_NdefMap_t          *psNdefMap,
   3998     uint8_t                     *p_parse_data,
   3999     uint16_t                    *p_parse_index,
   4000     uint16_t                    total_len_to_parse,
   4001     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute)
   4002 {
   4003     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   4004     uint16_t                    parse_index = *p_parse_index;
   4005     phFriNfc_Tpz_ParseSeq_t     expected_seq = *seq_to_execute;
   4006 
   4007     PHNFC_UNUSED_VARIABLE(psNdefMap);
   4008     PHNFC_UNUSED_VARIABLE(total_len_to_parse);
   4009 
   4010     switch (p_parse_data[parse_index])
   4011     {
   4012         case PH_FRINFC_TOPAZ_LOCK_CTRL_T:
   4013         {
   4014             expected_seq = LOCK_L_TLV;
   4015             parse_index = (parse_index + 1);
   4016             break;
   4017         }
   4018 
   4019         case PH_FRINFC_TOPAZ_NULL_T:
   4020         {
   4021             expected_seq = MEM_T_TLV;
   4022             parse_index = (parse_index + 1);
   4023             break;
   4024         }
   4025 
   4026         case PH_FRINFC_TOPAZ_MEM_CTRL_T:
   4027         {
   4028             expected_seq = MEM_L_TLV;
   4029             parse_index = (parse_index + 1);
   4030             break;
   4031         }
   4032 
   4033         default:
   4034         {
   4035             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   4036                                 NFCSTATUS_NO_NDEF_SUPPORT);
   4037             break;
   4038         }
   4039     }
   4040 
   4041     *seq_to_execute = expected_seq;
   4042     *p_parse_index = parse_index;
   4043     return result;
   4044 }
   4045 
   4046 static
   4047 NFCSTATUS
   4048 phFriNfc_Tpz_H_ParseNdefTLVType (
   4049     phFriNfc_NdefMap_t          *psNdefMap,
   4050     uint8_t                     *p_parse_data,
   4051     uint16_t                    *p_parse_index,
   4052     uint16_t                    total_len_to_parse,
   4053     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute)
   4054 {
   4055     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   4056     uint16_t                    parse_index = *p_parse_index;
   4057     phFriNfc_Tpz_ParseSeq_t     expected_seq = *seq_to_execute;
   4058 
   4059     PHNFC_UNUSED_VARIABLE(psNdefMap);
   4060     PHNFC_UNUSED_VARIABLE(total_len_to_parse);
   4061 
   4062     switch (p_parse_data[parse_index])
   4063     {
   4064         case PH_FRINFC_TOPAZ_MEM_CTRL_T:
   4065         {
   4066             /* TYPE field of Memory control TLV is found.
   4067                 This means that more than one memory control
   4068                 TLV exists */
   4069             expected_seq = MEM_L_TLV;
   4070             parse_index = (parse_index + 1);
   4071             break;
   4072         }
   4073 
   4074         case PH_FRINFC_TOPAZ_NULL_T:
   4075         {
   4076             /* Skip the NULL TLV */
   4077             expected_seq = NDEF_T_TLV;
   4078             parse_index = (parse_index + 1);
   4079             break;
   4080         }
   4081 
   4082         case PH_FRINFC_TOPAZ_NDEF_T:
   4083         {
   4084             /* TYPE field of NDEF TLV found, so next expected
   4085                 sequence is LENGTH field */
   4086             expected_seq = NDEF_L_TLV;
   4087             parse_index = (parse_index + 1);
   4088             break;
   4089         }
   4090 
   4091         default:
   4092         {
   4093             /* Reset the sequence */
   4094             expected_seq = LOCK_T_TLV;
   4095             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   4096                                 NFCSTATUS_NO_NDEF_SUPPORT);
   4097             break;
   4098         }
   4099     }
   4100 
   4101     *seq_to_execute = expected_seq;
   4102     *p_parse_index = parse_index;
   4103     return result;
   4104 }
   4105 
   4106 static
   4107 uint16_t
   4108 phFriNfc_Tpz_H_GetSkipSize (
   4109     phFriNfc_NdefMap_t          *psNdefMap,
   4110     uint16_t                    byte_adr_card)
   4111 {
   4112     uint16_t                        return_size = 0;
   4113     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
   4114     phFriNfc_ResMemCntrlTLVCont_t   *ps_memtlv_info = NULL;
   4115 
   4116     ps_locktlv_info = &(psNdefMap->LockTlv);
   4117     ps_memtlv_info = &(psNdefMap->MemTlv);
   4118 
   4119     /* If there are more than one LOCK CONTROL TLV, then
   4120     ADD A LOOP HERE OF THE NUMBER OF TLVs FOUND */
   4121     if (byte_adr_card == ps_locktlv_info->ByteAddr)
   4122     {
   4123         return_size = ps_locktlv_info->Size;
   4124     }
   4125 
   4126     /* If there are more than one MEMORY CONTROL TLV, then
   4127         ADD A LOOP HERE OF THE NUMBER OF TLVs FOUND */
   4128     if (byte_adr_card == ps_memtlv_info->ByteAddr)
   4129     {
   4130         return_size = ps_memtlv_info->Size;
   4131     }
   4132     return return_size;
   4133 }
   4134 
   4135 static
   4136 NFCSTATUS
   4137 phFriNfc_Tpz_H_GetLockBytesInfo (
   4138     phFriNfc_NdefMap_t          *psNdefMap,
   4139     uint8_t                     *p_lock_info)
   4140 {
   4141     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
   4142     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
   4143     uint8_t                         page_address = 0;
   4144     uint8_t                         bytes_offset = 0;
   4145     uint8_t                         lock_index = 0;
   4146 
   4147     ps_locktlv_info = &(psNdefMap->LockTlv);
   4148 
   4149     page_address = (uint8_t)(p_lock_info[lock_index] >> NIBBLE_SIZE);
   4150     bytes_offset = (uint8_t)(p_lock_info[lock_index] & TOPAZ_NIBBLE_MASK);
   4151 
   4152     lock_index = (lock_index + 1);
   4153     ps_locktlv_info->Size = (uint16_t)
   4154                             (((p_lock_info[lock_index] % TOPAZ_BYTE_SIZE_IN_BITS) > 0)?
   4155                             ((p_lock_info[lock_index] / TOPAZ_BYTE_SIZE_IN_BITS) + 1) :
   4156                             (p_lock_info[lock_index] / TOPAZ_BYTE_SIZE_IN_BITS));
   4157 
   4158     lock_index = (lock_index + 1);
   4159     ps_locktlv_info->BytesPerPage =
   4160                             (p_lock_info[lock_index] & TOPAZ_NIBBLE_MASK);
   4161     ps_locktlv_info->BytesLockedPerLockBit =
   4162                             (p_lock_info[lock_index] >> NIBBLE_SIZE);
   4163 
   4164     /* Apply the formula to calculate byte address
   4165         ByteAddr = PageAddr*2^BytesPerPage + ByteOffset
   4166     */
   4167     ps_locktlv_info->ByteAddr = (uint16_t)((page_address
   4168                                 * (1 << ps_locktlv_info->BytesPerPage))
   4169                                 + bytes_offset);
   4170 
   4171 
   4172     if (
   4173         /* Out of bound memory check */
   4174         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) >
   4175         (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] *
   4176         TOPAZ_BYTES_PER_BLOCK)) ||
   4177 
   4178         /* Check the static lock and reserved areas memory blocks */
   4179         ((ps_locktlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) &&
   4180         (ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) ||
   4181         (((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) >=
   4182         TOPAZ_STATIC_LOCK_RES_START) &&
   4183         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) <
   4184         TOPAZ_STATIC_LOCK_RES_END))
   4185         )
   4186     {
   4187         ps_locktlv_info->ByteAddr = 0;
   4188         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   4189                             NFCSTATUS_NO_NDEF_SUPPORT);
   4190     }
   4191     else
   4192     {
   4193         ps_locktlv_info->BlkNum = (ps_locktlv_info->ByteAddr /
   4194                                     TOPAZ_BYTES_PER_BLOCK);
   4195         ps_locktlv_info->ByteNum = (ps_locktlv_info->ByteAddr %
   4196                                     TOPAZ_BYTES_PER_BLOCK);
   4197     }
   4198 
   4199     return result;
   4200 }
   4201 
   4202 static
   4203 NFCSTATUS
   4204 phFriNfc_Tpz_H_GetMemBytesInfo (
   4205     phFriNfc_NdefMap_t          *psNdefMap,
   4206     uint8_t                     *p_mem_info)
   4207 {
   4208     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
   4209     phFriNfc_ResMemCntrlTLVCont_t   *ps_memtlv_info = NULL;
   4210     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
   4211     uint8_t                         page_address = 0;
   4212     uint8_t                         bytes_offset = 0;
   4213     uint8_t                         mem_index = 0;
   4214 
   4215     ps_memtlv_info = &(psNdefMap->MemTlv);
   4216     ps_locktlv_info = &(psNdefMap->LockTlv);
   4217     page_address = (uint8_t)(p_mem_info[mem_index] >> NIBBLE_SIZE);
   4218     bytes_offset = (uint8_t)(p_mem_info[mem_index] & TOPAZ_NIBBLE_MASK);
   4219 
   4220     mem_index = (mem_index + 1);
   4221     ps_memtlv_info->Size = (uint16_t)p_mem_info[mem_index];
   4222 
   4223     mem_index = (mem_index + 1);
   4224     ps_memtlv_info->BytesPerPage =
   4225                             (p_mem_info[mem_index] & TOPAZ_NIBBLE_MASK);
   4226 
   4227     /* Apply the formula to calculate byte address
   4228         ByteAddr = PageAddr * 2^BytesPerPage + ByteOffset
   4229     */
   4230     ps_memtlv_info->ByteAddr = (uint16_t)((page_address
   4231                             * (1 << ps_memtlv_info->BytesPerPage))
   4232                             + bytes_offset);
   4233 
   4234 
   4235     if (
   4236         /* Check if the lock and memory bytes are overlapped */
   4237         ((ps_memtlv_info->ByteAddr >= ps_locktlv_info->ByteAddr) &&
   4238         (ps_memtlv_info->ByteAddr <=
   4239         (ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1))) ||
   4240 
   4241         (((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) >=
   4242         ps_locktlv_info->ByteAddr) &&
   4243         ((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) <=
   4244         (ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1))) ||
   4245 
   4246         /* Check the static lock and reserved areas memory blocks */
   4247         ((ps_memtlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) &&
   4248         (ps_memtlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) ||
   4249         (((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) >=
   4250         TOPAZ_STATIC_LOCK_RES_START) &&
   4251         ((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) <
   4252         TOPAZ_STATIC_LOCK_RES_END)) ||
   4253 
   4254         /* Check if the memory address is out bound */
   4255         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) >
   4256         (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] *
   4257         TOPAZ_BYTES_PER_BLOCK))
   4258         )
   4259     {
   4260         ps_memtlv_info->ByteAddr = 0;
   4261         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   4262                             NFCSTATUS_NO_NDEF_SUPPORT);
   4263     }
   4264     else
   4265     {
   4266         ps_memtlv_info->BlkNum = (ps_memtlv_info->ByteAddr /
   4267                                     TOPAZ_BYTES_PER_BLOCK);
   4268         ps_memtlv_info->ByteNum = (ps_memtlv_info->ByteAddr %
   4269                                     TOPAZ_BYTES_PER_BLOCK);
   4270     }
   4271 
   4272     return result;
   4273 }
   4274 
   4275 #ifdef UNIT_TEST
   4276 #include <phUnitTestNfc_TopazDynamic_static.c>
   4277 #endif
   4278 
   4279 #endif  /*#if !(defined(PH_FRINFC_MAP_TOPAZ_DISABLED ) || defined (PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED ))*/
   4280 
   4281 
   4282 
   4283