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