3 * Copyright (C) 2010 NXP Semiconductors
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * \file phFriNfc_ISO15693Map.c
20 * \brief This component encapsulates read/write/check ndef/process functionalities,
21 * for the ISO-15693 Card.
32 #ifndef PH_FRINFC_MAP_ISO15693_DISABLED
34 #include <phNfcTypes.h>
35 #include <phNfcConfig.h>
36 #include <phNfcInterface.h>
37 #include <phNfcHalTypes.h>
39 #include <phFriNfc_NdefMap.h>
40 #include <phFriNfc_OvrHal.h>
41 #include <phFriNfc_MapTools.h>
42 #include <phFriNfc_ISO15693Map.h>
44 /************************** START DATA STRUCTURE *********************/
46 typedef enum phFriNfc_eChkNdefSeq
54 }phFriNfc_eChkNdefSeq_t;
56 typedef enum phFriNfc_eWrNdefSeq
58 ISO15693_RD_BEFORE_WR_NDEF_L_0,
60 ISO15693_RD_BEFORE_WR_NDEF_L,
61 ISO15693_WRITE_NDEF_TLV_L
63 }phFriNfc_eWrNdefSeq_t;
65 #ifdef FRINFC_READONLY_NDEF
67 typedef enum phFriNfc_eRONdefSeq
69 ISO15693_RD_BEFORE_WR_CC,
73 }phFriNfc_eRONdefSeq_t;
75 #endif /* #ifdef FRINFC_READONLY_NDEF */
77 /************************** END DATA STRUCTURE *********************/
79 /************************** START MACROS definition *********************/
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
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
100 #define ISO15693_UIDBYTE_5_VALUE_SLI_X 0x01U
101 /* Card size SL2 ICS20 / SL2S2002 */
102 #define ISO15693_SL2_S2002_ICS20 112U
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
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
128 /* State Machine declaration
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
137 /* READ ONLY NDEF state */
138 #define ISO15693_READ_ONLY_NDEF 0x04U
140 /* READ ONLY MASK byte for CC */
141 #define ISO15693_CC_READ_ONLY_MASK 0x03U
143 /* CC READ WRITE index */
144 #define ISO15693_RW_BTYE_INDEX 0x01U
146 /* LOCK BLOCK command */
147 #define ISO15693_LOCK_BLOCK_CMD 0x22U
149 #endif /* #ifdef FRINFC_READONLY_NDEF */
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
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
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
173 /* READ command identifier */
174 #define ISO15693_READ_COMMAND 0x20U
176 /* READ multiple command identifier */
177 #define ISO15693_READ_MULTIPLE_COMMAND 0x23U
179 /* INVENTORY pageread command identifier */
180 #define ICODE_INVENTORY_PAGEREAD_COMMAND 0xB0U
181 #define INVENTORY_PAGEREAD_FLAGS 0x24U
182 #define NXP_MANUFACTURING_CODE 0x04U
184 /* WRITE command identifier */
185 #define ISO15693_WRITE_COMMAND 0x21U
187 #define ISO15693_FLAGS 0x20U
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
197 #define ISO15693_BTYE_SHIFT 0x08U
199 /* Proprietary TLV TYPE identifier */
200 #define ISO15693_PROP_TLV_ID 0xFDU
202 /* CC SIZE in BYTES */
203 #define ISO15693_CC_SIZE 0x04U
205 /* To get the remaining size in the card.
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))
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)
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))
223 /************************** END MACROS definition *********************/
225 /************************** START static functions declaration *********************/
228 phFriNfc_ISO15693_H_ProcessReadOnly (
229 phFriNfc_NdefMap_t *psNdefMap);
233 phFriNfc_ISO15693_H_ProcessWriteNdef (
234 phFriNfc_NdefMap_t *psNdefMap);
238 phFriNfc_ISO15693_H_ProcessReadNdef (
239 phFriNfc_NdefMap_t *psNdefMap);
243 phFriNfc_ISO15693_H_ProcessCheckNdef (
244 phFriNfc_NdefMap_t *psNdefMap);
248 phFriNfc_ISO15693_H_Complete (
249 phFriNfc_NdefMap_t *psNdefMap,
254 phFriNfc_ISO15693_H_ReadWrite (
255 phFriNfc_NdefMap_t *psNdefMap,
258 uint8_t data_length);
262 phFriNfc_ReadRemainingInMultiple (
263 phFriNfc_NdefMap_t *psNdefMap,
264 uint32_t startBlock);
266 /************************** END static functions declaration *********************/
268 /************************** START static functions definition *********************/
272 phFriNfc_ISO15693_H_ProcessWriteNdef (
273 phFriNfc_NdefMap_t *psNdefMap)
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;
286 switch (e_wr_ndef_seq)
288 case ISO15693_RD_BEFORE_WR_NDEF_L_0:
291 p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
292 recv_length = (uint8_t)
293 (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
295 if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
297 /* Response length is correct */
298 uint8_t byte_index = 0;
300 /* Copy the recevied buffer */
301 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
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);
309 /* Writing length field to 0, Update length field to 0 */
310 *(a_write_buf + byte_index) = 0x00;
312 if ((ISO15693_BYTES_PER_BLOCK - 1) != byte_index)
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);
319 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
322 remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
323 psNdefMap->ApduBuffIndex);
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);
331 /* Write index updated */
332 psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
336 /* After this write, user data can be written.
337 Update the sequence accordingly */
338 e_wr_ndef_seq = ISO15693_WRITE_DATA;
340 } /* if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) */
343 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
344 NFCSTATUS_INVALID_RECEIVE_LENGTH);
347 } /* case ISO15693_RD_BEFORE_WR_NDEF_L_0: */
349 case ISO15693_RD_BEFORE_WR_NDEF_L:
351 p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
352 recv_length = (uint8_t)(*psNdefMap->SendRecvLength -
353 ISO15693_EXTRA_RESP_BYTE);
355 if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
357 uint8_t byte_index = 0;
359 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
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);
367 *(a_write_buf + byte_index) = (uint8_t)psNdefMap->ApduBuffIndex;
368 e_wr_ndef_seq = ISO15693_WRITE_NDEF_TLV_L;
373 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
374 NFCSTATUS_INVALID_RECEIVE_LENGTH);
379 case ISO15693_WRITE_DATA:
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)))
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;
394 remaining_size = ISO15693_BYTES_PER_BLOCK;
396 ps_iso_15693_con->current_block = (uint16_t)
397 (ps_iso_15693_con->current_block + 1);
399 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
402 remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
403 psNdefMap->ApduBuffIndex);
406 (void)memcpy ((void *)a_write_buf, (void *)
407 (psNdefMap->ApduBuffer +
408 psNdefMap->ApduBuffIndex), remaining_size);
410 psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
415 } /* case ISO15693_WRITE_DATA: */
417 case ISO15693_WRITE_NDEF_TLV_L:
419 *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex;
420 ps_iso_15693_con->actual_ndef_size = psNdefMap->ApduBuffIndex;
428 } /* switch (e_wr_ndef_seq) */
430 if (((0 == psNdefMap->ApduBuffIndex)
431 || (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex))
434 if (FALSE == write_flag)
436 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
437 ISO15693_READ_COMMAND, NULL, 0);
441 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
442 ISO15693_WRITE_COMMAND,
443 a_write_buf, sizeof (a_write_buf));
447 psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_wr_ndef_seq;
453 phFriNfc_ISO15693_H_ReadWrite (
454 phFriNfc_NdefMap_t *psNdefMap,
459 NFCSTATUS result = NFCSTATUS_SUCCESS;
460 uint8_t send_index = 0;
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;
467 psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
468 psNdefMap->MapCompletionInfo.Context = psNdefMap;
470 *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
472 psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
474 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)ISO15693_FLAGS;
475 send_index = (uint8_t)(send_index + 1);
477 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
478 send_index = (uint8_t)(send_index + 1);
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);
486 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
487 psNdefMap->ISO15693Container.current_block;
488 send_index = (uint8_t)(send_index + 1);
490 if ((ISO15693_WRITE_COMMAND == command) ||
491 (ISO15693_READ_MULTIPLE_COMMAND == command))
493 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
494 (void *)p_data, data_length);
495 send_index = (uint8_t)(send_index + data_length);
498 psNdefMap->SendLength = send_index;
499 result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
500 &psNdefMap->MapCompletionInfo,
501 psNdefMap->psRemoteDevInfo,
503 &psNdefMap->psDepAdditionalInfo,
504 psNdefMap->SendRecvBuf,
505 psNdefMap->SendLength,
506 psNdefMap->SendRecvBuf,
507 psNdefMap->SendRecvLength);
514 phFriNfc_ISO15693_H_Inventory_Page_Read (
515 phFriNfc_NdefMap_t *psNdefMap,
520 NFCSTATUS result = NFCSTATUS_SUCCESS;
521 uint8_t send_index = 0;
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;
528 psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
529 psNdefMap->MapCompletionInfo.Context = psNdefMap;
531 *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
533 psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
535 *(psNdefMap->SendRecvBuf + send_index) = INVENTORY_PAGEREAD_FLAGS;
536 send_index = (uint8_t)(send_index + 1);
538 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
539 send_index = (uint8_t)(send_index + 1);
541 *(psNdefMap->SendRecvBuf + send_index) = NXP_MANUFACTURING_CODE;
542 send_index = (uint8_t)(send_index + 1);
544 *(psNdefMap->SendRecvBuf + send_index) = 0x40;
545 send_index = (uint8_t)(send_index + 1);
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);
553 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
555 send_index = (uint8_t)(send_index + 1);
557 *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
559 send_index = (uint8_t)(send_index + 1);
561 psNdefMap->SendLength = send_index;
563 result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
564 &psNdefMap->MapCompletionInfo,
565 psNdefMap->psRemoteDevInfo,
567 &psNdefMap->psDepAdditionalInfo,
568 psNdefMap->SendRecvBuf,
569 psNdefMap->SendLength,
570 psNdefMap->SendRecvBuf,
571 psNdefMap->SendRecvLength);
578 phFriNfc_ISO15693_Reformat_Pageread_Buffer (
584 // Inventory page reads return an extra security byte per page
585 // So we need to reformat the returned buffer in memory
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) {
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;
599 // Skip security byte
601 if (i + 16 <= recv_length) {
602 memcpy(&(p_dst_buf[reformatted_index]), &(p_recv_buf[i]), 16);
603 reformatted_index += 16;
610 return reformatted_index;
615 phFriNfc_ISO15693_H_ProcessReadNdef (
616 phFriNfc_NdefMap_t *psNdefMap)
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);
627 uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size);
629 if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)
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);
636 if (ps_iso_15693_con->store_length)
638 /* Continue Offset option selected
639 So stored data already existing,
640 copy the information to the user buffer
642 if (ps_iso_15693_con->store_length
643 <= (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex))
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);
652 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
653 ps_iso_15693_con->store_length);
655 remaining_data_size = ps_iso_15693_con->store_length;
657 ps_iso_15693_con->store_length = 0;
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));
665 (void)memcpy ((void *)(psNdefMap->ApduBuffer +
666 psNdefMap->ApduBuffIndex),
667 (void *)ps_iso_15693_con->store_read_data,
668 remaining_data_size);
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));
677 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
678 remaining_data_size);
680 ps_iso_15693_con->store_length = (uint8_t)
681 (ps_iso_15693_con->store_length - remaining_data_size);
683 } /* if (ps_iso_15693_con->store_length) */
686 /* Data is read from the card. */
687 uint8_t byte_index = 0;
689 remaining_data_size = ps_iso_15693_con->remaining_size_to_read;
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)
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);
705 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
706 < remaining_data_size)
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)
714 /* user data required is less than the data read */
715 remaining_data_size = (uint8_t)(psNdefMap->ApduBufferSize -
716 psNdefMap->ApduBuffIndex);
718 if (0 != (recv_length - (byte_index +
719 remaining_data_size)))
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)));
728 ps_iso_15693_con->store_length = (uint8_t)
729 (recv_length - (byte_index +
730 remaining_data_size));
736 /* user data required is equal or greater than the data read */
737 if (remaining_data_size > (recv_length - byte_index))
739 remaining_data_size = (uint8_t)
740 (recv_length - byte_index);
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);
750 /* Update the read index */
751 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
752 remaining_data_size);
754 } /* else part of if (ps_iso_15693_con->store_length) */
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);
761 if ((psNdefMap->ApduBuffIndex != psNdefMap->ApduBufferSize)
762 && (0 != ps_iso_15693_con->remaining_size_to_read))
764 ps_iso_15693_con->current_block = (uint16_t)
765 (ps_iso_15693_con->current_block + 1);
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);
772 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
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;
783 if (reformatted_buf != NULL) {
784 phOsalNfc_FreeMemory(reformatted_buf);
791 phFriNfc_ISO15693_H_CheckCCBytes (
792 phFriNfc_NdefMap_t *psNdefMap)
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);
800 /* expected CC byte : E1 40 "MAX SIZE depends on tag" */
801 if (ISO15693_CC_MAGIC_BYTE == *p_recv_buf)
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)
808 /* Correct mapping version found */
809 switch (*(p_recv_buf + recv_index) & ISO15693_LSB_NIBBLE_MASK)
811 case ISO15693_RD_WR_PERMISSION:
813 /* READ/WRITE possible */
814 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
818 case ISO15693_RD_ONLY_PERMISSION:
820 /* ONLY READ possible, WRITE NOT possible */
821 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
827 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
828 NFCSTATUS_NO_NDEF_SUPPORT);
832 recv_index = (uint8_t)(recv_index + 1);
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));
848 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
849 NFCSTATUS_NO_NDEF_SUPPORT);
854 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
855 NFCSTATUS_NO_NDEF_SUPPORT);
862 phFriNfc_ISO15693_H_ProcessCheckNdef (
863 phFriNfc_NdefMap_t *psNdefMap)
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;
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);
879 if (0 == ps_iso_15693_con->current_block)
882 result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
883 parse_index = (uint8_t)(parse_index + recv_length);
885 else if (1 == ps_iso_15693_con->current_block &&
886 (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR))
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);
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)
902 parse_index = ps_iso_15693_con->ndef_tlv_type_byte;
903 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
907 while ((parse_index < recv_length)
908 && (NFCSTATUS_SUCCESS == result)
909 && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq))
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
916 switch (e_chk_ndef_seq)
918 case ISO15693_NDEF_TLV_T:
920 /* Expected value is 0x03 TYPE identifier
923 switch (*(p_recv_buf + parse_index))
925 case ISO15693_NDEF_TLV_TYPE_ID:
927 /* Update the data structure with the byte address and
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;
937 case ISO15693_NULL_TLV_ID:
939 /* Dont do any thing, go to next byte */
943 case ISO15693_PROP_TLV_ID:
945 /* Move the sequence to find the length
946 of the proprietary TLV */
947 e_chk_ndef_seq = ISO15693_PROP_TLV_L;
953 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
954 NFCSTATUS_NO_NDEF_SUPPORT);
957 } /* switch (*(p_recv_buf + parse_index)) */
961 case ISO15693_PROP_TLV_L:
963 /* Length field of the proprietary TLV */
964 switch (prop_ndef_index)
966 /* Length field can have 1 or 3 bytes depending
967 on the data size, so check for each index byte */
970 /* 1st index of the length field of the TLV */
971 if (0 == *(p_recv_buf + parse_index))
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;
980 if (ISO15693_THREE_BYTE_LENGTH_ID ==
981 *(p_recv_buf + parse_index))
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);
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
993 ps_iso_15693_con->actual_ndef_size =
994 *(p_recv_buf + parse_index);
995 e_chk_ndef_seq = ISO15693_PROP_TLV_V;
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);
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));
1021 e_chk_ndef_seq = ISO15693_PROP_TLV_V;
1022 prop_ndef_index = 0;
1028 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1029 NFCSTATUS_INVALID_DEVICE_REQUEST);
1032 } /* switch (prop_ndef_index) */
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))
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);
1047 uint16_t prop_byte_addr = 0;
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);
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 >=
1061 parse_index = (uint8_t)recv_length;
1065 parse_index = (uint8_t)(parse_index +
1066 ps_iso_15693_con->actual_ndef_size);
1071 } /* case ISO15693_PROP_TLV_L: */
1073 case ISO15693_PROP_TLV_V:
1075 uint8_t remaining_length = (uint8_t)(recv_length -
1078 if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
1081 parse_index = (uint8_t)(parse_index + remaining_length);
1082 prop_ndef_index = (uint8_t)(prop_ndef_index + remaining_length);
1084 else if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
1085 == remaining_length)
1087 parse_index = (uint8_t)(parse_index + remaining_length);
1088 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1089 prop_ndef_index = 0;
1093 parse_index = (uint8_t)(parse_index +
1094 (ps_iso_15693_con->actual_ndef_size -
1096 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1097 prop_ndef_index = 0;
1100 } /* case ISO15693_PROP_TLV_V: */
1102 case ISO15693_NDEF_TLV_L:
1104 /* Length field of the NDEF TLV */
1105 switch (prop_ndef_index)
1107 /* Length field can have 1 or 3 bytes depending
1108 on the data size, so check for each index byte */
1111 /* 1st index of the length field of the TLV */
1112 if (0 == *(p_recv_buf + parse_index))
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;
1120 prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
1122 if (ISO15693_THREE_BYTE_LENGTH_ID ==
1123 *(p_recv_buf + parse_index))
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;
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
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;
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);
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));
1167 e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
1168 prop_ndef_index = 0;
1174 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1175 NFCSTATUS_INVALID_DEVICE_REQUEST);
1178 } /* switch (prop_ndef_index) */
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
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))
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);
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));
1208 } /* case ISO15693_NDEF_TLV_L: */
1210 case ISO15693_NDEF_TLV_V:
1217 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1218 NFCSTATUS_INVALID_DEVICE_REQUEST);
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)) */
1229 /* Error returned while parsing, so STOP read */
1230 e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
1231 prop_ndef_index = 0;
1233 else if (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)
1236 if (ISO15693_PROP_TLV_V != e_chk_ndef_seq)
1238 ps_iso_15693_con->current_block = (uint16_t)
1239 (ps_iso_15693_con->current_block + 1);
1243 /* Proprietary TLV detected, so skip the proprietary blocks */
1244 ps_iso_15693_con->current_block = ps_iso_15693_con->ndef_tlv_type_blk;
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)
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);
1255 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
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);
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;
1278 psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_chk_ndef_seq;
1280 if (reformatted_buf != NULL) {
1281 phOsalNfc_FreeMemory(reformatted_buf);
1288 phFriNfc_ISO15693_H_Complete (
1289 phFriNfc_NdefMap_t *psNdefMap,
1292 /* set the state back to the RESET_INIT state*/
1293 psNdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
1295 /* set the completion routine*/
1296 psNdefMap->CompletionRoutine[psNdefMap->ISO15693Container.cr_index].
1297 CompletionRoutine (psNdefMap->CompletionRoutine->Context, Status);
1300 #ifdef FRINFC_READONLY_NDEF
1304 phFriNfc_ISO15693_H_ProcessReadOnly (
1305 phFriNfc_NdefMap_t *psNdefMap)
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};
1318 switch (e_ro_ndef_seq)
1320 case ISO15693_RD_BEFORE_WR_CC:
1322 if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
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
1328 if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState)
1331 /* CC byte read successful */
1332 (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
1333 sizeof (a_write_buf));
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);
1340 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1341 ISO15693_WRITE_COMMAND, a_write_buf,
1342 sizeof (a_write_buf));
1344 e_ro_ndef_seq = ISO15693_WRITE_CC;
1350 case ISO15693_WRITE_CC:
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);
1360 case ISO15693_LOCK_BLOCK:
1362 if (ps_iso_15693_con->current_block ==
1363 ((ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK) -
1366 /* End of card reached, READ ONLY successful */
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);
1386 ps_iso_15693_con->ndef_seq = (uint8_t)e_ro_ndef_seq;
1390 #endif /* #ifdef FRINFC_READONLY_NDEF */
1391 /************************** END static functions definition *********************/
1393 /************************** START external functions *********************/
1396 phFriNfc_ISO15693_ChkNdef (
1397 phFriNfc_NdefMap_t *psNdefMap)
1399 NFCSTATUS result = NFCSTATUS_SUCCESS;
1400 phHal_sIso15693Info_t *ps_iso_15693_info =
1401 &(psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
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;
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;
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]))
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])
1432 /* Check for supported tags, by checking the 5th byte index of UID */
1433 case ISO15693_UIDBYTE_5_VALUE_SLI_X:
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;
1442 case ISO15693_UIDBYTE_5_VALUE_SLI_X_S:
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])
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:
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;
1462 /* Tag not supported */
1463 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1464 NFCSTATUS_INVALID_DEVICE_REQUEST);
1471 case ISO15693_UIDBYTE_5_VALUE_SLI_X_L:
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])
1477 case ISO15693_UIDBYTE_4_VALUE_SLI_X_L:
1478 case ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC:
1480 /* Supported tags are with value (4th byte UID index)
1482 For these cards max size is 32 bytes */
1483 psNdefMap->ISO15693Container.max_data_size =
1484 ISO15693_SL2_S5002_ICS50_ICS51;
1490 /* Tag not supported */
1491 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1492 NFCSTATUS_INVALID_DEVICE_REQUEST);
1501 /* Tag not supported */
1502 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1503 NFCSTATUS_INVALID_DEVICE_REQUEST);
1510 /* Tag not supported */
1511 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1512 NFCSTATUS_INVALID_DEVICE_REQUEST);
1517 /* Start reading the data */
1518 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
1527 phFriNfc_ISO15693_RdNdef (
1528 phFriNfc_NdefMap_t *psNdefMap,
1529 uint8_t *pPacketData,
1530 uint32_t *pPacketDataLength,
1533 NFCSTATUS result = NFCSTATUS_SUCCESS;
1534 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
1535 &(psNdefMap->ISO15693Container);
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;
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
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;
1560 if ((!ps_iso_15693_con->remaining_size_to_read)
1561 && (!psNdefMap->Offset))
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);
1568 else if (0 == ps_iso_15693_con->actual_ndef_size)
1570 /* Card is NDEF, but no data in the card. */
1571 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1572 NFCSTATUS_READ_FAILED);
1574 else if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
1576 /* Card is NDEF, but no data in the card. */
1577 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1578 NFCSTATUS_READ_FAILED);
1580 else if (psNdefMap->Offset)
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);
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);
1597 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
1603 /* CONTINUE offset */
1604 if (ps_iso_15693_con->store_length > 0)
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);
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);
1624 phFriNfc_ReadRemainingInMultiple (
1625 phFriNfc_NdefMap_t *psNdefMap,
1626 uint32_t startBlock)
1628 NFCSTATUS result = NFCSTATUS_FAILED;
1629 phFriNfc_ISO15693Cont_t *ps_iso_15693_con = &(psNdefMap->ISO15693Container);
1631 uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
1633 // Check capabilities
1634 if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) {
1635 // Multi-page read command
1637 mbread[0] = (remaining_size / ISO15693_BYTES_PER_BLOCK) - 1;
1638 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_MULTIPLE_COMMAND,
1640 } else if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR) {
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) {
1646 result = phFriNfc_ISO15693_H_Inventory_Page_Read (psNdefMap, ICODE_INVENTORY_PAGEREAD_COMMAND,
1650 result = NFCSTATUS_FAILED;
1656 phFriNfc_ISO15693_WrNdef (
1657 phFriNfc_NdefMap_t *psNdefMap,
1658 uint8_t *pPacketData,
1659 uint32_t *pPacketDataLength,
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};
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;
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
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;
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);
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))
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
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);
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;
1716 /* Length is made 0x00 */
1717 *a_write_buf = 0x00;
1719 /* Write remaining data */
1720 (void)memcpy ((void *)(a_write_buf + 1),
1721 (void *)psNdefMap->ApduBuffer,
1722 (ISO15693_BYTES_PER_BLOCK - 1));
1725 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1726 ISO15693_WRITE_COMMAND,
1727 a_write_buf, ISO15693_BYTES_PER_BLOCK);
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));
1737 #ifdef FRINFC_READONLY_NDEF
1740 phFriNfc_ISO15693_ConvertToReadOnly (
1741 phFriNfc_NdefMap_t *psNdefMap)
1743 NFCSTATUS result = NFCSTATUS_SUCCESS;
1744 phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
1745 &(psNdefMap->ISO15693Container);
1747 psNdefMap->State = ISO15693_READ_ONLY_NDEF;
1749 ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_CC;
1750 ps_iso_15693_con->current_block = 0;
1752 result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
1753 ISO15693_READ_COMMAND, NULL, 0);
1758 #endif /* #ifdef FRINFC_READONLY_NDEF */
1762 phFriNfc_ISO15693_Process (
1766 phFriNfc_NdefMap_t *psNdefMap =
1767 (phFriNfc_NdefMap_t *)pContext;
1769 if ((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
1771 switch (psNdefMap->State)
1773 case ISO15693_CHECK_NDEF:
1775 /* State = CHECK NDEF in progress */
1776 Status = phFriNfc_ISO15693_H_ProcessCheckNdef (psNdefMap);
1780 case ISO15693_READ_NDEF:
1782 /* State = READ NDEF in progress */
1783 Status = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
1787 case ISO15693_WRITE_NDEF:
1789 /* State = WRITE NDEF in progress */
1790 Status = phFriNfc_ISO15693_H_ProcessWriteNdef (psNdefMap);
1794 #ifdef FRINFC_READONLY_NDEF
1795 case ISO15693_READ_ONLY_NDEF:
1797 /* State = RAD ONLY NDEF in progress */
1798 Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap);
1801 #endif /* #ifdef FRINFC_READONLY_NDEF */
1810 /* Call for the Completion Routine*/
1811 if (NFCSTATUS_PENDING != Status)
1813 phFriNfc_ISO15693_H_Complete(psNdefMap, Status);
1817 /************************** END external functions *********************/
1819 #endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */