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
46typedef 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
56typedef 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
67typedef 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
129CHECK 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
152Magic 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.
206Inputs are
2071. maximum data size
2082. block number
2093. 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 *********************/
226static
227NFCSTATUS
228phFriNfc_ISO15693_H_ProcessReadOnly (
229    phFriNfc_NdefMap_t      *psNdefMap);
230
231static
232NFCSTATUS
233phFriNfc_ISO15693_H_ProcessWriteNdef (
234    phFriNfc_NdefMap_t      *psNdefMap);
235
236static
237NFCSTATUS
238phFriNfc_ISO15693_H_ProcessReadNdef (
239    phFriNfc_NdefMap_t      *psNdefMap);
240
241static
242NFCSTATUS
243phFriNfc_ISO15693_H_ProcessCheckNdef (
244    phFriNfc_NdefMap_t      *psNdefMap);
245
246static
247void
248phFriNfc_ISO15693_H_Complete (
249    phFriNfc_NdefMap_t      *psNdefMap,
250    NFCSTATUS               Status);
251
252static
253NFCSTATUS
254phFriNfc_ISO15693_H_ReadWrite (
255    phFriNfc_NdefMap_t      *psNdefMap,
256    uint8_t                 command,
257    uint8_t                 *p_data,
258    uint8_t                 data_length);
259
260static
261NFCSTATUS
262phFriNfc_ReadRemainingInMultiple (
263    phFriNfc_NdefMap_t  *psNdefMap,
264    uint32_t            startBlock);
265
266/************************** END static functions declaration *********************/
267
268/************************** START static functions definition *********************/
269
270static
271NFCSTATUS
272phFriNfc_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
451static
452NFCSTATUS
453phFriNfc_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
512static
513NFCSTATUS
514phFriNfc_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
576static
577NFCSTATUS
578phFriNfc_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
613static
614NFCSTATUS
615phFriNfc_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
789static
790NFCSTATUS
791phFriNfc_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
860static
861NFCSTATUS
862phFriNfc_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
1286static
1287void
1288phFriNfc_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
1302static
1303NFCSTATUS
1304phFriNfc_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
1395NFCSTATUS
1396phFriNfc_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
1526NFCSTATUS
1527phFriNfc_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
1622static
1623NFCSTATUS
1624phFriNfc_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
1655NFCSTATUS
1656phFriNfc_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
1739NFCSTATUS
1740phFriNfc_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
1761void
1762phFriNfc_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