• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
phFriNfc_ISO15693_H_ProcessWriteNdef(phFriNfc_NdefMap_t * psNdefMap)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
phFriNfc_ISO15693_H_ReadWrite(phFriNfc_NdefMap_t * psNdefMap,uint8_t command,uint8_t * p_data,uint8_t data_length)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
phFriNfc_ISO15693_H_Inventory_Page_Read(phFriNfc_NdefMap_t * psNdefMap,uint8_t command,uint8_t page,uint8_t numPages)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
phFriNfc_ISO15693_Reformat_Pageread_Buffer(uint8_t * p_recv_buf,uint8_t recv_length,uint8_t * p_dst_buf,uint8_t dst_length)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
phFriNfc_ISO15693_H_ProcessReadNdef(phFriNfc_NdefMap_t * psNdefMap)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
phFriNfc_ISO15693_H_CheckCCBytes(phFriNfc_NdefMap_t * psNdefMap)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
phFriNfc_ISO15693_H_ProcessCheckNdef(phFriNfc_NdefMap_t * psNdefMap)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
phFriNfc_ISO15693_H_Complete(phFriNfc_NdefMap_t * psNdefMap,NFCSTATUS Status)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
phFriNfc_ISO15693_H_ProcessReadOnly(phFriNfc_NdefMap_t * psNdefMap)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
phFriNfc_ISO15693_ChkNdef(phFriNfc_NdefMap_t * psNdefMap)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
phFriNfc_ISO15693_RdNdef(phFriNfc_NdefMap_t * psNdefMap,uint8_t * pPacketData,uint32_t * pPacketDataLength,uint8_t Offset)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
phFriNfc_ReadRemainingInMultiple(phFriNfc_NdefMap_t * psNdefMap,uint32_t startBlock)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
phFriNfc_ISO15693_WrNdef(phFriNfc_NdefMap_t * psNdefMap,uint8_t * pPacketData,uint32_t * pPacketDataLength,uint8_t Offset)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
phFriNfc_ISO15693_ConvertToReadOnly(phFriNfc_NdefMap_t * psNdefMap)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
phFriNfc_ISO15693_Process(void * pContext,NFCSTATUS Status)1762 phFriNfc_ISO15693_Process (
1763     void        *pContext,
1764     NFCSTATUS   Status)
1765 {
1766     phFriNfc_NdefMap_t      *psNdefMap =
1767                             (phFriNfc_NdefMap_t *)pContext;
1768 
1769     if ((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
1770     {
1771         switch (psNdefMap->State)
1772         {
1773             case ISO15693_CHECK_NDEF:
1774             {
1775                 /* State = CHECK NDEF in progress */
1776                 Status = phFriNfc_ISO15693_H_ProcessCheckNdef (psNdefMap);
1777                 break;
1778             }
1779 
1780             case ISO15693_READ_NDEF:
1781             {
1782                 /* State = READ NDEF in progress */
1783                 Status = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
1784                 break;
1785             }
1786 
1787             case ISO15693_WRITE_NDEF:
1788             {
1789                 /* State = WRITE NDEF in progress */
1790                 Status = phFriNfc_ISO15693_H_ProcessWriteNdef (psNdefMap);
1791                 break;
1792             }
1793 
1794 #ifdef FRINFC_READONLY_NDEF
1795             case ISO15693_READ_ONLY_NDEF:
1796             {
1797                 /* State = RAD ONLY NDEF in progress */
1798                 Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap);
1799                 break;
1800             }
1801 #endif /* #ifdef FRINFC_READONLY_NDEF */
1802 
1803             default:
1804             {
1805                 break;
1806             }
1807         }
1808     }
1809 
1810     /* Call for the Completion Routine*/
1811     if (NFCSTATUS_PENDING != Status)
1812     {
1813         phFriNfc_ISO15693_H_Complete(psNdefMap, Status);
1814     }
1815 }
1816 
1817 /************************** END external functions *********************/
1818 
1819 #endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
1820