Home | History | Annotate | Download | only in src
      1 /*
      2  *
      3  * Copyright (C) 2010 NXP Semiconductors
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 /*!
     19 * \file  phFriNfc_ISO15693Map.c
     20 * \brief This component encapsulates read/write/check ndef/process functionalities,
     21 *        for the ISO-15693 Card.
     22 *
     23 * Project: NFC-FRI
     24 *
     25 * $Date: $
     26 * $Author: ing02260 $
     27 * $Revision: $
     28 * $Aliases:  $
     29 *
     30 */
     31 
     32 #ifndef PH_FRINFC_MAP_ISO15693_DISABLED
     33 
     34 #include <phNfcTypes.h>
     35 #include <phNfcConfig.h>
     36 #include <phNfcInterface.h>
     37 #include <phNfcHalTypes.h>
     38 #include <phFriNfc.h>
     39 #include <phFriNfc_NdefMap.h>
     40 #include <phFriNfc_OvrHal.h>
     41 #include <phFriNfc_MapTools.h>
     42 #include <phFriNfc_ISO15693Map.h>
     43 
     44 /************************** START DATA STRUCTURE *********************/
     45 
     46 typedef enum phFriNfc_eChkNdefSeq
     47 {
     48     ISO15693_NDEF_TLV_T,
     49     ISO15693_NDEF_TLV_L,
     50     ISO15693_NDEF_TLV_V,
     51     ISO15693_PROP_TLV_L,
     52     ISO15693_PROP_TLV_V
     53 
     54 }phFriNfc_eChkNdefSeq_t;
     55 
     56 typedef enum phFriNfc_eWrNdefSeq
     57 {
     58     ISO15693_RD_BEFORE_WR_NDEF_L_0,
     59     ISO15693_WRITE_DATA,
     60     ISO15693_RD_BEFORE_WR_NDEF_L,
     61     ISO15693_WRITE_NDEF_TLV_L
     62 
     63 }phFriNfc_eWrNdefSeq_t;
     64 
     65 #ifdef FRINFC_READONLY_NDEF
     66 
     67 typedef enum phFriNfc_eRONdefSeq
     68 {
     69     ISO15693_RD_BEFORE_WR_CC,
     70     ISO15693_WRITE_CC,
     71     ISO15693_LOCK_BLOCK
     72 
     73 }phFriNfc_eRONdefSeq_t;
     74 
     75 #endif /* #ifdef FRINFC_READONLY_NDEF */
     76 
     77 /************************** END DATA STRUCTURE *********************/
     78 
     79 /************************** START MACROS definition *********************/
     80 
     81 
     82 
     83 
     84 /* UID bytes to differentiate ICODE cards */
     85 #define ISO15693_UID_BYTE_4                 0x04U
     86 #define ISO15693_UID_BYTE_5                 0x05U
     87 #define ISO15693_UID_BYTE_6                 0x06U
     88 #define ISO15693_UID_BYTE_7                 0x07U
     89 
     90 /* UID 7th byte value shall be 0xE0 */
     91 #define ISO15693_UIDBYTE_7_VALUE            0xE0U
     92 /* UID 6th byte value shall be 0x04 - NXP manufacturer */
     93 #define ISO15693_UIDBYTE_6_VALUE            0x04U
     94 
     95 
     96 /* UID value for
     97     SL2 ICS20
     98     SL2S2002
     99     */
    100 #define ISO15693_UIDBYTE_5_VALUE_SLI_X      0x01U
    101 /* Card size SL2 ICS20 / SL2S2002 */
    102 #define ISO15693_SL2_S2002_ICS20            112U
    103 
    104 /* UID value for
    105     SL2 ICS53,
    106     SL2 ICS54
    107     SL2S5302
    108 */
    109 #define ISO15693_UIDBYTE_5_VALUE_SLI_X_S    0x02U
    110 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_S    0x00U
    111 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC  0x80U
    112 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_SY   0x40U
    113 /* SL2 ICS53, SL2 ICS54 and SL2S5302 */
    114 #define ISO15693_SL2_S5302_ICS53_ICS54      160U
    115 
    116 /* UID value for
    117     SL2 ICS50
    118     SL2 ICS51
    119     SL2S5002
    120 */
    121 #define ISO15693_UIDBYTE_5_VALUE_SLI_X_L    0x03U
    122 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_L    0x00U
    123 #define ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC  0x80U
    124 /* SL2 ICS50, SL2 ICS51 and SL2S5002 */
    125 #define ISO15693_SL2_S5002_ICS50_ICS51      32U
    126 
    127 
    128 /* State Machine declaration
    129 CHECK NDEF state */
    130 #define ISO15693_CHECK_NDEF                 0x01U
    131 /* READ NDEF state */
    132 #define ISO15693_READ_NDEF                  0x02U
    133 /* WRITE NDEF state */
    134 #define ISO15693_WRITE_NDEF                 0x03U
    135 #ifdef FRINFC_READONLY_NDEF
    136 
    137     /* READ ONLY NDEF state */
    138     #define ISO15693_READ_ONLY_NDEF         0x04U
    139 
    140     /* READ ONLY MASK byte for CC */
    141     #define ISO15693_CC_READ_ONLY_MASK      0x03U
    142 
    143     /* CC READ WRITE index */
    144     #define ISO15693_RW_BTYE_INDEX          0x01U
    145 
    146     /* LOCK BLOCK command */
    147     #define ISO15693_LOCK_BLOCK_CMD         0x22U
    148 
    149 #endif /* #ifdef FRINFC_READONLY_NDEF */
    150 
    151 /* CC Bytes
    152 Magic number */
    153 #define ISO15693_CC_MAGIC_BYTE              0xE1U
    154 /* Expected mapping version */
    155 #define ISO15693_MAPPING_VERSION            0x01U
    156 /* Major version is in upper 2 bits */
    157 #define ISO15693_MAJOR_VERSION_MASK         0xC0U
    158 
    159 /* CC indicating tag is capable of multi-block read */
    160 #define ISO15693_CC_USE_MBR                 0x01U
    161 /* CC indicating tag is capable of inventory page read */
    162 #define ISO15693_CC_USE_IPR                 0x02U
    163 /* EXTRA byte in the response */
    164 #define ISO15693_EXTRA_RESP_BYTE            0x01U
    165 
    166 /* Maximum card size multiplication factor */
    167 #define ISO15693_MULT_FACTOR                0x08U
    168 /* NIBBLE mask for READ WRITE access */
    169 #define ISO15693_LSB_NIBBLE_MASK            0x0FU
    170 #define ISO15693_RD_WR_PERMISSION           0x00U
    171 #define ISO15693_RD_ONLY_PERMISSION         0x03U
    172 
    173 /* READ command identifier */
    174 #define ISO15693_READ_COMMAND               0x20U
    175 
    176 /* READ multiple command identifier */
    177 #define ISO15693_READ_MULTIPLE_COMMAND      0x23U
    178 
    179 /* INVENTORY pageread command identifier */
    180 #define ICODE_INVENTORY_PAGEREAD_COMMAND    0xB0U
    181 #define INVENTORY_PAGEREAD_FLAGS            0x24U
    182 #define NXP_MANUFACTURING_CODE              0x04U
    183 
    184 /* WRITE command identifier */
    185 #define ISO15693_WRITE_COMMAND              0x21U
    186 /* FLAG option */
    187 #define ISO15693_FLAGS                      0x20U
    188 
    189 /* RESPONSE length expected for single block READ */
    190 #define ISO15693_SINGLE_BLK_RD_RESP_LEN     0x04U
    191 /* NULL TLV identifier */
    192 #define ISO15693_NULL_TLV_ID                0x00U
    193 /* NDEF TLV, TYPE identifier  */
    194 #define ISO15693_NDEF_TLV_TYPE_ID           0x03U
    195 
    196 /* 8 BIT shift */
    197 #define ISO15693_BTYE_SHIFT                 0x08U
    198 
    199 /* Proprietary TLV TYPE identifier */
    200 #define ISO15693_PROP_TLV_ID                0xFDU
    201 
    202 /* CC SIZE in BYTES */
    203 #define ISO15693_CC_SIZE                    0x04U
    204 
    205 /* To get the remaining size in the card.
    206 Inputs are
    207 1. maximum data size
    208 2. block number
    209 3. index of the block number */
    210 #define ISO15693_GET_REMAINING_SIZE(max_data_size, blk, index) \
    211     (max_data_size - ((blk * ISO15693_BYTES_PER_BLOCK) + index))
    212 
    213 #define ISO15693_GET_LEN_FIELD_BLOCK_NO(blk, byte_addr, ndef_size) \
    214     (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) > \
    215     (ISO15693_BYTES_PER_BLOCK - 1)) ? (blk + 1) : blk)
    216 
    217 #define ISO15693_GET_LEN_FIELD_BYTE_NO(blk, byte_addr, ndef_size) \
    218     (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) % \
    219     ISO15693_BYTES_PER_BLOCK))
    220 
    221 
    222 
    223 /************************** END MACROS definition *********************/
    224 
    225 /************************** START static functions declaration *********************/
    226 static
    227 NFCSTATUS
    228 phFriNfc_ISO15693_H_ProcessReadOnly (
    229     phFriNfc_NdefMap_t      *psNdefMap);
    230 
    231 static
    232 NFCSTATUS
    233 phFriNfc_ISO15693_H_ProcessWriteNdef (
    234     phFriNfc_NdefMap_t      *psNdefMap);
    235 
    236 static
    237 NFCSTATUS
    238 phFriNfc_ISO15693_H_ProcessReadNdef (
    239     phFriNfc_NdefMap_t      *psNdefMap);
    240 
    241 static
    242 NFCSTATUS
    243 phFriNfc_ISO15693_H_ProcessCheckNdef (
    244     phFriNfc_NdefMap_t      *psNdefMap);
    245 
    246 static
    247 void
    248 phFriNfc_ISO15693_H_Complete (
    249     phFriNfc_NdefMap_t      *psNdefMap,
    250     NFCSTATUS               Status);
    251 
    252 static
    253 NFCSTATUS
    254 phFriNfc_ISO15693_H_ReadWrite (
    255     phFriNfc_NdefMap_t      *psNdefMap,
    256     uint8_t                 command,
    257     uint8_t                 *p_data,
    258     uint8_t                 data_length);
    259 
    260 static
    261 NFCSTATUS
    262 phFriNfc_ReadRemainingInMultiple (
    263     phFriNfc_NdefMap_t  *psNdefMap,
    264     uint32_t            startBlock);
    265 
    266 /************************** END static functions declaration *********************/
    267 
    268 /************************** START static functions definition *********************/
    269 
    270 static
    271 NFCSTATUS
    272 phFriNfc_ISO15693_H_ProcessWriteNdef (
    273     phFriNfc_NdefMap_t      *psNdefMap)
    274 {
    275     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    276     phFriNfc_ISO15693Cont_t     *ps_iso_15693_con =
    277                                 &(psNdefMap->ISO15693Container);
    278     phFriNfc_eWrNdefSeq_t       e_wr_ndef_seq = (phFriNfc_eWrNdefSeq_t)
    279                                 psNdefMap->ISO15693Container.ndef_seq;
    280     uint8_t                     *p_recv_buf = NULL;
    281     uint8_t                     recv_length = 0;
    282     uint8_t                     write_flag = FALSE;
    283     uint8_t                     a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
    284     uint8_t                     remaining_size = 0;
    285 
    286     switch (e_wr_ndef_seq)
    287     {
    288         case ISO15693_RD_BEFORE_WR_NDEF_L_0:
    289         {
    290             /* L byte is read  */
    291             p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
    292             recv_length = (uint8_t)
    293                         (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
    294 
    295             if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
    296             {
    297                 /* Response length is correct */
    298                 uint8_t     byte_index = 0;
    299 
    300                 /* Copy the recevied buffer */
    301                 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
    302                                 recv_length);
    303 
    304                 byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO(
    305                         ps_iso_15693_con->ndef_tlv_type_blk,
    306                         ps_iso_15693_con->ndef_tlv_type_byte,
    307                         psNdefMap->ApduBufferSize);
    308 
    309                 /* Writing length field to 0, Update length field to 0 */
    310                 *(a_write_buf + byte_index) = 0x00;
    311 
    312                 if ((ISO15693_BYTES_PER_BLOCK - 1) != byte_index)
    313                 {
    314                     /* User data is updated in the buffer */
    315                     byte_index = (uint8_t)(byte_index + 1);
    316                     /* Block number shall be udate */
    317                     remaining_size = (ISO15693_BYTES_PER_BLOCK - byte_index);
    318 
    319                     if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
    320                         < remaining_size)
    321                     {
    322                         remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
    323                                                     psNdefMap->ApduBuffIndex);
    324                     }
    325 
    326                     /* Go to next byte to fill the write buffer */
    327                     (void)memcpy ((void *)(a_write_buf + byte_index),
    328                                 (void *)(psNdefMap->ApduBuffer +
    329                                 psNdefMap->ApduBuffIndex), remaining_size);
    330 
    331                     /* Write index updated */
    332                     psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
    333                                                 remaining_size);
    334                 }
    335 
    336                 /* After this write, user data can be written.
    337                 Update the sequence accordingly */
    338                 e_wr_ndef_seq = ISO15693_WRITE_DATA;
    339                 write_flag = TRUE;
    340             } /* if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) */
    341             else
    342             {
    343                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    344                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
    345             }
    346             break;
    347         } /* case ISO15693_RD_BEFORE_WR_NDEF_L_0: */
    348 
    349         case ISO15693_RD_BEFORE_WR_NDEF_L:
    350         {
    351             p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
    352             recv_length = (uint8_t)(*psNdefMap->SendRecvLength -
    353                             ISO15693_EXTRA_RESP_BYTE);
    354 
    355             if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
    356             {
    357                 uint8_t     byte_index = 0;
    358 
    359                 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
    360                                 recv_length);
    361 
    362                 byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO(
    363                                 ps_iso_15693_con->ndef_tlv_type_blk,
    364                                 ps_iso_15693_con->ndef_tlv_type_byte,
    365                                 psNdefMap->ApduBuffIndex);
    366 
    367                 *(a_write_buf + byte_index) = (uint8_t)psNdefMap->ApduBuffIndex;
    368                 e_wr_ndef_seq = ISO15693_WRITE_NDEF_TLV_L;
    369                 write_flag = TRUE;
    370             }
    371             else
    372             {
    373                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    374                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
    375             }
    376             break;
    377         }
    378 
    379         case ISO15693_WRITE_DATA:
    380         {
    381             if ((psNdefMap->ApduBufferSize == psNdefMap->ApduBuffIndex)
    382                 || (ps_iso_15693_con->current_block ==
    383                     (ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK)))
    384             {
    385                 ps_iso_15693_con->current_block =
    386                         ISO15693_GET_LEN_FIELD_BLOCK_NO(
    387                         ps_iso_15693_con->ndef_tlv_type_blk,
    388                         ps_iso_15693_con->ndef_tlv_type_byte,
    389                         psNdefMap->ApduBuffIndex);
    390                 e_wr_ndef_seq = ISO15693_RD_BEFORE_WR_NDEF_L;
    391             }
    392             else
    393             {
    394                 remaining_size = ISO15693_BYTES_PER_BLOCK;
    395 
    396                 ps_iso_15693_con->current_block = (uint16_t)
    397                                     (ps_iso_15693_con->current_block + 1);
    398 
    399                 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
    400                     < remaining_size)
    401                 {
    402                     remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
    403                                                 psNdefMap->ApduBuffIndex);
    404                 }
    405 
    406                 (void)memcpy ((void *)a_write_buf, (void *)
    407                                 (psNdefMap->ApduBuffer +
    408                                 psNdefMap->ApduBuffIndex), remaining_size);
    409 
    410                 psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
    411                                                 remaining_size);
    412                 write_flag = TRUE;
    413             }
    414             break;
    415         } /* case ISO15693_WRITE_DATA: */
    416 
    417         case ISO15693_WRITE_NDEF_TLV_L:
    418         {
    419             *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex;
    420             ps_iso_15693_con->actual_ndef_size = psNdefMap->ApduBuffIndex;
    421             break;
    422         }
    423 
    424         default:
    425         {
    426             break;
    427         }
    428     } /* switch (e_wr_ndef_seq) */
    429 
    430     if (((0 == psNdefMap->ApduBuffIndex)
    431         || (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex))
    432         && (!result))
    433     {
    434         if (FALSE == write_flag)
    435         {
    436             result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
    437                                     ISO15693_READ_COMMAND, NULL, 0);
    438         }
    439         else
    440         {
    441             result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
    442                                         ISO15693_WRITE_COMMAND,
    443                                         a_write_buf, sizeof (a_write_buf));
    444         }
    445     }
    446 
    447     psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_wr_ndef_seq;
    448     return result;
    449 }
    450 
    451 static
    452 NFCSTATUS
    453 phFriNfc_ISO15693_H_ReadWrite (
    454     phFriNfc_NdefMap_t      *psNdefMap,
    455     uint8_t                 command,
    456     uint8_t                 *p_data,
    457     uint8_t                 data_length)
    458 {
    459     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    460     uint8_t                     send_index = 0;
    461 
    462     /* set the data for additional data exchange*/
    463     psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    464     psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    465     psNdefMap->psDepAdditionalInfo.NAD = 0;
    466 
    467     psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
    468     psNdefMap->MapCompletionInfo.Context = psNdefMap;
    469 
    470     *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
    471 
    472     psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
    473 
    474     *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)ISO15693_FLAGS;
    475     send_index = (uint8_t)(send_index + 1);
    476 
    477     *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
    478     send_index = (uint8_t)(send_index + 1);
    479 
    480     (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
    481         (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid,
    482         psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
    483     send_index = (uint8_t)(send_index +
    484                 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
    485 
    486     *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
    487                                 psNdefMap->ISO15693Container.current_block;
    488     send_index = (uint8_t)(send_index + 1);
    489 
    490     if ((ISO15693_WRITE_COMMAND == command) ||
    491         (ISO15693_READ_MULTIPLE_COMMAND == command))
    492     {
    493         (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
    494                     (void *)p_data, data_length);
    495         send_index = (uint8_t)(send_index + data_length);
    496     }
    497 
    498     psNdefMap->SendLength = send_index;
    499     result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
    500                                         &psNdefMap->MapCompletionInfo,
    501                                         psNdefMap->psRemoteDevInfo,
    502                                         psNdefMap->Cmd,
    503                                         &psNdefMap->psDepAdditionalInfo,
    504                                         psNdefMap->SendRecvBuf,
    505                                         psNdefMap->SendLength,
    506                                         psNdefMap->SendRecvBuf,
    507                                         psNdefMap->SendRecvLength);
    508 
    509     return result;
    510 }
    511 
    512 static
    513 NFCSTATUS
    514 phFriNfc_ISO15693_H_Inventory_Page_Read (
    515     phFriNfc_NdefMap_t      *psNdefMap,
    516     uint8_t                 command,
    517     uint8_t                 page,
    518     uint8_t                 numPages)
    519 {
    520     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    521     uint8_t                     send_index = 0;
    522 
    523     /* set the data for additional data exchange*/
    524     psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    525     psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    526     psNdefMap->psDepAdditionalInfo.NAD = 0;
    527 
    528     psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
    529     psNdefMap->MapCompletionInfo.Context = psNdefMap;
    530 
    531     *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
    532 
    533     psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
    534 
    535     *(psNdefMap->SendRecvBuf + send_index) = INVENTORY_PAGEREAD_FLAGS;
    536     send_index = (uint8_t)(send_index + 1);
    537 
    538     *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
    539     send_index = (uint8_t)(send_index + 1);
    540 
    541     *(psNdefMap->SendRecvBuf + send_index) = NXP_MANUFACTURING_CODE;
    542     send_index = (uint8_t)(send_index + 1);
    543 
    544     *(psNdefMap->SendRecvBuf + send_index) = 0x40;
    545     send_index = (uint8_t)(send_index + 1);
    546 
    547     (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
    548         (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid,
    549         psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
    550     send_index = (uint8_t)(send_index +
    551                 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
    552 
    553     *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
    554                                 page;
    555     send_index = (uint8_t)(send_index + 1);
    556 
    557     *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
    558                                 numPages;
    559     send_index = (uint8_t)(send_index + 1);
    560 
    561     psNdefMap->SendLength = send_index;
    562 
    563     result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
    564                                         &psNdefMap->MapCompletionInfo,
    565                                         psNdefMap->psRemoteDevInfo,
    566                                         psNdefMap->Cmd,
    567                                         &psNdefMap->psDepAdditionalInfo,
    568                                         psNdefMap->SendRecvBuf,
    569                                         psNdefMap->SendLength,
    570                                         psNdefMap->SendRecvBuf,
    571                                         psNdefMap->SendRecvLength);
    572 
    573     return result;
    574 }
    575 
    576 static
    577 NFCSTATUS
    578 phFriNfc_ISO15693_Reformat_Pageread_Buffer (
    579     uint8_t                 *p_recv_buf,
    580     uint8_t                 recv_length,
    581     uint8_t                 *p_dst_buf,
    582     uint8_t                 dst_length)
    583 {
    584    // Inventory page reads return an extra security byte per page
    585    // So we need to reformat the returned buffer in memory
    586     uint32_t i = 0;
    587     uint32_t reformatted_index = 0;
    588     while (i < recv_length) {
    589         // Going for another page of 16 bytes, check for space in dst buffer
    590         if (reformatted_index + 16 > dst_length) {
    591             break;
    592         }
    593         if (p_recv_buf[i] == 0x0F) {
    594             // Security, insert 16 0 bytes
    595             memset(&(p_dst_buf[reformatted_index]), 0, 16);
    596             reformatted_index += 16;
    597             i++;
    598         } else {
    599             // Skip security byte
    600             i++;
    601             if (i + 16 <= recv_length) {
    602                 memcpy(&(p_dst_buf[reformatted_index]), &(p_recv_buf[i]), 16);
    603                 reformatted_index += 16;
    604             } else {
    605                 break;
    606             }
    607             i+=16;
    608         }
    609     }
    610     return reformatted_index;
    611 }
    612 
    613 static
    614 NFCSTATUS
    615 phFriNfc_ISO15693_H_ProcessReadNdef (
    616     phFriNfc_NdefMap_t      *psNdefMap)
    617 {
    618     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    619     phFriNfc_ISO15693Cont_t     *ps_iso_15693_con =
    620                                 &(psNdefMap->ISO15693Container);
    621     uint16_t                    remaining_data_size = 0;
    622     uint8_t                     *p_recv_buf =
    623                                 (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
    624     uint8_t                     recv_length = (uint8_t)
    625                                 (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
    626 
    627     uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size);
    628 
    629     if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)
    630     {
    631         uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length,
    632                 reformatted_buf, ps_iso_15693_con->max_data_size);
    633         p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
    634         recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
    635     }
    636     if (ps_iso_15693_con->store_length)
    637     {
    638         /* Continue Offset option selected
    639             So stored data already existing,
    640             copy the information to the user buffer
    641         */
    642         if (ps_iso_15693_con->store_length
    643             <= (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex))
    644         {
    645             /* Stored data length is less than or equal
    646                 to the user expected size */
    647             (void)memcpy ((void *)(psNdefMap->ApduBuffer +
    648                         psNdefMap->ApduBuffIndex),
    649                             (void *)ps_iso_15693_con->store_read_data,
    650                         ps_iso_15693_con->store_length);
    651 
    652             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
    653                                         ps_iso_15693_con->store_length);
    654 
    655             remaining_data_size = ps_iso_15693_con->store_length;
    656 
    657             ps_iso_15693_con->store_length = 0;
    658         }
    659         else
    660         {
    661             /* stored length is more than the user expected size */
    662             remaining_data_size = (uint16_t)(ps_iso_15693_con->store_length -
    663                                 (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex));
    664 
    665             (void)memcpy ((void *)(psNdefMap->ApduBuffer +
    666                         psNdefMap->ApduBuffIndex),
    667                         (void *)ps_iso_15693_con->store_read_data,
    668                         remaining_data_size);
    669 
    670                 /* As stored data is more than the user expected data. So store
    671                     the remaining bytes again into the data structure */
    672             (void)memcpy ((void *)ps_iso_15693_con->store_read_data,
    673                         (void *)(ps_iso_15693_con->store_read_data +
    674                         remaining_data_size),
    675                         (ps_iso_15693_con->store_length - remaining_data_size));
    676 
    677             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
    678                                         remaining_data_size);
    679 
    680                 ps_iso_15693_con->store_length = (uint8_t)
    681                             (ps_iso_15693_con->store_length - remaining_data_size);
    682         }
    683     } /* if (ps_iso_15693_con->store_length) */
    684     else
    685     {
    686             /* Data is read from the card. */
    687         uint8_t                 byte_index = 0;
    688 
    689         remaining_data_size = ps_iso_15693_con->remaining_size_to_read;
    690 
    691             /* Check if the block number is to read the first VALUE field */
    692         if (ISO15693_GET_VALUE_FIELD_BLOCK_NO(ps_iso_15693_con->ndef_tlv_type_blk,
    693                                     ps_iso_15693_con->ndef_tlv_type_byte,
    694                                     ps_iso_15693_con->actual_ndef_size)
    695             == ps_iso_15693_con->current_block)
    696         {
    697             /* Read from the beginning option selected,
    698                 BYTE number may start from the middle */
    699             byte_index = (uint8_t)ISO15693_GET_VALUE_FIELD_BYTE_NO(
    700                             ps_iso_15693_con->ndef_tlv_type_blk,
    701                             ps_iso_15693_con->ndef_tlv_type_byte,
    702                             ps_iso_15693_con->actual_ndef_size);
    703         }
    704 
    705         if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
    706             < remaining_data_size)
    707         {
    708                 remaining_data_size = (uint8_t)
    709                                     (recv_length - byte_index);
    710                 /* user input is less than the remaining card size */
    711             if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
    712                     < (uint16_t)remaining_data_size)
    713             {
    714                     /* user data required is less than the data read */
    715                 remaining_data_size = (uint8_t)(psNdefMap->ApduBufferSize -
    716                                                 psNdefMap->ApduBuffIndex);
    717 
    718                     if (0 != (recv_length - (byte_index +
    719                                     remaining_data_size)))
    720                     {
    721                 /* Store the data for the continue read option */
    722                 (void)memcpy ((void *)ps_iso_15693_con->store_read_data,
    723                                 (void *)(p_recv_buf + (byte_index +
    724                                         remaining_data_size)),
    725                                         (recv_length - (byte_index +
    726                                         remaining_data_size)));
    727 
    728                 ps_iso_15693_con->store_length = (uint8_t)
    729                                     (recv_length - (byte_index +
    730                                         remaining_data_size));
    731             }
    732             }
    733         }
    734         else
    735         {
    736                 /* user data required is equal or greater than the data read */
    737             if (remaining_data_size > (recv_length - byte_index))
    738             {
    739                 remaining_data_size = (uint8_t)
    740                                 (recv_length - byte_index);
    741             }
    742         }
    743 
    744             /* Copy data in the user buffer */
    745         (void)memcpy ((void *)(psNdefMap->ApduBuffer +
    746                         psNdefMap->ApduBuffIndex),
    747                         (void *)(p_recv_buf + byte_index),
    748                         remaining_data_size);
    749 
    750             /* Update the read index */
    751         psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
    752                                     remaining_data_size);
    753 
    754         } /* else part of if (ps_iso_15693_con->store_length) */
    755 
    756     /* Remaining size is decremented */
    757     ps_iso_15693_con->remaining_size_to_read = (uint8_t)
    758                             (ps_iso_15693_con->remaining_size_to_read -
    759                             remaining_data_size);
    760 
    761     if ((psNdefMap->ApduBuffIndex != psNdefMap->ApduBufferSize)
    762         && (0 != ps_iso_15693_con->remaining_size_to_read))
    763     {
    764         ps_iso_15693_con->current_block = (uint16_t)
    765                             (ps_iso_15693_con->current_block + 1);
    766         /* READ again */
    767         if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
    768             (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
    769             result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
    770         }
    771         else {
    772             result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
    773                                                     NULL, 0);
    774         }
    775     }
    776     else
    777     {
    778             /* Read completed, EITHER index has reached to the user size
    779             OR end of the card is reached
    780             update the user data structure with read data size */
    781         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
    782     }
    783     if (reformatted_buf != NULL) {
    784         phOsalNfc_FreeMemory(reformatted_buf);
    785     }
    786     return result;
    787 }
    788 
    789 static
    790 NFCSTATUS
    791 phFriNfc_ISO15693_H_CheckCCBytes (
    792     phFriNfc_NdefMap_t      *psNdefMap)
    793 {
    794     NFCSTATUS               result = NFCSTATUS_SUCCESS;
    795     phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
    796                             &(psNdefMap->ISO15693Container);
    797     uint8_t                 recv_index = 0;
    798     uint8_t                 *p_recv_buf = (psNdefMap->SendRecvBuf + 1);
    799 
    800     /* expected CC byte : E1 40 "MAX SIZE depends on tag" */
    801     if (ISO15693_CC_MAGIC_BYTE == *p_recv_buf)
    802     {
    803         /*  0xE1 magic byte found*/
    804         recv_index = (uint8_t)(recv_index + 1);
    805         uint8_t tag_major_version = (*(p_recv_buf + recv_index) & ISO15693_MAJOR_VERSION_MASK) >> 6;
    806         if (ISO15693_MAPPING_VERSION >= tag_major_version)
    807         {
    808             /* Correct mapping version found */
    809             switch (*(p_recv_buf + recv_index) & ISO15693_LSB_NIBBLE_MASK)
    810             {
    811                 case ISO15693_RD_WR_PERMISSION:
    812                 {
    813                     /* READ/WRITE possible */
    814                     psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
    815                     break;
    816                 }
    817 
    818                 case ISO15693_RD_ONLY_PERMISSION:
    819                 {
    820                     /* ONLY READ possible, WRITE NOT possible */
    821                     psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
    822                     break;
    823                 }
    824 
    825                 default:
    826                 {
    827                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    828                                         NFCSTATUS_NO_NDEF_SUPPORT);
    829                     break;
    830                 }
    831             }
    832             recv_index = (uint8_t)(recv_index + 1);
    833 
    834             if (!result)
    835             {
    836                 /* Update MAX SIZE */
    837                 ps_iso_15693_con->max_data_size = (uint16_t)
    838                     (*(p_recv_buf + recv_index) *
    839                     ISO15693_MULT_FACTOR);
    840                 recv_index = (uint8_t)(recv_index + 1);
    841                 ps_iso_15693_con->read_capabilities = (*(p_recv_buf + recv_index));
    842 
    843 
    844             }
    845         }
    846         else
    847         {
    848             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    849                             NFCSTATUS_NO_NDEF_SUPPORT);
    850         }
    851     }
    852     else
    853     {
    854         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    855                             NFCSTATUS_NO_NDEF_SUPPORT);
    856     }
    857     return result;
    858 }
    859 
    860 static
    861 NFCSTATUS
    862 phFriNfc_ISO15693_H_ProcessCheckNdef (
    863     phFriNfc_NdefMap_t      *psNdefMap)
    864 {
    865     NFCSTATUS               result = NFCSTATUS_SUCCESS;
    866     phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
    867                             &(psNdefMap->ISO15693Container);
    868     phFriNfc_eChkNdefSeq_t  e_chk_ndef_seq = (phFriNfc_eChkNdefSeq_t)
    869                             psNdefMap->ISO15693Container.ndef_seq;
    870 
    871     uint8_t                 *p_recv_buf =
    872                             (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
    873     uint8_t                 recv_length = (uint8_t)
    874                             (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
    875     uint8_t                 parse_index = 0;
    876     static uint16_t         prop_ndef_index = 0;
    877     uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size);
    878 
    879     if (0 == ps_iso_15693_con->current_block)
    880     {
    881         /* Check CC byte */
    882         result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
    883         parse_index = (uint8_t)(parse_index + recv_length);
    884     }
    885     else if (1 == ps_iso_15693_con->current_block &&
    886             (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR))
    887     {
    888 
    889         uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length,
    890                 reformatted_buf, ps_iso_15693_con->max_data_size);
    891         // Skip initial CC bytes
    892         p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
    893         recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
    894     }
    895     else
    896     {
    897         /* Propreitary TLVs VALUE can end in between a block,
    898             so when that block is read, update the parse_index
    899             with byte address value */
    900         if (ISO15693_PROP_TLV_V == e_chk_ndef_seq)
    901         {
    902             parse_index = ps_iso_15693_con->ndef_tlv_type_byte;
    903             e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
    904         }
    905     }
    906 
    907     while ((parse_index < recv_length)
    908             && (NFCSTATUS_SUCCESS == result)
    909             && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq))
    910     {
    911         /* Parse
    912             1. till the received length of the block
    913             2. till there is no error during parse
    914             3. till LENGTH field of NDEF TLV is found
    915         */
    916         switch (e_chk_ndef_seq)
    917         {
    918             case ISO15693_NDEF_TLV_T:
    919             {
    920                 /* Expected value is 0x03 TYPE identifier
    921                     of the NDEF TLV */
    922                 prop_ndef_index = 0;
    923                 switch (*(p_recv_buf + parse_index))
    924                 {
    925                     case ISO15693_NDEF_TLV_TYPE_ID:
    926                     {
    927                         /* Update the data structure with the byte address and
    928                         the block number */
    929                         ps_iso_15693_con->ndef_tlv_type_byte = parse_index;
    930                         ps_iso_15693_con->ndef_tlv_type_blk =
    931                                             ps_iso_15693_con->current_block;
    932                         e_chk_ndef_seq = ISO15693_NDEF_TLV_L;
    933 
    934                         break;
    935                     }
    936 
    937                     case ISO15693_NULL_TLV_ID:
    938                     {
    939                         /* Dont do any thing, go to next byte */
    940                         break;
    941                     }
    942 
    943                     case ISO15693_PROP_TLV_ID:
    944                     {
    945                         /* Move the sequence to find the length
    946                             of the proprietary TLV */
    947                         e_chk_ndef_seq = ISO15693_PROP_TLV_L;
    948                         break;
    949                     }
    950 
    951                     default:
    952                     {
    953                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    954                                             NFCSTATUS_NO_NDEF_SUPPORT);
    955                         break;
    956                     }
    957                 } /* switch (*(p_recv_buf + parse_index)) */
    958                 break;
    959             }
    960 
    961             case ISO15693_PROP_TLV_L:
    962             {
    963                 /* Length field of the proprietary TLV */
    964                 switch (prop_ndef_index)
    965                 {
    966                     /* Length field can have 1 or 3 bytes depending
    967                         on the data size, so check for each index byte */
    968                     case 0:
    969                     {
    970                         /* 1st index of the length field of the TLV */
    971                         if (0 == *(p_recv_buf + parse_index))
    972                         {
    973                             /* LENGTH is 0, not possible, so error */
    974                             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
    975                                                 NFCSTATUS_NO_NDEF_SUPPORT);
    976                             e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
    977                         }
    978                         else
    979                         {
    980                             if (ISO15693_THREE_BYTE_LENGTH_ID ==
    981                                 *(p_recv_buf + parse_index))
    982                             {
    983                                 /* 3 byte LENGTH field identified, so increment the
    984                                 index, so next time 2nd byte is parsed */
    985                                 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
    986                             }
    987                             else
    988                             {
    989                                 /* 1 byte LENGTH field identified, so "static"
    990                                 index is set to 0 and actual ndef size is
    991                                 copied to the data structure
    992                                 */
    993                                 ps_iso_15693_con->actual_ndef_size =
    994                                                     *(p_recv_buf + parse_index);
    995                                 e_chk_ndef_seq = ISO15693_PROP_TLV_V;
    996                                 prop_ndef_index = 0;
    997                             }
    998                         }
    999                         break;
   1000                     }
   1001 
   1002                     case 1:
   1003                     {
   1004                         /* 2nd index of the LENGTH field that is MSB of the length,
   1005                         so the length is left shifted by 8 */
   1006                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
   1007                                         (*(p_recv_buf + parse_index) <<
   1008                                         ISO15693_BTYE_SHIFT);
   1009                         prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
   1010                         break;
   1011                     }
   1012 
   1013                     case 2:
   1014                     {
   1015                         /* 3rd index of the LENGTH field that is LSB of the length,
   1016                         so the length ORed with the previously stored size */
   1017                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
   1018                                         (ps_iso_15693_con->actual_ndef_size |
   1019                                         *(p_recv_buf + parse_index));
   1020 
   1021                         e_chk_ndef_seq = ISO15693_PROP_TLV_V;
   1022                         prop_ndef_index = 0;
   1023                         break;
   1024                     }
   1025 
   1026                     default:
   1027                     {
   1028                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1029                                             NFCSTATUS_INVALID_DEVICE_REQUEST);
   1030                         break;
   1031                     }
   1032                 } /* switch (prop_ndef_index) */
   1033 
   1034                 if ((ISO15693_PROP_TLV_V == e_chk_ndef_seq)
   1035                     && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
   1036                         ps_iso_15693_con->current_block, parse_index)
   1037                         <= ps_iso_15693_con->actual_ndef_size))
   1038                 {
   1039                     /* Check for the length field value has not exceeded the card size,
   1040                     if size is exceeded or then return error */
   1041                     e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
   1042                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1043                                         NFCSTATUS_NO_NDEF_SUPPORT);
   1044                 }
   1045                 else
   1046                 {
   1047                     uint16_t            prop_byte_addr = 0;
   1048 
   1049                     /* skip the proprietary TLVs value field */
   1050                     prop_byte_addr = (uint16_t)
   1051                         ((ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK) +
   1052                         parse_index + ps_iso_15693_con->actual_ndef_size);
   1053 
   1054                     ps_iso_15693_con->ndef_tlv_type_byte = (uint8_t)(prop_byte_addr %
   1055                                                         ISO15693_BYTES_PER_BLOCK);
   1056                     ps_iso_15693_con->ndef_tlv_type_blk = (uint16_t)(prop_byte_addr /
   1057                                                         ISO15693_BYTES_PER_BLOCK);
   1058                     if (parse_index + ps_iso_15693_con->actual_ndef_size >=
   1059                         recv_length)
   1060                     {
   1061                         parse_index = (uint8_t)recv_length;
   1062                     }
   1063                     else
   1064                     {
   1065                         parse_index = (uint8_t)(parse_index +
   1066                                         ps_iso_15693_con->actual_ndef_size);
   1067                     }
   1068 
   1069                 }
   1070                 break;
   1071             } /* case ISO15693_PROP_TLV_L: */
   1072 
   1073             case ISO15693_PROP_TLV_V:
   1074             {
   1075                 uint8_t         remaining_length = (uint8_t)(recv_length -
   1076                                                     parse_index);
   1077 
   1078                 if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
   1079                     > remaining_length)
   1080                 {
   1081                     parse_index = (uint8_t)(parse_index + remaining_length);
   1082                     prop_ndef_index = (uint8_t)(prop_ndef_index + remaining_length);
   1083                 }
   1084                 else if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
   1085                     == remaining_length)
   1086                 {
   1087                     parse_index = (uint8_t)(parse_index + remaining_length);
   1088                     e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
   1089                     prop_ndef_index = 0;
   1090                 }
   1091                 else
   1092                 {
   1093                     parse_index = (uint8_t)(parse_index +
   1094                                             (ps_iso_15693_con->actual_ndef_size -
   1095                                             prop_ndef_index));
   1096                     e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
   1097                     prop_ndef_index = 0;
   1098                 }
   1099                 break;
   1100             } /* case ISO15693_PROP_TLV_V: */
   1101 
   1102             case ISO15693_NDEF_TLV_L:
   1103             {
   1104                 /* Length field of the NDEF TLV */
   1105                 switch (prop_ndef_index)
   1106                 {
   1107                     /* Length field can have 1 or 3 bytes depending
   1108                         on the data size, so check for each index byte */
   1109                     case 0:
   1110                     {
   1111                         /* 1st index of the length field of the TLV */
   1112                         if (0 == *(p_recv_buf + parse_index))
   1113                         {
   1114                             /* LENGTH is 0, card is in INITILIASED STATE */
   1115                             e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
   1116                             ps_iso_15693_con->actual_ndef_size = 0;
   1117                         }
   1118                         else
   1119                         {
   1120                             prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
   1121 
   1122                             if (ISO15693_THREE_BYTE_LENGTH_ID ==
   1123                                 *(p_recv_buf + parse_index))
   1124                             {
   1125                                 /* At present no CARD supports more than 255 bytes,
   1126                                 so error is returned */
   1127                                 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
   1128                                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1129                                                     NFCSTATUS_NO_NDEF_SUPPORT);
   1130                                 prop_ndef_index = 0;
   1131                             }
   1132                             else
   1133                             {
   1134                                 /* 1 byte LENGTH field identified, so "static"
   1135                                 index is set to 0 and actual ndef size is
   1136                                 copied to the data structure
   1137                                 */
   1138                                 ps_iso_15693_con->actual_ndef_size =
   1139                                                     *(p_recv_buf + parse_index);
   1140                                 /* next values are the DATA field of the NDEF TLV */
   1141                                 e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
   1142                                 prop_ndef_index = 0;
   1143                             }
   1144                         }
   1145                         break;
   1146                     }
   1147 
   1148                     case 1:
   1149                     {
   1150                         /* 2nd index of the LENGTH field that is MSB of the length,
   1151                         so the length is left shifted by 8 */
   1152                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
   1153                             (*(p_recv_buf + parse_index) <<
   1154                             ISO15693_BTYE_SHIFT);
   1155                         prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
   1156                         break;
   1157                     }
   1158 
   1159                     case 2:
   1160                     {
   1161                         /* 3rd index of the LENGTH field that is LSB of the length,
   1162                         so the length ORed with the previously stored size */
   1163                         ps_iso_15693_con->actual_ndef_size = (uint16_t)
   1164                             (ps_iso_15693_con->actual_ndef_size |
   1165                             *(p_recv_buf + parse_index));
   1166 
   1167                         e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
   1168                         prop_ndef_index = 0;
   1169                         break;
   1170                     }
   1171 
   1172                     default:
   1173                     {
   1174                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1175                                     NFCSTATUS_INVALID_DEVICE_REQUEST);
   1176                         break;
   1177                     }
   1178                 } /* switch (prop_ndef_index) */
   1179 
   1180                 if ((ISO15693_NDEF_TLV_V == e_chk_ndef_seq)
   1181                     && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
   1182                         /* parse_index + 1 is done because the data starts from the next index.
   1183                         "MOD" operation is used to know that parse_index >
   1184                         ISO15693_BYTES_PER_BLOCK, then block shall be incremented
   1185                         */
   1186                         (((parse_index + 1) % ISO15693_BYTES_PER_BLOCK) ?
   1187                         ps_iso_15693_con->current_block :
   1188                         ps_iso_15693_con->current_block + 1), ((parse_index + 1) %
   1189                         ISO15693_BYTES_PER_BLOCK))
   1190                         < ps_iso_15693_con->actual_ndef_size))
   1191                 {
   1192                     /* Check for the length field value has not exceeded the card size */
   1193                     e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
   1194                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1195                                         NFCSTATUS_NO_NDEF_SUPPORT);
   1196                 }
   1197                 else
   1198                 {
   1199                     psNdefMap->CardState = (uint8_t)
   1200                                     ((PH_NDEFMAP_CARD_STATE_READ_ONLY
   1201                                     == psNdefMap->CardState) ?
   1202                                     PH_NDEFMAP_CARD_STATE_READ_ONLY :
   1203                                     ((ps_iso_15693_con->actual_ndef_size) ?
   1204                                     PH_NDEFMAP_CARD_STATE_READ_WRITE :
   1205                                     PH_NDEFMAP_CARD_STATE_INITIALIZED));
   1206                 }
   1207                 break;
   1208             } /* case ISO15693_NDEF_TLV_L: */
   1209 
   1210             case ISO15693_NDEF_TLV_V:
   1211             {
   1212                 break;
   1213             }
   1214 
   1215             default:
   1216             {
   1217                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1218                                     NFCSTATUS_INVALID_DEVICE_REQUEST);
   1219                 break;
   1220             }
   1221         } /* switch (e_chk_ndef_seq) */
   1222         parse_index = (uint8_t)(parse_index + 1);
   1223     } /* while ((parse_index < recv_length)
   1224             && (NFCSTATUS_SUCCESS == result)
   1225             && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)) */
   1226 
   1227     if (result)
   1228     {
   1229         /* Error returned while parsing, so STOP read */
   1230         e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
   1231         prop_ndef_index = 0;
   1232     }
   1233     else if (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)
   1234     {
   1235         /* READ again */
   1236         if (ISO15693_PROP_TLV_V != e_chk_ndef_seq)
   1237         {
   1238             ps_iso_15693_con->current_block = (uint16_t)
   1239                                 (ps_iso_15693_con->current_block + 1);
   1240         }
   1241         else
   1242         {
   1243             /* Proprietary TLV detected, so skip the proprietary blocks */
   1244             ps_iso_15693_con->current_block = ps_iso_15693_con->ndef_tlv_type_blk;
   1245         }
   1246 
   1247         uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
   1248                                            ps_iso_15693_con->current_block, 0);
   1249         if (remaining_size > 0)
   1250         {
   1251             if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
   1252                 (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
   1253                 result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
   1254             } else  {
   1255                 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
   1256                                                         NULL, 0);
   1257             }
   1258         }
   1259         else
   1260         {
   1261             /* End of card reached, error no NDEF information found */
   1262             e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
   1263             prop_ndef_index = 0;
   1264             /* Error, no size to parse */
   1265             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1266                                     NFCSTATUS_NO_NDEF_SUPPORT);
   1267         }
   1268 
   1269     }
   1270     else
   1271     {
   1272         /* Successful read with proper NDEF information updated */
   1273         prop_ndef_index = 0;
   1274         e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
   1275         psNdefMap->CardType = (uint8_t)PH_FRINFC_NDEFMAP_ISO15693_CARD;
   1276     }
   1277 
   1278     psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_chk_ndef_seq;
   1279 
   1280     if (reformatted_buf != NULL) {
   1281         phOsalNfc_FreeMemory(reformatted_buf);
   1282     }
   1283     return result;
   1284 }
   1285 
   1286 static
   1287 void
   1288 phFriNfc_ISO15693_H_Complete (
   1289     phFriNfc_NdefMap_t      *psNdefMap,
   1290     NFCSTATUS               Status)
   1291 {
   1292     /* set the state back to the RESET_INIT state*/
   1293     psNdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
   1294 
   1295     /* set the completion routine*/
   1296     psNdefMap->CompletionRoutine[psNdefMap->ISO15693Container.cr_index].
   1297         CompletionRoutine (psNdefMap->CompletionRoutine->Context, Status);
   1298 }
   1299 
   1300 #ifdef FRINFC_READONLY_NDEF
   1301 
   1302 static
   1303 NFCSTATUS
   1304 phFriNfc_ISO15693_H_ProcessReadOnly (
   1305     phFriNfc_NdefMap_t      *psNdefMap)
   1306 {
   1307     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   1308     phFriNfc_ISO15693Cont_t     *ps_iso_15693_con =
   1309                                 &(psNdefMap->ISO15693Container);
   1310     phFriNfc_eRONdefSeq_t       e_ro_ndef_seq = (phFriNfc_eRONdefSeq_t)
   1311                                 ps_iso_15693_con->ndef_seq;
   1312     uint8_t                     *p_recv_buf = (psNdefMap->SendRecvBuf +
   1313                                 ISO15693_EXTRA_RESP_BYTE);
   1314     uint8_t                     recv_length = (uint8_t)(*psNdefMap->SendRecvLength -
   1315                                 ISO15693_EXTRA_RESP_BYTE);
   1316     uint8_t                     a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
   1317 
   1318     switch (e_ro_ndef_seq)
   1319     {
   1320         case ISO15693_RD_BEFORE_WR_CC:
   1321         {
   1322             if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
   1323             {
   1324                 result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
   1325                 /* Check CC bytes and also the card state for READ ONLY,
   1326                 if the card is already read only, then dont continue with
   1327                 next operation */
   1328                 if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState)
   1329                     && (!result))
   1330                 {
   1331                     /* CC byte read successful */
   1332                 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
   1333                                 sizeof (a_write_buf));
   1334 
   1335                     /* Change the read write access to read only */
   1336                 *(a_write_buf + ISO15693_RW_BTYE_INDEX) = (uint8_t)
   1337                             (*(a_write_buf + ISO15693_RW_BTYE_INDEX) |
   1338                             ISO15693_CC_READ_ONLY_MASK);
   1339 
   1340                 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
   1341                                     ISO15693_WRITE_COMMAND, a_write_buf,
   1342                                 sizeof (a_write_buf));
   1343 
   1344                 e_ro_ndef_seq = ISO15693_WRITE_CC;
   1345             }
   1346             }
   1347             break;
   1348         }
   1349 
   1350         case ISO15693_WRITE_CC:
   1351         {
   1352             /* Write to CC is successful. */
   1353             e_ro_ndef_seq = ISO15693_LOCK_BLOCK;
   1354             /* Start the lock block command to lock the blocks */
   1355             result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
   1356                                 ISO15693_LOCK_BLOCK_CMD, NULL, 0);
   1357             break;
   1358         }
   1359 
   1360         case ISO15693_LOCK_BLOCK:
   1361         {
   1362             if (ps_iso_15693_con->current_block ==
   1363                 ((ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK) -
   1364                 1))
   1365             {
   1366                 /* End of card reached, READ ONLY successful */
   1367             }
   1368             else
   1369             {
   1370                 /* current block is incremented */
   1371                 ps_iso_15693_con->current_block = (uint16_t)
   1372                     (ps_iso_15693_con->current_block + 1);
   1373                 /* Lock the current block */
   1374                 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
   1375                                 ISO15693_LOCK_BLOCK_CMD, NULL, 0);
   1376             }
   1377             break;
   1378         }
   1379 
   1380         default:
   1381         {
   1382             break;
   1383         }
   1384     }
   1385 
   1386     ps_iso_15693_con->ndef_seq = (uint8_t)e_ro_ndef_seq;
   1387     return result;
   1388 }
   1389 
   1390 #endif /* #ifdef FRINFC_READONLY_NDEF */
   1391 /************************** END static functions definition *********************/
   1392 
   1393 /************************** START external functions *********************/
   1394 
   1395 NFCSTATUS
   1396 phFriNfc_ISO15693_ChkNdef (
   1397     phFriNfc_NdefMap_t  *psNdefMap)
   1398 {
   1399     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
   1400     phHal_sIso15693Info_t           *ps_iso_15693_info =
   1401                         &(psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
   1402 
   1403     /* Update the previous operation with current operation.
   1404         This becomes the previous operation after this execution */
   1405     psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
   1406     /* Update the CR index to know from which operation completion
   1407         routine has to be called */
   1408     psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
   1409     /* State update */
   1410     psNdefMap->State = ISO15693_CHECK_NDEF;
   1411     /* Reset the NDEF sequence */
   1412     psNdefMap->ISO15693Container.ndef_seq = 0;
   1413     psNdefMap->ISO15693Container.current_block = 0;
   1414     psNdefMap->ISO15693Container.actual_ndef_size = 0;
   1415     psNdefMap->ISO15693Container.ndef_tlv_type_blk = 0;
   1416     psNdefMap->ISO15693Container.ndef_tlv_type_byte = 0;
   1417     psNdefMap->ISO15693Container.store_length = 0;
   1418     psNdefMap->ISO15693Container.remaining_size_to_read = 0;
   1419     psNdefMap->ISO15693Container.read_capabilities = 0;
   1420 
   1421     if ((ISO15693_UIDBYTE_6_VALUE ==
   1422         ps_iso_15693_info->Uid[ISO15693_UID_BYTE_6])
   1423         && (ISO15693_UIDBYTE_7_VALUE ==
   1424         ps_iso_15693_info->Uid[ISO15693_UID_BYTE_7]))
   1425     {
   1426         /* Check if the card is manufactured by NXP (6th byte
   1427             index of UID value = 0x04 and the
   1428             last byte i.e., 7th byte of UID is 0xE0, only then the card detected
   1429             is NDEF compliant */
   1430     switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_5])
   1431     {
   1432             /* Check for supported tags, by checking the 5th byte index of UID */
   1433         case ISO15693_UIDBYTE_5_VALUE_SLI_X:
   1434         {
   1435                 /* ISO 15693 card type is ICODE SLI
   1436                 so maximum size is 112 */
   1437             psNdefMap->ISO15693Container.max_data_size =
   1438                             ISO15693_SL2_S2002_ICS20;
   1439             break;
   1440         }
   1441 
   1442         case ISO15693_UIDBYTE_5_VALUE_SLI_X_S:
   1443         {
   1444                 /* ISO 15693 card type is ICODE SLI/X S
   1445                 so maximum size depends on the 4th UID byte index */
   1446             switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
   1447             {
   1448                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_S:
   1449                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC:
   1450                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_SY:
   1451                 {
   1452                         /* Supported tags are with value (4th byte UID index)
   1453                         of 0x00, 0x80 and 0x40
   1454                         For these cards max size is 160 bytes */
   1455                     psNdefMap->ISO15693Container.max_data_size =
   1456                                     ISO15693_SL2_S5302_ICS53_ICS54;
   1457                     break;
   1458                 }
   1459 
   1460                 default:
   1461                 {
   1462                         /* Tag not supported */
   1463                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1464                                         NFCSTATUS_INVALID_DEVICE_REQUEST);
   1465                     break;
   1466                 }
   1467             }
   1468             break;
   1469         }
   1470 
   1471         case ISO15693_UIDBYTE_5_VALUE_SLI_X_L:
   1472         {
   1473                 /* ISO 15693 card type is ICODE SLI/X L
   1474                 so maximum size depends on the 4th UID byte index */
   1475             switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
   1476             {
   1477                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_L:
   1478                 case ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC:
   1479                 {
   1480                         /* Supported tags are with value (4th byte UID index)
   1481                         of 0x00 and 0x80
   1482                         For these cards max size is 32 bytes */
   1483                     psNdefMap->ISO15693Container.max_data_size =
   1484                                     ISO15693_SL2_S5002_ICS50_ICS51;
   1485                     break;
   1486                 }
   1487 
   1488                 default:
   1489                 {
   1490                         /* Tag not supported */
   1491                     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1492                                         NFCSTATUS_INVALID_DEVICE_REQUEST);
   1493                     break;
   1494                 }
   1495             }
   1496             break;
   1497         }
   1498 
   1499         default:
   1500         {
   1501                 /* Tag not supported */
   1502             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1503                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
   1504             break;
   1505         }
   1506     }
   1507     }
   1508     else
   1509     {
   1510         /* Tag not supported */
   1511         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1512                             NFCSTATUS_INVALID_DEVICE_REQUEST);
   1513     }
   1514 
   1515     if (!result)
   1516     {
   1517         /* Start reading the data */
   1518         result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
   1519                                                 NULL, 0);
   1520     }
   1521 
   1522 
   1523     return result;
   1524 }
   1525 
   1526 NFCSTATUS
   1527 phFriNfc_ISO15693_RdNdef (
   1528     phFriNfc_NdefMap_t  *psNdefMap,
   1529     uint8_t             *pPacketData,
   1530     uint32_t            *pPacketDataLength,
   1531     uint8_t             Offset)
   1532 {
   1533     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   1534     phFriNfc_ISO15693Cont_t     *ps_iso_15693_con =
   1535                                 &(psNdefMap->ISO15693Container);
   1536 
   1537     /* Update the previous operation with current operation.
   1538         This becomes the previous operation after this execution */
   1539     psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
   1540     /* Update the CR index to know from which operation completion
   1541         routine has to be called */
   1542     psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
   1543     /* State update */
   1544     psNdefMap->State = ISO15693_READ_NDEF;
   1545     /* Copy user buffer to the context */
   1546     psNdefMap->ApduBuffer = pPacketData;
   1547     /* Copy user length to the context */
   1548     psNdefMap->ApduBufferSize = *pPacketDataLength;
   1549     /* Update the user memory size to a context variable */
   1550     psNdefMap->NumOfBytesRead = pPacketDataLength;
   1551     /* Number of bytes read from the card is zero.
   1552     This variable returns the number of bytes read
   1553     from the card. */
   1554     *psNdefMap->NumOfBytesRead = 0;
   1555     /* Index to know the length read */
   1556     psNdefMap->ApduBuffIndex = 0;
   1557     /* Store the offset in the context */
   1558     psNdefMap->Offset = Offset;
   1559 
   1560     if ((!ps_iso_15693_con->remaining_size_to_read)
   1561         && (!psNdefMap->Offset))
   1562     {
   1563         /* Entire data is already read from the card.
   1564         There is no data to give */
   1565         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1566                             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
   1567     }
   1568     else if (0 == ps_iso_15693_con->actual_ndef_size)
   1569     {
   1570         /* Card is NDEF, but no data in the card. */
   1571         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1572                             NFCSTATUS_READ_FAILED);
   1573     }
   1574     else if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
   1575     {
   1576         /* Card is NDEF, but no data in the card. */
   1577         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
   1578                             NFCSTATUS_READ_FAILED);
   1579     }
   1580     else if (psNdefMap->Offset)
   1581     {
   1582         /* BEGIN offset, so reset the remaining read size and
   1583         also the curretn block */
   1584         ps_iso_15693_con->remaining_size_to_read =
   1585                         ps_iso_15693_con->actual_ndef_size;
   1586         ps_iso_15693_con->current_block =
   1587                         ISO15693_GET_VALUE_FIELD_BLOCK_NO(
   1588                         ps_iso_15693_con->ndef_tlv_type_blk,
   1589                         ps_iso_15693_con->ndef_tlv_type_byte,
   1590                         ps_iso_15693_con->actual_ndef_size);
   1591 
   1592         // Check capabilities
   1593         if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
   1594             (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
   1595             result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
   1596         } else  {
   1597             result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
   1598                                                         NULL, 0);
   1599         }
   1600     }
   1601     else
   1602     {
   1603         /* CONTINUE offset */
   1604         if (ps_iso_15693_con->store_length > 0)
   1605         {
   1606             /* Previous read had extra bytes, so data is stored, so give that take
   1607             that data from store. If more data is required, then read remaining bytes */
   1608             result = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
   1609         }
   1610         else
   1611         {
   1612             ps_iso_15693_con->current_block = (uint16_t)
   1613                                 (ps_iso_15693_con->current_block + 1);
   1614             result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
   1615                                             ISO15693_READ_COMMAND, NULL, 0);
   1616         }
   1617     }
   1618 
   1619     return result;
   1620 }
   1621 
   1622 static
   1623 NFCSTATUS
   1624 phFriNfc_ReadRemainingInMultiple (
   1625     phFriNfc_NdefMap_t  *psNdefMap,
   1626     uint32_t            startBlock)
   1627 {
   1628     NFCSTATUS result = NFCSTATUS_FAILED;
   1629     phFriNfc_ISO15693Cont_t *ps_iso_15693_con = &(psNdefMap->ISO15693Container);
   1630 
   1631     uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
   1632                                            startBlock, 0);
   1633     // Check capabilities
   1634     if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) {
   1635         // Multi-page read command
   1636         uint8_t mbread[1];
   1637         mbread[0] = (remaining_size / ISO15693_BYTES_PER_BLOCK) - 1;
   1638         result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_MULTIPLE_COMMAND,
   1639                 mbread, 1);
   1640     } else if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR) {
   1641         uint32_t page = 0;
   1642         uint32_t pagesToRead = (remaining_size / ISO15693_BYTES_PER_BLOCK / 4) - 1;
   1643         if ((remaining_size % (ISO15693_BYTES_PER_BLOCK * ISO15693_BLOCKS_PER_PAGE)) != 0) {
   1644             pagesToRead++;
   1645         }
   1646         result = phFriNfc_ISO15693_H_Inventory_Page_Read (psNdefMap, ICODE_INVENTORY_PAGEREAD_COMMAND,
   1647                 page, pagesToRead);
   1648         // Inventory
   1649     } else  {
   1650         result = NFCSTATUS_FAILED;
   1651     }
   1652     return result;
   1653 }
   1654 
   1655 NFCSTATUS
   1656 phFriNfc_ISO15693_WrNdef (
   1657     phFriNfc_NdefMap_t  *psNdefMap,
   1658     uint8_t             *pPacketData,
   1659     uint32_t            *pPacketDataLength,
   1660     uint8_t             Offset)
   1661 {
   1662     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   1663     phFriNfc_ISO15693Cont_t     *ps_iso_15693_con =
   1664                                 &(psNdefMap->ISO15693Container);
   1665     uint8_t                     a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
   1666 
   1667     /* Update the previous operation with current operation.
   1668         This becomes the previous operation after this execution */
   1669     psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
   1670     /* Update the CR index to know from which operation completion
   1671         routine has to be called */
   1672     psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
   1673     /* State update */
   1674     psNdefMap->State = ISO15693_WRITE_NDEF;
   1675     /* Copy user buffer to the context */
   1676     psNdefMap->ApduBuffer = pPacketData;
   1677     /* Copy user length to the context */
   1678     psNdefMap->ApduBufferSize = *pPacketDataLength;
   1679     /* Update the user memory size to a context variable */
   1680     psNdefMap->NumOfBytesRead = pPacketDataLength;
   1681     /* Number of bytes written to the card is zero.
   1682     This variable returns the number of bytes written
   1683     to the card. */
   1684     *psNdefMap->WrNdefPacketLength = 0;
   1685     /* Index to know the length read */
   1686     psNdefMap->ApduBuffIndex = 0;
   1687     /* Store the offset in the context */
   1688     psNdefMap->Offset = Offset;
   1689 
   1690     /* Set the current block correctly to write the length field to 0 */
   1691     ps_iso_15693_con->current_block =
   1692                         ISO15693_GET_LEN_FIELD_BLOCK_NO(
   1693                         ps_iso_15693_con->ndef_tlv_type_blk,
   1694                         ps_iso_15693_con->ndef_tlv_type_byte,
   1695                         *pPacketDataLength);
   1696 
   1697     if (ISO15693_GET_LEN_FIELD_BYTE_NO(
   1698                         ps_iso_15693_con->ndef_tlv_type_blk,
   1699                         ps_iso_15693_con->ndef_tlv_type_byte,
   1700                         *pPacketDataLength))
   1701     {
   1702         /* Check the byte address to write. If length byte address is in between or
   1703         is the last byte of the block, then READ before write
   1704         reason, write should not corrupt other data
   1705         */
   1706         ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_NDEF_L_0;
   1707         result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
   1708                                 ISO15693_READ_COMMAND, NULL, 0);
   1709     }
   1710     else
   1711     {
   1712         /* If length byte address is at the beginning of the block then WRITE
   1713         length field to 0 and as also write user DATA */
   1714         ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_WRITE_DATA;
   1715 
   1716         /* Length is made 0x00 */
   1717         *a_write_buf = 0x00;
   1718 
   1719         /* Write remaining data */
   1720         (void)memcpy ((void *)(a_write_buf + 1),
   1721                         (void *)psNdefMap->ApduBuffer,
   1722                         (ISO15693_BYTES_PER_BLOCK - 1));
   1723 
   1724         /* Write data */
   1725         result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
   1726                                     ISO15693_WRITE_COMMAND,
   1727                                     a_write_buf, ISO15693_BYTES_PER_BLOCK);
   1728 
   1729         /* Increment the index to keep track of bytes sent for write */
   1730         psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex
   1731                                         + (ISO15693_BYTES_PER_BLOCK - 1));
   1732     }
   1733 
   1734     return result;
   1735 }
   1736 
   1737 #ifdef FRINFC_READONLY_NDEF
   1738 
   1739 NFCSTATUS
   1740 phFriNfc_ISO15693_ConvertToReadOnly (
   1741     phFriNfc_NdefMap_t  *psNdefMap)
   1742 {
   1743     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
   1744     phFriNfc_ISO15693Cont_t     *ps_iso_15693_con =
   1745                                 &(psNdefMap->ISO15693Container);
   1746 
   1747     psNdefMap->State = ISO15693_READ_ONLY_NDEF;
   1748     /* READ CC bytes */
   1749     ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_CC;
   1750     ps_iso_15693_con->current_block = 0;
   1751 
   1752     result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
   1753                                     ISO15693_READ_COMMAND, NULL, 0);
   1754 
   1755     return result;
   1756 }
   1757 
   1758 #endif /* #ifdef FRINFC_READONLY_NDEF */
   1759 
   1760 
   1761 void
   1762 phFriNfc_ISO15693_Process (
   1763     void        *pContext,
   1764     NFCSTATUS   Status)
   1765 {
   1766     phFriNfc_NdefMap_t      *psNdefMap =
   1767                             (phFriNfc_NdefMap_t *)pContext;
   1768 
   1769     if ((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
   1770     {
   1771         switch (psNdefMap->State)
   1772         {
   1773             case ISO15693_CHECK_NDEF:
   1774             {
   1775                 /* State = CHECK NDEF in progress */
   1776                 Status = phFriNfc_ISO15693_H_ProcessCheckNdef (psNdefMap);
   1777                 break;
   1778             }
   1779 
   1780             case ISO15693_READ_NDEF:
   1781             {
   1782                 /* State = READ NDEF in progress */
   1783                 Status = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
   1784                 break;
   1785             }
   1786 
   1787             case ISO15693_WRITE_NDEF:
   1788             {
   1789                 /* State = WRITE NDEF in progress */
   1790                 Status = phFriNfc_ISO15693_H_ProcessWriteNdef (psNdefMap);
   1791                 break;
   1792             }
   1793 
   1794 #ifdef FRINFC_READONLY_NDEF
   1795             case ISO15693_READ_ONLY_NDEF:
   1796             {
   1797                 /* State = RAD ONLY NDEF in progress */
   1798                 Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap);
   1799                 break;
   1800             }
   1801 #endif /* #ifdef FRINFC_READONLY_NDEF */
   1802 
   1803             default:
   1804             {
   1805                 break;
   1806             }
   1807         }
   1808     }
   1809 
   1810     /* Call for the Completion Routine*/
   1811     if (NFCSTATUS_PENDING != Status)
   1812     {
   1813         phFriNfc_ISO15693_H_Complete(psNdefMap, Status);
   1814     }
   1815 }
   1816 
   1817 /************************** END external functions *********************/
   1818 
   1819 #endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
   1820