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