summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <martijn.coenen@nxp.com>2011-01-13 23:24:24 +0100
committerJeff Hamilton <jham@android.com>2011-02-25 06:44:34 +0900
commita6e012a748e70ab203655d4e1c0d0a77b6515fad (patch)
treea3aeefc1f4816c58a4e943d85fca89678432f159
parent29e144ebf81b0f09b3fe4c26b67485ce836909c6 (diff)
downloadexternal_libnfc-nxp-a6e012a748e70ab203655d4e1c0d0a77b6515fad.zip
external_libnfc-nxp-a6e012a748e70ab203655d4e1c0d0a77b6515fad.tar.gz
external_libnfc-nxp-a6e012a748e70ab203655d4e1c0d0a77b6515fad.tar.bz2
Added support for NDEF on ICODE.
This patch allows reading and writing of NDEF messages on ICODE tags. Change-Id: I43b4845c898c2bf268f609a5a81e991460059ff6
-rw-r--r--Android.mk1
-rw-r--r--src/phFriNfc.h16
-rw-r--r--src/phFriNfc_ISO15693Map.c1668
-rw-r--r--src/phFriNfc_ISO15693Map.h219
-rw-r--r--src/phFriNfc_NdefMap.c76
-rw-r--r--src/phFriNfc_NdefMap.h44
6 files changed, 2016 insertions, 8 deletions
diff --git a/Android.mk b/Android.mk
index 8c05843..5dc9682 100644
--- a/Android.mk
+++ b/Android.mk
@@ -77,6 +77,7 @@ LOCAL_SRC_FILES += src/phFriNfc_MapTools.c
LOCAL_SRC_FILES += src/phFriNfc_TopazMap.c
LOCAL_SRC_FILES += src/phFriNfc_TopazDynamicMap.c
LOCAL_SRC_FILES += src/phFriNfc_DesfireMap.c
+LOCAL_SRC_FILES += src/phFriNfc_ISO15693Map.c
LOCAL_SRC_FILES += src/phFriNfc_NdefMap.c
LOCAL_SRC_FILES += src/phFriNfc_IntNdefMap.c
diff --git a/src/phFriNfc.h b/src/phFriNfc.h
index 989871b..fb4b5ee 100644
--- a/src/phFriNfc.h
+++ b/src/phFriNfc.h
@@ -20,10 +20,10 @@
*
* Project: NFC-FRI
*
- * $Date: Thu Feb 11 18:45:30 2010 $
- * $Author: ing04880 $
- * $Revision: 1.19 $
- * $Aliases: NFC_FRI1.1_WK1007_R33_1 $
+ * $Date: Mon Dec 13 14:14:13 2010 $
+ * $Author: ing02260 $
+ * $Revision: 1.20 $
+ * $Aliases: $
*
*/
@@ -58,6 +58,10 @@
#define PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED
#endif
+#ifdef DISABLE_ISO15693_MAPPING
+#define PH_FRINFC_MAP_ISO15693_DISABLED
+#endif
+
#ifdef DISABLE_FORMAT
#define PH_FRINFC_FMT_DESFIRE_DISABLED
@@ -75,8 +79,8 @@
*/
/*@{*/
-#define PH_FRINFC_FILEREVISION "$Revision: 1.19 $" /**< \ingroup grp_file_attributes */
-#define PH_FRINFC_FILEALIASES "$Aliases: NFC_FRI1.1_WK1007_R33_1 $" /**< \ingroup grp_file_attributes */
+#define PH_FRINFC_FILEREVISION "$Revision: 1.20 $" /**< \ingroup grp_file_attributes */
+#define PH_FRINFC_FILEALIASES "$Aliases: $" /**< \ingroup grp_file_attributes */
/*@}*/
diff --git a/src/phFriNfc_ISO15693Map.c b/src/phFriNfc_ISO15693Map.c
new file mode 100644
index 0000000..8b6d1f1
--- /dev/null
+++ b/src/phFriNfc_ISO15693Map.c
@@ -0,0 +1,1668 @@
+/*
+/*
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*!
+* \file phFriNfc_ISO15693Map.c
+* \brief This component encapsulates read/write/check ndef/process functionalities,
+* for the ISO-15693 Card.
+*
+* Project: NFC-FRI
+*
+* $Date: $
+* $Author: ing02260 $
+* $Revision: $
+* $Aliases: $
+*
+*/
+
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+
+#include <phNfcTypes.h>
+#include <phNfcConfig.h>
+#include <phNfcInterface.h>
+#include <phNfcHalTypes.h>
+#include <phFriNfc.h>
+#include <phFriNfc_NdefMap.h>
+#include <phFriNfc_OvrHal.h>
+#include <phFriNfc_MapTools.h>
+#include <phFriNfc_ISO15693Map.h>
+
+/************************** START DATA STRUCTURE *********************/
+
+typedef enum phFriNfc_eChkNdefSeq
+{
+ ISO15693_NDEF_TLV_T,
+ ISO15693_NDEF_TLV_L,
+ ISO15693_NDEF_TLV_V,
+ ISO15693_PROP_TLV_L,
+ ISO15693_PROP_TLV_V
+
+}phFriNfc_eChkNdefSeq_t;
+
+typedef enum phFriNfc_eWrNdefSeq
+{
+ ISO15693_RD_BEFORE_WR_NDEF_L_0,
+ ISO15693_WRITE_DATA,
+ ISO15693_RD_BEFORE_WR_NDEF_L,
+ ISO15693_WRITE_NDEF_TLV_L
+
+}phFriNfc_eWrNdefSeq_t;
+
+#ifdef FRINFC_READONLY_NDEF
+
+typedef enum phFriNfc_eRONdefSeq
+{
+ ISO15693_RD_BEFORE_WR_CC,
+ ISO15693_WRITE_CC,
+ ISO15693_LOCK_BLOCK
+
+}phFriNfc_eRONdefSeq_t;
+
+#endif /* #ifdef FRINFC_READONLY_NDEF */
+
+/************************** END DATA STRUCTURE *********************/
+
+/************************** START MACROS definition *********************/
+
+
+
+
+/* UID bytes to differentiate ICODE cards */
+#define ISO15693_UID_BYTE_4 0x04U
+#define ISO15693_UID_BYTE_5 0x05U
+
+/* UID value for
+ SL2 ICS20
+ SL2S2002
+ */
+#define ISO15693_UIDBYTE_5_VALUE_SLI_X 0x01U
+/* Card size SL2 ICS20 / SL2S2002 */
+#define ISO15693_SL2_S2002_ICS20 112U
+
+/* UID value for
+ SL2 ICS53,
+ SL2 ICS54
+ SL2S5302
+*/
+#define ISO15693_UIDBYTE_5_VALUE_SLI_X_S 0x02U
+#define ISO15693_UIDBYTE_4_VALUE_SLI_X_S 0x00U
+#define ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC 0x80U
+#define ISO15693_UIDBYTE_4_VALUE_SLI_X_SY 0x40U
+/* SL2 ICS53, SL2 ICS54 and SL2S5302 */
+#define ISO15693_SL2_S5302_ICS53_ICS54 160U
+
+/* UID value for
+ SL2 ICS50
+ SL2 ICS51
+ SL2S5002
+*/
+#define ISO15693_UIDBYTE_5_VALUE_SLI_X_L 0x03U
+#define ISO15693_UIDBYTE_4_VALUE_SLI_X_L 0x00U
+#define ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC 0x80U
+/* SL2 ICS50, SL2 ICS51 and SL2S5002 */
+#define ISO15693_SL2_S5002_ICS50_ICS51 32U
+
+
+/* State Machine declaration
+CHECK NDEF state */
+#define ISO15693_CHECK_NDEF 0x01U
+/* READ NDEF state */
+#define ISO15693_READ_NDEF 0x02U
+/* WRITE NDEF state */
+#define ISO15693_WRITE_NDEF 0x03U
+#ifdef FRINFC_READONLY_NDEF
+
+ /* READ ONLY NDEF state */
+ #define ISO15693_READ_ONLY_NDEF 0x04U
+
+ /* READ ONLY MASK byte for CC */
+ #define ISO15693_CC_READ_ONLY_MASK 0x03U
+
+ /* CC READ WRITE index */
+ #define ISO15693_RW_BTYE_INDEX 0x01U
+
+ /* LOCK BLOCK command */
+ #define ISO15693_LOCK_BLOCK_CMD 0x22U
+
+#endif /* #ifdef FRINFC_READONLY_NDEF */
+
+/* CC Bytes
+Magic number */
+#define ISO15693_CC_MAGIC_BYTE 0xE1U
+/* Expected mapping version */
+#define ISO15693_MAPPING_VERSION 0x01U
+/* Major version is in upper 2 bits */
+#define ISO15693_MAJOR_VERSION_MASK 0xC0U
+
+/* CC indicating tag is capable of multi-block read */
+#define ISO15693_CC_USE_MBR 0x01U
+/* CC indicating tag is capable of inventory page read */
+#define ISO15693_CC_USE_IPR 0x02U
+/* EXTRA byte in the response */
+#define ISO15693_EXTRA_RESP_BYTE 0x01U
+
+/* Maximum card size multiplication factor */
+#define ISO15693_MULT_FACTOR 0x08U
+/* NIBBLE mask for READ WRITE access */
+#define ISO15693_LSB_NIBBLE_MASK 0x0FU
+#define ISO15693_MSB_NIBBLE_MASK 0xF0U
+
+#define ISO15693_RD_WR_PERMISSION 0x00U
+#define ISO15693_RD_ONLY_PERMISSION 0x03U
+
+/* READ command identifier */
+#define ISO15693_READ_COMMAND 0x20U
+
+/* READ multiple command identifier */
+#define ISO15693_READ_MULTIPLE_COMMAND 0x23U
+
+/* INVENTORY pageread command identifier */
+#define ICODE_INVENTORY_PAGEREAD_COMMAND 0xB0U
+#define INVENTORY_PAGEREAD_FLAGS 0x24U
+#define NXP_MANUFACTURING_CODE 0x04U
+
+/* WRITE command identifier */
+#define ISO15693_WRITE_COMMAND 0x21U
+/* FLAG option */
+#define ISO15693_FLAGS 0x20U
+
+/* RESPONSE length expected for single block READ */
+#define ISO15693_SINGLE_BLK_RD_RESP_LEN 0x04U
+/* NULL TLV identifier */
+#define ISO15693_NULL_TLV_ID 0x00U
+/* NDEF TLV, TYPE identifier */
+#define ISO15693_NDEF_TLV_TYPE_ID 0x03U
+
+/* 8 BIT shift */
+#define ISO15693_BTYE_SHIFT 0x08U
+
+/* Proprietary TLV TYPE identifier */
+#define ISO15693_PROP_TLV_ID 0xFDU
+
+/* CC SIZE in BYTES */
+#define ISO15693_CC_SIZE 0x04U
+
+/* To get the remaining size in the card.
+Inputs are
+1. maximum data size
+2. block number
+3. index of the block number */
+#define ISO15693_GET_REMAINING_SIZE(max_data_size, blk, index) \
+ (max_data_size - ((blk * ISO15693_BYTES_PER_BLOCK) + index))
+
+#define ISO15693_GET_LEN_FIELD_BLOCK_NO(blk, byte_addr, ndef_size) \
+ (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) >= \
+ (ISO15693_BYTES_PER_BLOCK - 1)) ? (blk + 1) : blk)
+
+#define ISO15693_GET_LEN_FIELD_BYTE_NO(blk, byte_addr, ndef_size) \
+ (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) % \
+ ISO15693_BYTES_PER_BLOCK))
+
+
+
+/************************** END MACROS definition *********************/
+
+/************************** START static functions declaration *********************/
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessReadOnly (
+ phFriNfc_NdefMap_t *psNdefMap);
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessWriteNdef (
+ phFriNfc_NdefMap_t *psNdefMap);
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessReadNdef (
+ phFriNfc_NdefMap_t *psNdefMap);
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessCheckNdef (
+ phFriNfc_NdefMap_t *psNdefMap);
+
+static
+void
+phFriNfc_ISO15693_H_Complete (
+ phFriNfc_NdefMap_t *psNdefMap,
+ NFCSTATUS Status);
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ReadWrite (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint8_t command,
+ uint8_t *p_data,
+ uint8_t data_length);
+
+static
+NFCSTATUS
+phFriNfc_ReadRemainingInMultiple (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint32_t startBlock);
+
+/************************** END static functions declaration *********************/
+
+/************************** START static functions definition *********************/
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessWriteNdef (
+ phFriNfc_NdefMap_t *psNdefMap)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+ phFriNfc_eWrNdefSeq_t e_wr_ndef_seq = (phFriNfc_eWrNdefSeq_t)
+ psNdefMap->ISO15693Container.ndef_seq;
+ uint8_t *p_recv_buf = NULL;
+ uint8_t recv_length = 0;
+ uint8_t write_flag = FALSE;
+ uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
+ uint8_t remaining_size = 0;
+
+ switch (e_wr_ndef_seq)
+ {
+ case ISO15693_RD_BEFORE_WR_NDEF_L_0:
+ {
+ p_recv_buf = (psNdefMap->SendRecvBuf +
+ ISO15693_EXTRA_RESP_BYTE);
+ recv_length = (uint8_t)
+ (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
+
+ if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
+ {
+ uint8_t byte_index = 0;
+
+ (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
+ recv_length);
+
+ byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO(
+ ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ psNdefMap->ApduBufferSize);
+
+ /* Writing length field to 0 */
+ *(a_write_buf + byte_index) = 0x00;
+
+ if ((ISO15693_BYTES_PER_BLOCK - 1) != byte_index)
+ {
+ byte_index = (uint8_t)(byte_index + 1);
+ remaining_size = (ISO15693_BYTES_PER_BLOCK - byte_index);
+
+ if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
+ < remaining_size)
+ {
+ remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
+ psNdefMap->ApduBuffIndex);
+ }
+
+ /* Go to next byte to fill the write buffer */
+
+ (void)memcpy ((void *)(a_write_buf + byte_index),
+ (void *)(psNdefMap->ApduBuffer +
+ psNdefMap->ApduBuffIndex), remaining_size);
+
+ psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
+ remaining_size);
+ }
+
+ e_wr_ndef_seq = ISO15693_WRITE_DATA;
+ write_flag = TRUE;
+ } /* if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) */
+ else
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_RECEIVE_LENGTH);
+ }
+ break;
+ } /* case ISO15693_RD_BEFORE_WR_NDEF_L_0: */
+
+ case ISO15693_RD_BEFORE_WR_NDEF_L:
+ {
+ p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
+ recv_length = (uint8_t)(*psNdefMap->SendRecvLength -
+ ISO15693_EXTRA_RESP_BYTE);
+
+ if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
+ {
+ uint8_t byte_index = 0;
+
+ (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
+ recv_length);
+
+ byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO(
+ ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ psNdefMap->ApduBuffIndex);
+
+ *(a_write_buf + byte_index) = (uint8_t)psNdefMap->ApduBuffIndex;
+ e_wr_ndef_seq = ISO15693_WRITE_NDEF_TLV_L;
+ write_flag = TRUE;
+ }
+ else
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_RECEIVE_LENGTH);
+ }
+ break;
+ }
+
+ case ISO15693_WRITE_DATA:
+ {
+ if ((psNdefMap->ApduBufferSize == psNdefMap->ApduBuffIndex)
+ || (ps_iso_15693_con->current_block ==
+ (ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK)))
+ {
+ ps_iso_15693_con->current_block =
+ ISO15693_GET_LEN_FIELD_BLOCK_NO(
+ ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ psNdefMap->ApduBuffIndex);
+ e_wr_ndef_seq = ISO15693_RD_BEFORE_WR_NDEF_L;
+ }
+ else
+ {
+ remaining_size = ISO15693_BYTES_PER_BLOCK;
+
+ ps_iso_15693_con->current_block = (uint16_t)
+ (ps_iso_15693_con->current_block + 1);
+
+ if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
+ < remaining_size)
+ {
+ remaining_size = (uint8_t)(psNdefMap->ApduBufferSize -
+ psNdefMap->ApduBuffIndex);
+ }
+
+ (void)memcpy ((void *)a_write_buf, (void *)
+ (psNdefMap->ApduBuffer +
+ psNdefMap->ApduBuffIndex), remaining_size);
+
+ psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
+ remaining_size);
+ write_flag = TRUE;
+ }
+ break;
+ } /* case ISO15693_WRITE_DATA: */
+
+ case ISO15693_WRITE_NDEF_TLV_L:
+ {
+ *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex;
+ ps_iso_15693_con->actual_ndef_size = psNdefMap->ApduBuffIndex;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ } /* switch (e_wr_ndef_seq) */
+
+ if (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex)
+ {
+ if (FALSE == write_flag)
+ {
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_READ_COMMAND, NULL, 0);
+ }
+ else
+ {
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_WRITE_COMMAND,
+ a_write_buf, sizeof (a_write_buf));
+ }
+ }
+
+ psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_wr_ndef_seq;
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ReadWrite (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint8_t command,
+ uint8_t *p_data,
+ uint8_t data_length)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ uint8_t send_index = 0;
+
+ /* set the data for additional data exchange*/
+ psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
+ psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
+ psNdefMap->psDepAdditionalInfo.NAD = 0;
+
+ psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
+ psNdefMap->MapCompletionInfo.Context = psNdefMap;
+
+ *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
+
+ psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
+
+ *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)ISO15693_FLAGS;
+ send_index = (uint8_t)(send_index + 1);
+
+ *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
+ send_index = (uint8_t)(send_index + 1);
+
+ (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
+ (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid,
+ psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+ send_index = (uint8_t)(send_index +
+ psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+
+ *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
+ psNdefMap->ISO15693Container.current_block;
+ send_index = (uint8_t)(send_index + 1);
+
+ if ((ISO15693_WRITE_COMMAND == command) ||
+ (ISO15693_READ_MULTIPLE_COMMAND == command))
+ {
+ (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
+ (void *)p_data, data_length);
+ send_index = (uint8_t)(send_index + data_length);
+ }
+
+ psNdefMap->SendLength = send_index;
+ result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
+ &psNdefMap->MapCompletionInfo,
+ psNdefMap->psRemoteDevInfo,
+ psNdefMap->Cmd,
+ &psNdefMap->psDepAdditionalInfo,
+ psNdefMap->SendRecvBuf,
+ psNdefMap->SendLength,
+ psNdefMap->SendRecvBuf,
+ psNdefMap->SendRecvLength);
+
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_Inventory_Page_Read (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint8_t command,
+ uint8_t page,
+ uint8_t numPages)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ uint8_t send_index = 0;
+
+ /* set the data for additional data exchange*/
+ psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
+ psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
+ psNdefMap->psDepAdditionalInfo.NAD = 0;
+
+ psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process;
+ psNdefMap->MapCompletionInfo.Context = psNdefMap;
+
+ *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
+
+ psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
+
+ *(psNdefMap->SendRecvBuf + send_index) = INVENTORY_PAGEREAD_FLAGS;
+ send_index = (uint8_t)(send_index + 1);
+
+ *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command;
+ send_index = (uint8_t)(send_index + 1);
+
+ *(psNdefMap->SendRecvBuf + send_index) = NXP_MANUFACTURING_CODE;
+ send_index = (uint8_t)(send_index + 1);
+
+ *(psNdefMap->SendRecvBuf + send_index) = 0x40;
+ send_index = (uint8_t)(send_index + 1);
+
+ (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
+ (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid,
+ psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+ send_index = (uint8_t)(send_index +
+ psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+
+ *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
+ page;
+ send_index = (uint8_t)(send_index + 1);
+
+ *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)
+ numPages;
+ send_index = (uint8_t)(send_index + 1);
+
+ psNdefMap->SendLength = send_index;
+
+ result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice,
+ &psNdefMap->MapCompletionInfo,
+ psNdefMap->psRemoteDevInfo,
+ psNdefMap->Cmd,
+ &psNdefMap->psDepAdditionalInfo,
+ psNdefMap->SendRecvBuf,
+ psNdefMap->SendLength,
+ psNdefMap->SendRecvBuf,
+ psNdefMap->SendRecvLength);
+
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_Reformat_Pageread_Buffer (
+ uint8_t *p_recv_buf,
+ uint8_t recv_length,
+ uint8_t *p_dst_buf,
+ uint8_t dst_length)
+{
+ // Inventory page reads return an extra security byte per page
+ // So we need to reformat the returned buffer in memory
+ uint32_t i = 0;
+ uint32_t reformatted_index = 0;
+ while (i < recv_length) {
+ // Going for another page of 16 bytes, check for space in dst buffer
+ if (reformatted_index + 16 > dst_length) {
+ break;
+ }
+ if (p_recv_buf[i] == 0x0F) {
+ // Security, insert 16 0 bytes
+ memset(&(p_dst_buf[reformatted_index]), 0, 16);
+ reformatted_index += 16;
+ i++;
+ } else {
+ // Skip security byte
+ i++;
+ if (i + 16 <= recv_length) {
+ memcpy(&(p_dst_buf[reformatted_index]), &(p_recv_buf[i]), 16);
+ reformatted_index += 16;
+ } else {
+ break;
+ }
+ i+=16;
+ }
+ }
+ return reformatted_index;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessReadNdef (
+ phFriNfc_NdefMap_t *psNdefMap)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+ uint16_t remaining_data_size = 0;
+ uint8_t *p_recv_buf =
+ (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
+ uint8_t recv_length = (uint8_t)
+ (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
+
+ uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size);
+
+ if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)
+ {
+ uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length,
+ reformatted_buf, ps_iso_15693_con->max_data_size);
+ p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
+ recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
+ }
+ if (ps_iso_15693_con->store_length)
+ {
+ /* Continue read option selected
+ So stored data already existing,
+ copy the information to the user buffer
+ */
+ if (ps_iso_15693_con->store_length
+ <= (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex))
+ {
+ /* Stored data length is less than or equal
+ to the user expected size */
+ (void)memcpy ((void *)(psNdefMap->ApduBuffer +
+ psNdefMap->ApduBuffIndex),
+ (void *)p_recv_buf,
+ ps_iso_15693_con->store_length);
+
+ psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
+ ps_iso_15693_con->store_length);
+
+ remaining_data_size = ps_iso_15693_con->store_length;
+
+ ps_iso_15693_con->store_length = 0;
+ }
+ else
+ {
+ /* stored length is more than the user expected size */
+ remaining_data_size = (uint16_t)(ps_iso_15693_con->store_length -
+ (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex));
+
+ (void)memcpy ((void *)(psNdefMap->ApduBuffer +
+ psNdefMap->ApduBuffIndex),
+ (void *)ps_iso_15693_con->store_read_data,
+ remaining_data_size);
+
+ (void)memcpy ((void *)ps_iso_15693_con->store_read_data,
+ (void *)(ps_iso_15693_con->store_read_data +
+ remaining_data_size),
+ (ps_iso_15693_con->store_length - remaining_data_size));
+
+ psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
+ remaining_data_size);
+ }
+ } /* if (ps_iso_15693_con->store_length) */
+ else
+ {
+ uint8_t byte_index = 0;
+
+ remaining_data_size = ps_iso_15693_con->remaining_size_to_read;
+ if (ISO15693_GET_VALUE_FIELD_BLOCK_NO(ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ ps_iso_15693_con->actual_ndef_size)
+ == ps_iso_15693_con->current_block)
+ {
+ /* Read from the beginning option selected,
+ BYTE number may start from the middle */
+ byte_index = (uint8_t)ISO15693_GET_VALUE_FIELD_BYTE_NO(
+ ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ ps_iso_15693_con->actual_ndef_size);
+ }
+
+ if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
+ < remaining_data_size)
+ {
+ if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
+ < (uint16_t)(recv_length - byte_index))
+ {
+ remaining_data_size = (uint8_t)(psNdefMap->ApduBufferSize -
+ psNdefMap->ApduBuffIndex);
+ /* Store the data for the continue read option */
+ (void)memcpy ((void *)ps_iso_15693_con->store_read_data,
+ (void *)(p_recv_buf + byte_index +
+ remaining_data_size),
+ ((recv_length - byte_index) -
+ remaining_data_size));
+
+ ps_iso_15693_con->store_length = (uint8_t)
+ ((recv_length - byte_index) - remaining_data_size);
+ }
+ else
+ {
+ remaining_data_size = (uint8_t)
+ (recv_length - byte_index);
+ }
+ }
+ else
+ {
+ if (remaining_data_size > (recv_length - byte_index))
+ {
+ remaining_data_size = (uint8_t)
+ (recv_length - byte_index);
+ }
+ }
+ (void)memcpy ((void *)(psNdefMap->ApduBuffer +
+ psNdefMap->ApduBuffIndex),
+ (void *)(p_recv_buf + byte_index),
+ remaining_data_size);
+
+ psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
+ remaining_data_size);
+
+ } /* if (ps_iso_15693_con->store_length) */
+
+ /* Remaining size is decremented */
+ ps_iso_15693_con->remaining_size_to_read = (uint8_t)
+ (ps_iso_15693_con->remaining_size_to_read -
+ remaining_data_size);
+
+ if ((psNdefMap->ApduBuffIndex != psNdefMap->ApduBufferSize)
+ && (0 != ps_iso_15693_con->remaining_size_to_read))
+ {
+ ps_iso_15693_con->current_block = (uint16_t)
+ (ps_iso_15693_con->current_block + 1);
+ /* READ again */
+ if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
+ (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
+ result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
+ }
+ else {
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
+ NULL, 0);
+ }
+ }
+ else
+ {
+ /* Read completed */
+ *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
+ }
+ if (reformatted_buf != NULL) {
+ phOsalNfc_FreeMemory(reformatted_buf);
+ }
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_CheckCCBytes (
+ phFriNfc_NdefMap_t *psNdefMap)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+ uint8_t recv_index = 0;
+ uint8_t *p_recv_buf = (psNdefMap->SendRecvBuf + 1);
+
+ if (ISO15693_CC_MAGIC_BYTE == *p_recv_buf)
+ {
+ recv_index = (uint8_t)(recv_index + 1);
+ uint8_t tag_major_version = (*(p_recv_buf + recv_index) & ISO15693_MAJOR_VERSION_MASK) >> 6;
+ if (ISO15693_MAPPING_VERSION >= tag_major_version)
+ {
+ switch (*(p_recv_buf + recv_index) & ISO15693_LSB_NIBBLE_MASK)
+ {
+ case ISO15693_RD_WR_PERMISSION:
+ {
+ psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
+ break;
+ }
+
+ case ISO15693_RD_ONLY_PERMISSION:
+ {
+ psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ break;
+ }
+ }
+ recv_index = (uint8_t)(recv_index + 1);
+
+ if (!result)
+ {
+ ps_iso_15693_con->max_data_size = (uint16_t)
+ (*(p_recv_buf + recv_index) *
+ ISO15693_MULT_FACTOR);
+ recv_index = (uint8_t)(recv_index + 1);
+ ps_iso_15693_con->read_capabilities = (*(p_recv_buf + recv_index));
+
+
+ }
+ }
+ else
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ }
+ }
+ else
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ }
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessCheckNdef (
+ phFriNfc_NdefMap_t *psNdefMap)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+ phFriNfc_eChkNdefSeq_t e_chk_ndef_seq = (phFriNfc_eChkNdefSeq_t)
+ psNdefMap->ISO15693Container.ndef_seq;
+
+ uint8_t *p_recv_buf =
+ (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE);
+ uint8_t recv_length = (uint8_t)
+ (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE);
+ uint8_t parse_index = 0;
+ static uint16_t prop_ndef_index = 0;
+ uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size);
+
+ if (0 == ps_iso_15693_con->current_block)
+ {
+ /* Check CC byte */
+ result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
+ parse_index = (uint8_t)(parse_index + recv_length);
+ }
+ else if (1 == ps_iso_15693_con->current_block &&
+ (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR))
+ {
+
+ uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length,
+ reformatted_buf, ps_iso_15693_con->max_data_size);
+ // Skip initial CC bytes
+ p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
+ recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK);
+ }
+ else
+ {
+ /* Propreitary TLVs VALUE can end in between a block,
+ so when that block is read, dont read the proprietary data */
+ if (ISO15693_PROP_TLV_V == e_chk_ndef_seq)
+ {
+ parse_index = ps_iso_15693_con->ndef_tlv_type_byte;
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ }
+ }
+
+ while ((parse_index < recv_length)
+ && (NFCSTATUS_SUCCESS == result)
+ && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq))
+ {
+ switch (e_chk_ndef_seq)
+ {
+ case ISO15693_NDEF_TLV_T:
+ {
+ prop_ndef_index = 0;
+ switch (*(p_recv_buf + parse_index))
+ {
+ case ISO15693_NDEF_TLV_TYPE_ID:
+ {
+ ps_iso_15693_con->ndef_tlv_type_byte = parse_index;
+ ps_iso_15693_con->ndef_tlv_type_blk =
+ ps_iso_15693_con->current_block;
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_L;
+ /* Update the block number */
+
+ break;
+ }
+
+ case ISO15693_NULL_TLV_ID:
+ {
+ /* Dont do any thing, go to next byte */
+ break;
+ }
+
+ case ISO15693_PROP_TLV_ID:
+ {
+ /* Move the sequence to find the length
+ of the proprietary TLV */
+ e_chk_ndef_seq = ISO15693_PROP_TLV_L;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ break;
+ }
+ } /* switch (*(p_recv_buf + parse_index)) */
+ break;
+ }
+
+ case ISO15693_PROP_TLV_L:
+ {
+ switch (prop_ndef_index)
+ {
+ case 0:
+ {
+ if (0 == *(p_recv_buf + parse_index))
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ }
+ else
+ {
+ prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
+
+ if (ISO15693_THREE_BYTE_LENGTH_ID ==
+ *(p_recv_buf + parse_index))
+ {
+ prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
+ }
+ else
+ {
+ ps_iso_15693_con->actual_ndef_size =
+ *(p_recv_buf + parse_index);
+ e_chk_ndef_seq = ISO15693_PROP_TLV_V;
+ prop_ndef_index = 0;
+ }
+ }
+ break;
+ }
+
+ case 1:
+ {
+ ps_iso_15693_con->actual_ndef_size = (uint16_t)
+ (*(p_recv_buf + parse_index) <<
+ ISO15693_BTYE_SHIFT);
+ prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
+ break;
+ }
+
+ case 2:
+ {
+ ps_iso_15693_con->actual_ndef_size = (uint16_t)
+ (ps_iso_15693_con->actual_ndef_size |
+ *(p_recv_buf + parse_index));
+
+ e_chk_ndef_seq = ISO15693_PROP_TLV_V;
+ prop_ndef_index = 0;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ } /* switch (prop_ndef_index) */
+
+ if ((ISO15693_PROP_TLV_V == e_chk_ndef_seq)
+ && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
+ ps_iso_15693_con->current_block, parse_index)
+ <= ps_iso_15693_con->actual_ndef_size))
+ {
+ /* Check for the length field value has not exceeded the card size,
+ if size is exceeded or then return error */
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ }
+ else
+ {
+ uint16_t prop_byte_addr = 0;
+ /* skip the proprietary TLVs value field */
+ prop_byte_addr = (uint16_t)
+ ((ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK) +
+ parse_index + ps_iso_15693_con->actual_ndef_size);
+
+ ps_iso_15693_con->ndef_tlv_type_byte = (uint8_t)(prop_byte_addr %
+ ISO15693_BYTES_PER_BLOCK);
+ ps_iso_15693_con->ndef_tlv_type_blk = (uint16_t)(prop_byte_addr /
+ ISO15693_BYTES_PER_BLOCK);
+ if (parse_index + ps_iso_15693_con->actual_ndef_size >=
+ recv_length)
+ {
+ parse_index = (uint8_t)recv_length;
+ }
+ else
+ {
+ parse_index = (uint8_t)(parse_index +
+ ps_iso_15693_con->actual_ndef_size);
+ }
+
+ }
+ break;
+ } /* case ISO15693_PROP_TLV_L: */
+
+ case ISO15693_PROP_TLV_V:
+ {
+ uint8_t remaining_length = (uint8_t)(recv_length -
+ parse_index);
+
+ if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
+ > remaining_length)
+ {
+ parse_index = (uint8_t)(parse_index + remaining_length);
+ prop_ndef_index = (uint8_t)(prop_ndef_index + remaining_length);
+ }
+ else if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index)
+ == remaining_length)
+ {
+ parse_index = (uint8_t)(parse_index + remaining_length);
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ prop_ndef_index = 0;
+ }
+ else
+ {
+ parse_index = (uint8_t)(parse_index +
+ (ps_iso_15693_con->actual_ndef_size -
+ prop_ndef_index));
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ prop_ndef_index = 0;
+ }
+ break;
+ } /* case ISO15693_PROP_TLV_V: */
+
+ case ISO15693_NDEF_TLV_L:
+ {
+ switch (prop_ndef_index)
+ {
+ case 0:
+ {
+ if (0 == *(p_recv_buf + parse_index))
+ {
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
+ ps_iso_15693_con->actual_ndef_size = 0;
+ }
+ else
+ {
+ prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
+
+ if (ISO15693_THREE_BYTE_LENGTH_ID ==
+ *(p_recv_buf + parse_index))
+ {
+ prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ prop_ndef_index = 0;
+ }
+ else
+ {
+ ps_iso_15693_con->actual_ndef_size =
+ *(p_recv_buf + parse_index);
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
+ prop_ndef_index = 0;
+ }
+ }
+ break;
+ }
+
+ case 1:
+ {
+ ps_iso_15693_con->actual_ndef_size = (uint16_t)
+ (*(p_recv_buf + parse_index) <<
+ ISO15693_BTYE_SHIFT);
+ prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
+ break;
+ }
+
+ case 2:
+ {
+ ps_iso_15693_con->actual_ndef_size = (uint16_t)
+ (ps_iso_15693_con->actual_ndef_size |
+ *(p_recv_buf + parse_index));
+
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
+ prop_ndef_index = 0;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ } /* switch (prop_ndef_index) */
+
+ if ((ISO15693_NDEF_TLV_V == e_chk_ndef_seq)
+ && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
+ /* parse_index + 1 is done because the data starts from the next index.
+ MOD operation is used to know that parse_index >
+ ISO15693_BYTES_PER_BLOCK, then block shall be incremented
+ */
+ (((parse_index + 1) % ISO15693_BYTES_PER_BLOCK) ?
+ ps_iso_15693_con->current_block :
+ ps_iso_15693_con->current_block + 1), ((parse_index + 1) %
+ ISO15693_BYTES_PER_BLOCK))
+ < ps_iso_15693_con->actual_ndef_size))
+ {
+ /* Check for the length field value has not exceeded the card size */
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ }
+ else
+ {
+ psNdefMap->CardState = (uint8_t)
+ ((PH_NDEFMAP_CARD_STATE_READ_ONLY
+ == psNdefMap->CardState) ?
+ PH_NDEFMAP_CARD_STATE_READ_ONLY :
+ ((ps_iso_15693_con->actual_ndef_size) ?
+ PH_NDEFMAP_CARD_STATE_READ_WRITE :
+ PH_NDEFMAP_CARD_STATE_INITIALIZED));
+ }
+ break;
+ } /* case ISO15693_NDEF_TLV_L: */
+
+ case ISO15693_NDEF_TLV_V:
+ {
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ } /* switch (e_chk_ndef_seq) */
+ parse_index = (uint8_t)(parse_index + 1);
+ } /* while ((parse_index < recv_length)
+ && (NFCSTATUS_SUCCESS == result)
+ && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)) */
+
+ if (result)
+ {
+ /* Error returned while parsing, so STOP read */
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ prop_ndef_index = 0;
+ }
+ else if (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)
+ {
+ /* READ again */
+ if (ISO15693_PROP_TLV_V != e_chk_ndef_seq)
+ {
+ ps_iso_15693_con->current_block = (uint16_t)
+ (ps_iso_15693_con->current_block + 1);
+ }
+ else
+ {
+ ps_iso_15693_con->current_block = ps_iso_15693_con->ndef_tlv_type_blk;
+ }
+
+ uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
+ ps_iso_15693_con->current_block, 0);
+ if (remaining_size > 0)
+ {
+ if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
+ (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
+ result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
+ } else {
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
+ NULL, 0);
+ }
+ }
+ else
+ {
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ prop_ndef_index = 0;
+ /* Error, no size to parse */
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_NO_NDEF_SUPPORT);
+ }
+
+ }
+ else
+ {
+ /* Successful read with proper NDEF information updated */
+ prop_ndef_index = 0;
+ e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
+ psNdefMap->CardType = (uint8_t)PH_FRINFC_NDEFMAP_ISO15693_CARD;
+ }
+
+ psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_chk_ndef_seq;
+
+ if (reformatted_buf != NULL) {
+ phOsalNfc_FreeMemory(reformatted_buf);
+ }
+ return result;
+}
+
+static
+void
+phFriNfc_ISO15693_H_Complete (
+ phFriNfc_NdefMap_t *psNdefMap,
+ NFCSTATUS Status)
+{
+ /* set the state back to the RESET_INIT state*/
+ psNdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
+
+ /* set the completion routine*/
+ psNdefMap->CompletionRoutine[psNdefMap->ISO15693Container.cr_index].
+ CompletionRoutine (psNdefMap->CompletionRoutine->Context, Status);
+}
+
+#ifdef FRINFC_READONLY_NDEF
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProcessReadOnly (
+ phFriNfc_NdefMap_t *psNdefMap)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+ phFriNfc_eRONdefSeq_t e_ro_ndef_seq = (phFriNfc_eRONdefSeq_t)
+ ps_iso_15693_con->ndef_seq;
+ uint8_t *p_recv_buf = (psNdefMap->SendRecvBuf +
+ ISO15693_EXTRA_RESP_BYTE);
+ uint8_t recv_length = (uint8_t)(*psNdefMap->SendRecvLength -
+ ISO15693_EXTRA_RESP_BYTE);
+ uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
+
+ switch (e_ro_ndef_seq)
+ {
+ case ISO15693_RD_BEFORE_WR_CC:
+ {
+ if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
+ {
+ (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
+ sizeof (a_write_buf));
+
+ *(a_write_buf + ISO15693_RW_BTYE_INDEX) = (uint8_t)
+ (*(a_write_buf + ISO15693_RW_BTYE_INDEX) |
+ ISO15693_CC_READ_ONLY_MASK);
+
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_WRITE_DATA, a_write_buf,
+ sizeof (a_write_buf));
+
+ e_ro_ndef_seq = ISO15693_WRITE_CC;
+ }
+ break;
+ }
+
+ case ISO15693_WRITE_CC:
+ {
+ e_ro_ndef_seq = ISO15693_LOCK_BLOCK;
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_LOCK_BLOCK_CMD, NULL, 0);
+ break;
+ }
+
+ case ISO15693_LOCK_BLOCK:
+ {
+ if (ps_iso_15693_con->current_block ==
+ (ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK))
+ {
+ /* READ ONLY successful */
+ }
+ else
+ {
+ ps_iso_15693_con->current_block = (uint16_t)
+ (ps_iso_15693_con->current_block + 1);
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_LOCK_BLOCK_CMD, NULL, 0);
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ ps_iso_15693_con->ndef_seq = (uint8_t)e_ro_ndef_seq;
+ return result;
+}
+
+#endif /* #ifdef FRINFC_READONLY_NDEF */
+/************************** END static functions definition *********************/
+
+/************************** START external functions *********************/
+
+NFCSTATUS
+phFriNfc_ISO15693_ChkNdef (
+ phFriNfc_NdefMap_t *psNdefMap)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phHal_sIso15693Info_t *ps_iso_15693_info =
+ &(psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
+
+ /* Update the previous operation with current operation.
+ This becomes the previous operation after this execution */
+ psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
+ /* Update the CR index to know from which operation completion
+ routine has to be called */
+ psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
+ /* State update */
+ psNdefMap->State = ISO15693_CHECK_NDEF;
+ /* Reset the NDEF sequence */
+ psNdefMap->ISO15693Container.ndef_seq = 0;
+ psNdefMap->ISO15693Container.current_block = 0;
+ psNdefMap->ISO15693Container.actual_ndef_size = 0;
+ psNdefMap->ISO15693Container.ndef_tlv_type_blk = 0;
+ psNdefMap->ISO15693Container.ndef_tlv_type_byte = 0;
+ psNdefMap->ISO15693Container.store_length = 0;
+ psNdefMap->ISO15693Container.remaining_size_to_read = 0;
+ psNdefMap->ISO15693Container.read_capabilities = 0;
+
+ switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_5])
+ {
+ case ISO15693_UIDBYTE_5_VALUE_SLI_X:
+ {
+ psNdefMap->ISO15693Container.max_data_size =
+ ISO15693_SL2_S2002_ICS20;
+ break;
+ }
+
+ case ISO15693_UIDBYTE_5_VALUE_SLI_X_S:
+ {
+ switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
+ {
+ case ISO15693_UIDBYTE_4_VALUE_SLI_X_S:
+ case ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC:
+ case ISO15693_UIDBYTE_4_VALUE_SLI_X_SY:
+ {
+ psNdefMap->ISO15693Container.max_data_size =
+ ISO15693_SL2_S5302_ICS53_ICS54;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+ break;
+ }
+
+ case ISO15693_UIDBYTE_5_VALUE_SLI_X_L:
+ {
+ switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_4])
+ {
+ case ISO15693_UIDBYTE_4_VALUE_SLI_X_L:
+ case ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC:
+ {
+ psNdefMap->ISO15693Container.max_data_size =
+ ISO15693_SL2_S5002_ICS50_ICS51;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+
+ if (!result)
+ {
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
+ NULL, 0);
+ }
+
+
+ return result;
+}
+
+NFCSTATUS
+phFriNfc_ISO15693_RdNdef (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint8_t *pPacketData,
+ uint32_t *pPacketDataLength,
+ uint8_t Offset)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+
+ /* Update the previous operation with current operation.
+ This becomes the previous operation after this execution */
+ psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
+ /* Update the CR index to know from which operation completion
+ routine has to be called */
+ psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
+ /* State update */
+ psNdefMap->State = ISO15693_READ_NDEF;
+ /* Copy user buffer to the context */
+ psNdefMap->ApduBuffer = pPacketData;
+ /* Copy user length to the context */
+ psNdefMap->ApduBufferSize = *pPacketDataLength;
+ /* Update the user memory size to a context variable */
+ psNdefMap->NumOfBytesRead = pPacketDataLength;
+ /* Number of bytes read from the card is zero.
+ This variable returns the number of bytes read
+ from the card. */
+ *psNdefMap->NumOfBytesRead = 0;
+ /* Index to know the length read */
+ psNdefMap->ApduBuffIndex = 0;
+ /* Store the offset in the context */
+ psNdefMap->Offset = Offset;
+
+ if ((!ps_iso_15693_con->remaining_size_to_read)
+ && (!psNdefMap->Offset))
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
+ }
+ else if (0 == ps_iso_15693_con->actual_ndef_size)
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_READ_FAILED);
+ }
+ else if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_READ_FAILED);
+ }
+ else if (psNdefMap->Offset)
+ {
+ ps_iso_15693_con->remaining_size_to_read =
+ ps_iso_15693_con->actual_ndef_size;
+ ps_iso_15693_con->current_block =
+ ISO15693_GET_VALUE_FIELD_BLOCK_NO(
+ ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ ps_iso_15693_con->actual_ndef_size);
+
+ // Check capabilities
+ if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) ||
+ (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) {
+ result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block);
+ } else {
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
+ NULL, 0);
+ }
+ }
+ else
+ {
+ if (ps_iso_15693_con->store_length > 0)
+ {
+ result = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
+ }
+ else
+ {
+ ps_iso_15693_con->current_block = (uint16_t)
+ (ps_iso_15693_con->current_block + 1);
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
+ NULL, 0);
+ }
+ }
+
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ReadRemainingInMultiple (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint32_t startBlock)
+{
+ NFCSTATUS result = NFCSTATUS_FAILED;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con = &(psNdefMap->ISO15693Container);
+
+ uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size,
+ startBlock, 0);
+ // Check capabilities
+ if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) {
+ // Multi-page read command
+ uint8_t mbread[1];
+ mbread[0] = (remaining_size / ISO15693_BYTES_PER_BLOCK) - 1;
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_MULTIPLE_COMMAND,
+ mbread, 1);
+ } else if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR) {
+ uint32_t page = 0;
+ uint32_t pagesToRead = (remaining_size / ISO15693_BYTES_PER_BLOCK / 4) - 1;
+ if ((remaining_size % (ISO15693_BYTES_PER_BLOCK * ISO15693_BLOCKS_PER_PAGE)) != 0) {
+ pagesToRead++;
+ }
+ result = phFriNfc_ISO15693_H_Inventory_Page_Read (psNdefMap, ICODE_INVENTORY_PAGEREAD_COMMAND,
+ page, pagesToRead);
+ // Inventory
+ } else {
+ result = NFCSTATUS_FAILED;
+ }
+ return result;
+}
+
+NFCSTATUS
+phFriNfc_ISO15693_WrNdef (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint8_t *pPacketData,
+ uint32_t *pPacketDataLength,
+ uint8_t Offset)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+ uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0};
+
+ /* Update the previous operation with current operation.
+ This becomes the previous operation after this execution */
+ psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
+ /* Update the CR index to know from which operation completion
+ routine has to be called */
+ psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
+ /* State update */
+ psNdefMap->State = ISO15693_WRITE_NDEF;
+ /* Copy user buffer to the context */
+ psNdefMap->ApduBuffer = pPacketData;
+ /* Copy user length to the context */
+ psNdefMap->ApduBufferSize = *pPacketDataLength;
+ /* Update the user memory size to a context variable */
+ psNdefMap->NumOfBytesRead = pPacketDataLength;
+ /* Number of bytes written to the card is zero.
+ This variable returns the number of bytes written
+ to the card. */
+ *psNdefMap->WrNdefPacketLength = 0;
+ /* Index to know the length read */
+ psNdefMap->ApduBuffIndex = 0;
+ /* Store the offset in the context */
+ psNdefMap->Offset = Offset;
+
+ ps_iso_15693_con->current_block =
+ ISO15693_GET_LEN_FIELD_BLOCK_NO(
+ ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ *pPacketDataLength);
+
+ if (ISO15693_GET_LEN_FIELD_BYTE_NO(
+ ps_iso_15693_con->ndef_tlv_type_blk,
+ ps_iso_15693_con->ndef_tlv_type_byte,
+ *pPacketDataLength))
+ {
+ ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_NDEF_L_0;
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_READ_COMMAND, NULL, 0);
+ }
+ else
+ {
+ ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_WRITE_DATA;
+
+ /* Length is made 0x00 */
+ *a_write_buf = 0x00;
+
+ /* Write remaining data */
+ (void)memcpy ((void *)(a_write_buf + 1),
+ (void *)psNdefMap->ApduBuffer,
+ (ISO15693_BYTES_PER_BLOCK - 1));
+
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_WRITE_COMMAND,
+ a_write_buf, ISO15693_BYTES_PER_BLOCK);
+
+ psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex
+ + (ISO15693_BYTES_PER_BLOCK - 1));
+ }
+
+ return result;
+}
+
+#ifdef FRINFC_READONLY_NDEF
+
+NFCSTATUS
+phFriNfc_ISO15693_ConvertToReadOnly (
+ phFriNfc_NdefMap_t *psNdefMap)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693Cont_t *ps_iso_15693_con =
+ &(psNdefMap->ISO15693Container);
+
+ psNdefMap->State = ISO15693_READ_ONLY_NDEF;
+ ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_CC;
+ ps_iso_15693_con->current_block = 0;
+
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_READ_COMMAND, NULL, 0);
+
+ return result;
+}
+
+#endif /* #ifdef FRINFC_READONLY_NDEF */
+
+
+void
+phFriNfc_ISO15693_Process (
+ void *pContext,
+ NFCSTATUS Status)
+{
+ phFriNfc_NdefMap_t *psNdefMap =
+ (phFriNfc_NdefMap_t *)pContext;
+
+ if ((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
+ {
+ switch (psNdefMap->State)
+ {
+ case ISO15693_CHECK_NDEF:
+ {
+ Status = phFriNfc_ISO15693_H_ProcessCheckNdef (psNdefMap);
+ break;
+ }
+
+ case ISO15693_READ_NDEF:
+ {
+ Status = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
+ break;
+ }
+
+ case ISO15693_WRITE_NDEF:
+ {
+ Status = phFriNfc_ISO15693_H_ProcessWriteNdef (psNdefMap);
+ break;
+ }
+
+#ifdef FRINFC_READONLY_NDEF
+ case ISO15693_READ_ONLY_NDEF:
+ {
+ Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap);
+ break;
+ }
+#endif /* #ifdef FRINFC_READONLY_NDEF */
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ /* Call for the Completion Routine*/
+ if (NFCSTATUS_PENDING != Status)
+ {
+ phFriNfc_ISO15693_H_Complete(psNdefMap, Status);
+ }
+}
+
+/************************** END external functions *********************/
+
+#endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
diff --git a/src/phFriNfc_ISO15693Map.h b/src/phFriNfc_ISO15693Map.h
new file mode 100644
index 0000000..f696019
--- /dev/null
+++ b/src/phFriNfc_ISO15693Map.h
@@ -0,0 +1,219 @@
+/*
+/*
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * \file phFriNfc_ISO15693Map.h
+ * \brief NFC Ndef Mapping For ISO-15693 Smart Card.
+ *
+ * Project: NFC-FRI
+ *
+ * $Date: $
+ * $Author: ing02260 $
+ * $Revision: $
+ * $Aliases: $
+ *
+ */
+
+#ifndef PHFRINFC_ISO15693MAP_H
+#define PHFRINFC_ISO15693MAP_H
+
+/************************** START MACROS definition *********************/
+/* BYTES in a BLOCK */
+#define ISO15693_BYTES_PER_BLOCK 0x04U
+/* BLOCKS per page */
+#define ISO15693_BLOCKS_PER_PAGE 0x04U
+/* 3 BYTE value identifier for NDEF TLV */
+#define ISO15693_THREE_BYTE_LENGTH_ID 0xFFU
+
+/* Get the NDEF TLV VALUE field block and byte address */
+#define ISO15693_GET_VALUE_FIELD_BLOCK_NO(blk, byte_addr, ndef_size) \
+ (((byte_addr + 1 + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) >= \
+ (ISO15693_BYTES_PER_BLOCK - 1)) ? (blk + 1) : blk)
+
+#define ISO15693_GET_VALUE_FIELD_BYTE_NO(blk, byte_addr, ndef_size) \
+ (((byte_addr + 1 + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) % \
+ ISO15693_BYTES_PER_BLOCK))
+
+/************************** END MACROS definition *********************/
+
+/************************** START Functions declaration *********************/
+/*!
+ * \brief \copydoc page_ovr Initiates Reading of NDEF information from the Remote Device.
+ *
+ * The function initiates the reading of NDEF information from a Remote Device.
+ * It performs a reset of the state and starts the action (state machine).
+ * A periodic call of the \ref phFriNfc_NdefMap_Process has to be done once the action
+ * has been triggered.
+ *
+ * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
+ * the component context.
+ *
+ * \param[in] PacketData Pointer to a location that receives the NDEF Packet.
+ *
+ * \param[in,out] PacketDataLength Pointer to a variable receiving the length of the NDEF packet.
+ *
+ * \param[in] Offset Indicates whether the read operation shall start from the begining of the
+ * file/card storage \b or continue from the last offset. The last Offset set is stored
+ * within a context variable (must not be modified by the integration).
+ * If the caller sets the value to \ref PH_FRINFC_NDEFMAP_SEEK_CUR, the component shall
+ * start reading from the last offset set (continue where it has stopped before).
+ * If set to \ref PH_FRINFC_NDEFMAP_SEEK_BEGIN, the component shall start reading
+ * from the begining of the card (restarted)
+ *
+ * \retval NFCSTATUS_PENDING The action has been successfully triggered.
+ * \retval NFCSTATUS_INVALID_DEVICE_REQUEST If Previous Operation is Write Ndef and Offset
+ * is Current then this error is displayed.
+ * \retval NFCSTATUS_EOF_NDEF_CONTAINER_REACHED No Space in the File to read.
+ * \retval NFCSTATUS_MORE_INFORMATION There are more bytes to read in the card.
+ * \retval NFCSTATUS_SUCCESS Last Byte of the card read.
+ * \retval NFCSTATUS_INVALID_DEVICE The device has not been opened or has been disconnected
+ * meanwhile.
+ * \retval NFCSTATUS_CMD_ABORTED The caller/driver has aborted the request.
+ * \retval NFCSTATUS_BUFFER_TOO_SMALL The buffer provided by the caller is too small.
+ * \retval NFCSTATUS_RF_TIMEOUT No data has been received within the TIMEOUT period.
+ *
+ */
+
+NFCSTATUS
+phFriNfc_ISO15693_RdNdef (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint8_t *pPacketData,
+ uint32_t *pPacketDataLength,
+ uint8_t Offset);
+
+/*!
+ * \brief \copydoc page_ovr Initiates Writing of NDEF information to the Remote Device.
+ *
+ * The function initiates the writing of NDEF information to a Remote Device.
+ * It performs a reset of the state and starts the action (state machine).
+ * A periodic call of the \ref phFriNfc_NdefMap_Process has to be done once the action
+ * has been triggered.
+ *
+ * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
+ * the component context.
+ *
+ * \param[in] PacketData Pointer to a location that holds the prepared NDEF Packet.
+ *
+ * \param[in,out] PacketDataLength Variable specifying the length of the prepared NDEF packet.
+ *
+ * \param[in] Offset Indicates whether the write operation shall start from the begining of the
+ * file/card storage \b or continue from the last offset. The last Offset set is stored
+ * within a context variable (must not be modified by the integration).
+ * If the caller sets the value to \ref PH_FRINFC_NDEFMAP_SEEK_CUR, the component shall
+ * start writing from the last offset set (continue where it has stopped before).
+ * If set to \ref PH_FRINFC_NDEFMAP_SEEK_BEGIN, the component shall start writing
+ * from the begining of the card (restarted)
+ *
+ * \retval NFCSTATUS_PENDING The action has been successfully triggered.
+ * \retval NFCSTATUS_INVALID_DEVICE_REQUEST If Previous Operation is Write Ndef and Offset
+ * is Current then this error is displayed.
+ * \retval NFCSTATUS_EOF_NDEF_CONTAINER_REACHED Last byte is written to the card after this
+ * no further writing is possible.
+ * \retval NFCSTATUS_SUCCESS Buffer provided by the user is completely written
+ * into the card.
+ * \retval NFCSTATUS_INVALID_DEVICE The device has not been opened or has been disconnected
+ * meanwhile.
+ * \retval NFCSTATUS_CMD_ABORTED The caller/driver has aborted the request.
+ * \retval NFCSTATUS_BUFFER_TOO_SMALL The buffer provided by the caller is too small.
+ * \retval NFCSTATUS_RF_TIMEOUT No data has been received within the TIMEOUT period.
+ *
+ */
+
+NFCSTATUS
+phFriNfc_ISO15693_WrNdef (
+ phFriNfc_NdefMap_t *psNdefMap,
+ uint8_t *pPacketData,
+ uint32_t *pPacketDataLength,
+ uint8_t Offset);
+
+/*!
+ * \brief \copydoc page_ovr Check whether a particulat Remote Device is NDEF compliant.
+ *
+ * The function checks whether the peer device is NDEF compliant.
+ *
+ * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
+ * the component context.
+ *
+ * \retval NFCSTATUS_PENDING The action has been successfully triggered.
+ * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
+ * \retval NFCSTATUS_INVALID_DEVICE The device has not been opened or has been disconnected
+ * meanwhile.
+ * \retval NFCSTATUS_CMD_ABORTED The caller/driver has aborted the request.
+ * \retval NFCSTATUS_BUFFER_TOO_SMALL The buffer provided by the caller is too small.
+ * \retval NFCSTATUS_RF_TIMEOUT No data has been received within the TIMEOUT period.
+ *
+ */
+
+NFCSTATUS
+phFriNfc_ISO15693_ChkNdef (
+ phFriNfc_NdefMap_t *psNdefMap);
+
+/*!
+ * \brief \copydoc page_cb Completion Routine, Processing function, needed to avoid long blocking.
+ *
+ * The function call scheme is according to \ref grp_interact. No State reset is performed during operation.
+ *
+ * \copydoc pphFriNfc_Cr_t
+ *
+ * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
+ * Routine in order to be able to notify the component that an I/O has finished and data are
+ * ready to be processed.
+ *
+ */
+
+void
+phFriNfc_ISO15693_Process (
+ void *pContext,
+ NFCSTATUS Status);
+
+#ifdef FRINFC_READONLY_NDEF
+
+/*!
+ * \brief \copydoc page_ovr Initiates Writing of NDEF information to the Remote Device.
+ *
+ * The function initiates the writing of NDEF information to a Remote Device.
+ * It performs a reset of the state and starts the action (state machine).
+ * A periodic call of the \ref phFriNfc_NdefMap_Process has to be done once the action
+ * has been triggered.
+ *
+ * \param[in] psNdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
+ * the component context.
+ *
+ *
+ * \retval NFCSTATUS_PENDING The action has been successfully triggered.
+ * \retval NFCSTATUS_INVALID_DEVICE_REQUEST If Previous Operation is Write Ndef and Offset
+ * is Current then this error is displayed.
+ * \retval NFCSTATUS_EOF_NDEF_CONTAINER_REACHED Last byte is written to the card after this
+ * no further writing is possible.
+ * \retval NFCSTATUS_SUCCESS Buffer provided by the user is completely written
+ * into the card.
+ * \retval NFCSTATUS_INVALID_DEVICE The device has not been opened or has been disconnected
+ * meanwhile.
+ * \retval NFCSTATUS_CMD_ABORTED The caller/driver has aborted the request.
+ * \retval NFCSTATUS_BUFFER_TOO_SMALL The buffer provided by the caller is too small.
+ * \retval NFCSTATUS_RF_TIMEOUT No data has been received within the TIMEOUT period.
+ *
+ */
+NFCSTATUS
+phFriNfc_ISO15693_ConvertToReadOnly (
+ phFriNfc_NdefMap_t *psNdefMap);
+
+#endif /* #ifdef FRINFC_READONLY_NDEF */
+
+/************************** END Functions declaration *********************/
+
+#endif /* #ifndef PHFRINFC_ISO15693MAP_H */
diff --git a/src/phFriNfc_NdefMap.c b/src/phFriNfc_NdefMap.c
index 88cf5ff..28f39f7 100644
--- a/src/phFriNfc_NdefMap.c
+++ b/src/phFriNfc_NdefMap.c
@@ -50,6 +50,10 @@
#include <phFriNfc_FelicaMap.h>
#endif /* PH_FRINFC_MAP_FELICA_DISABLED */
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+#include <phFriNfc_ISO15693Map.h>
+#endif /* PH_FRINFC_MAP_ISO15693_DISABLED */
+
#ifdef PHFRINFC_OVRHAL_MOCKUP
#include <phFriNfc_MockupMap.h>
#endif /* PHFRINFC_OVRHAL_MOCKUP */
@@ -404,6 +408,15 @@ NFCSTATUS phFriNfc_NdefMap_RdNdef( phFriNfc_NdefMap_t *NdefMap,
#endif /* PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED */
#endif /* PH_FRINFC_MAP_TOPAZ_DISABLED */
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+ case PH_FRINFC_NDEFMAP_ISO15693_CARD:
+ status = phFriNfc_ISO15693_RdNdef( NdefMap,
+ PacketData,
+ PacketDataLength,
+ Offset);
+ break;
+#endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
+
#ifdef PHFRINFC_OVRHAL_MOCKUP
case PH_FRINFC_NDEFMAP_MOCKUP_CARD :
/* Mockup card selected. Call Mockup Write */
@@ -596,6 +609,15 @@ NFCSTATUS phFriNfc_NdefMap_WrNdef( phFriNfc_NdefMap_t *NdefMap,
#endif /* PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED */
#endif /* PH_FRINFC_MAP_TOPAZ_DISABLED */
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+ case PH_FRINFC_NDEFMAP_ISO15693_CARD:
+ status = phFriNfc_ISO15693_WrNdef( NdefMap,
+ PacketData,
+ PacketDataLength,
+ Offset);
+ break;
+#endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
+
#ifdef PHFRINFC_OVRHAL_MOCKUP
case PH_FRINFC_NDEFMAP_MOCKUP_CARD :
@@ -618,6 +640,7 @@ NFCSTATUS phFriNfc_NdefMap_WrNdef( phFriNfc_NdefMap_t *NdefMap,
}
#ifdef FRINFC_READONLY_NDEF
+
NFCSTATUS
phFriNfc_NdefMap_ConvertToReadOnly (
phFriNfc_NdefMap_t *NdefMap)
@@ -657,10 +680,17 @@ phFriNfc_NdefMap_ConvertToReadOnly (
NFCSTATUS_INVALID_REMOTE_DEVICE);
break;
}
+
+ case PH_FRINFC_NDEFMAP_ISO15693_CARD:
+ {
+ result = phFriNfc_ISO15693_ConvertToReadOnly (NdefMap);
+ break;
+ }
}
}
return result;
}
+
#endif /* #ifdef FRINFC_READONLY_NDEF */
/*!
@@ -721,6 +751,17 @@ NFCSTATUS phFriNfc_NdefMap_ChkNdef( phFriNfc_NdefMap_t *NdefMap)
switch ( NdefMap->psRemoteDevInfo->RemDevType )
{
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+ case phHal_eISO15693_PICC:
+ {
+ status = phFriNfc_ISO15693_ChkNdef (NdefMap);
+ break;
+ }
+#else /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
+ status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_REMOTE_DEVICE);
+#endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
+
case phHal_eMifare_PICC:
case phHal_eISO14443_3A_PICC:
/* Remote device is Mifare card . Check for Mifare
@@ -1156,6 +1197,9 @@ NFCSTATUS phFriNfc_NdefMap_EraseNdef(phFriNfc_NdefMap_t *NdefMap)
#ifndef PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED
case PH_FRINFC_NDEFMAP_TOPAZ_DYNAMIC_CARD :
#endif
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+ case PH_FRINFC_NDEFMAP_ISO15693_CARD:
+#endif
#endif
/* Mifare card selected. Call Mifare Write */
status = phFriNfc_NdefMap_WrNdef( NdefMap,
@@ -1360,6 +1404,38 @@ NFCSTATUS phFriNfc_NdefMap_GetContainerSize(const phFriNfc_NdefMap_t *NdefMap,ui
break;
#endif /* PH_FRINFC_MAP_FELICA_DISABLED */
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+ case PH_FRINFC_NDEFMAP_ISO15693_CARD:
+ {
+#if 0
+ uint16_t block_no = 0;
+ uint8_t byte_no = 0;
+
+ block_no = (uint16_t)
+ ISO15693_GET_VALUE_FIELD_BLOCK_NO (
+ NdefMap->ISO15693Container.ndef_tlv_type_blk,
+ NdefMap->ISO15693Container.ndef_tlv_type_byte,
+ NdefMap->ISO15693Container.actual_ndef_size);
+ byte_no = (uint8_t)
+ ISO15693_GET_VALUE_FIELD_BYTE_NO (
+ NdefMap->ISO15693Container.ndef_tlv_type_blk,
+ NdefMap->ISO15693Container.ndef_tlv_type_byte,
+ NdefMap->ISO15693Container.actual_ndef_size);
+
+ *maxSize = (NdefMap->ISO15693Container.max_data_size -
+ ((NdefMap->ISO15693Container.actual_ndef_size > 0) ?
+ ((block_no * ISO15693_BYTES_PER_BLOCK) + byte_no) :
+ ISO15693_BYTES_PER_BLOCK));
+#else /* #if 0 */
+ /* 2 is used to exclude the T and L part of the TLV */
+ *maxSize = (NdefMap->ISO15693Container.max_data_size
+ - ISO15693_BYTES_PER_BLOCK - 2);
+#endif /* #if 0 */
+ *actualSize = NdefMap->ISO15693Container.actual_ndef_size;
+ break;
+ }
+#endif
+
#ifdef PHFRINFC_OVRHAL_MOCKUP
case PH_FRINFC_NDEFMAP_MOCKUP_CARD :
*maxSize = 0xFFFFFFFF;
diff --git a/src/phFriNfc_NdefMap.h b/src/phFriNfc_NdefMap.h
index a7d3459..13eb348 100644
--- a/src/phFriNfc_NdefMap.h
+++ b/src/phFriNfc_NdefMap.h
@@ -20,9 +20,9 @@
*
* Project: NFC-FRI
*
- * $Date: Tue Jul 27 08:58:22 2010 $
+ * $Date: Mon Dec 13 14:14:14 2010 $
* $Author: ing02260 $
- * $Revision: 1.24 $
+ * $Revision: 1.25 $
* $Aliases: $
*
*/
@@ -108,6 +108,8 @@
#define PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 9 /**< \internal Iso 14443-4A EV1 */
#endif /* #ifdef DESFIRE_EV1 */
+#define PH_FRINFC_NDEFMAP_ISO15693_CARD 10 /**< \internal ISO 15693 */
+
#ifdef PH_NDEF_MIFARE_ULC
#define PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD 8 /**< \internal Mifare UL */
@@ -245,7 +247,41 @@ typedef enum
#ifndef PH_FRINFC_EXCLUDE_FROM_TESTFW /* */
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+
+#define ISO15693_MAX_DATA_TO_STORE 0x04U
+typedef struct phFriNfc_ISO15693Cont
+{
+ /**< \internal block number that is executed */
+ uint16_t current_block;
+ /**< \internal The state of the operation */
+ uint8_t state;
+ /**< \internal Completion routine index */
+ uint8_t cr_index;
+ /**< \internal Execution sequence */
+ uint8_t ndef_seq;
+ /**< \internal NDEF TLV size */
+ uint16_t actual_ndef_size;
+ /**< \internal NDEF TLV size */
+ uint16_t max_data_size;
+ /**< \internal NDEF TLV TYPE block number */
+ uint16_t ndef_tlv_type_blk;
+ /**< \internal NDEF TLV TYPE byte number in the
+ "ndef_tlv_type_blk" */
+ uint8_t ndef_tlv_type_byte;
+ /**< \internal Store the remaining bytes that can be used for
+ READ with continue option */
+ uint8_t store_read_data[ISO15693_MAX_DATA_TO_STORE];
+ uint8_t store_length;
+ /**< \internal Remaining size that can be read */
+ uint16_t remaining_size_to_read;
+ uint8_t read_capabilities;
+
+
+}phFriNfc_ISO15693Cont_t;
+
+#endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
@@ -903,6 +939,10 @@ typedef struct phFriNfc_NdefMap
phFriNfc_TopazCont_t TopazContainer;
#endif /* PH_FRINFC_MAP_TOPAZ_DISABLED */
+#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
+ phFriNfc_ISO15693Cont_t ISO15693Container;
+#endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */
+
#ifdef PHFRINFC_OVRHAL_MOCKUP
phFriNfc_MockupCont_t MochupContainer;
#endif /* PHFRINFC_OVRHAL_MOCKUP */