Initialize Tizen 2.3
[adaptation/devices/nfc-plugin-nxp.git] / src / phFriNfc_ISO15693Map.c
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 */