summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <martijn.coenen@nxp.com>2011-02-24 20:34:13 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-02-24 20:34:13 -0800
commit649229da505c1f8564f6dd6f2873a9a96416a7d9 (patch)
treeda98a1a69cd065f1ad6474a4b0a40cfa63cc5fce
parentbb2e41f0d14865792bafbd9a4ff2aa778fde2049 (diff)
parent4f3ef022906e5d3b763fbcfe81e3f5cd53976ab5 (diff)
downloadexternal_libnfc-nxp-649229da505c1f8564f6dd6f2873a9a96416a7d9.zip
external_libnfc-nxp-649229da505c1f8564f6dd6f2873a9a96416a7d9.tar.gz
external_libnfc-nxp-649229da505c1f8564f6dd6f2873a9a96416a7d9.tar.bz2
am 4f3ef022: Support formatting / makeReadOnly() of NDEF on ICODE.
* commit '4f3ef022906e5d3b763fbcfe81e3f5cd53976ab5': Support formatting / makeReadOnly() of NDEF on ICODE.
-rw-r--r--Android.mk1
-rw-r--r--src/phFriNfc.h1
-rw-r--r--src/phFriNfc_ISO15693Format.c594
-rw-r--r--src/phFriNfc_ISO15693Format.h116
-rw-r--r--src/phFriNfc_ISO15693Map.c215
-rw-r--r--src/phFriNfc_ISO15693Map.h2
-rw-r--r--src/phFriNfc_NdefMap.c20
-rw-r--r--src/phFriNfc_SmtCrdFmt.c30
-rw-r--r--src/phFriNfc_SmtCrdFmt.h22
-rw-r--r--src/phLibNfc_ndef_raw.c9
10 files changed, 958 insertions, 52 deletions
diff --git a/Android.mk b/Android.mk
index 3284051..9b122a1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -89,6 +89,7 @@ LOCAL_SRC_FILES += src/phFriNfc_DesfireFormat.c
LOCAL_SRC_FILES += src/phFriNfc_MifULFormat.c
LOCAL_SRC_FILES += src/phFriNfc_MifStdFormat.c
LOCAL_SRC_FILES += src/phFriNfc_SmtCrdFmt.c
+LOCAL_SRC_FILES += src/phFriNfc_ISO15693Format.c
#phFriNfc_OvrHal
LOCAL_SRC_FILES += src/phFriNfc_OvrHal.c
diff --git a/src/phFriNfc.h b/src/phFriNfc.h
index fb4b5ee..3677405 100644
--- a/src/phFriNfc.h
+++ b/src/phFriNfc.h
@@ -67,6 +67,7 @@
#define PH_FRINFC_FMT_DESFIRE_DISABLED
#define PH_FRINFC_FMT_MIFAREUL_DISABLED
#define PH_FRINFC_FMT_MIFARESTD_DISABLED
+#define PH_FRINFC_FMT_ISO15693_DISABLED
#endif /* #ifdef DISABLE_FORMAT */
#define PH_FRINFC_FMT_TOPAZ_DISABLED
diff --git a/src/phFriNfc_ISO15693Format.c b/src/phFriNfc_ISO15693Format.c
new file mode 100644
index 0000000..574c107
--- /dev/null
+++ b/src/phFriNfc_ISO15693Format.c
@@ -0,0 +1,594 @@
+/*
+/*
+ * 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_ISO15693Format.c
+* \brief This component encapsulates different format functinalities ,
+* for the ISO-15693 card.
+*
+* Project: NFC-FRI
+*
+* $Date: $
+* $Author: ing02260 $
+* $Revision: 1.0 $
+* $Aliases: $
+*
+*/
+
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+
+#include <phNfcTypes.h>
+#include <phFriNfc_OvrHal.h>
+#include <phFriNfc_SmtCrdFmt.h>
+#include <phFriNfc_ISO15693Format.h>
+
+
+/****************************** Macro definitions start ********************************/
+/* State for the format */
+#define ISO15693_FORMAT 0x01U
+
+/* Bytes per block in the ISO-15693 */
+#define ISO15693_BYTES_PER_BLOCK 0x04U
+
+/* ISO-15693 Commands
+GET SYSTEM INFORMATION COMMAND
+*/
+#define ISO15693_GET_SYSTEM_INFO_CMD 0x2BU
+/* READ SINGLE BLOCK COMMAND */
+#define ISO15693_RD_SINGLE_BLK_CMD 0x20U
+/* WRITE SINGLE BLOCK COMMAND */
+#define ISO15693_WR_SINGLE_BLK_CMD 0x21U
+/* READ MULTIPLE BLOCK COMMAND */
+#define ISO15693_RD_MULTIPLE_BLKS_CMD 0x23U
+
+/* CC bytes
+CC BYTE 0 - Magic Number - 0xE1
+*/
+#define ISO15693_CC_MAGIC_NUM 0xE1U
+/* CC BYTE 1 - Mapping version and READ WRITE settings 0x40
+*/
+#define ISO15693_CC_VER_RW 0x40U
+/* CC BYTE 2 - max size is calaculated using the byte 3 multiplied by 8 */
+#define ISO15693_CC_MULTIPLE_FACTOR 0x08U
+
+/* Inventory command support mask for the CC byte 4 */
+#define ISO15693_INVENTORY_CMD_MASK 0x02U
+/* Read MULTIPLE blocks support mask for CC byte 4 */
+#define ISO15693_RDMULBLKS_CMD_MASK 0x01U
+/* Flags for the command */
+#define ISO15693_FMT_FLAGS 0x20U
+
+/* Read two blocks */
+#define ISO15693_RD_2_BLOCKS 0x02U
+
+/* TYPE identifier of the NDEF TLV */
+#define ISO15693_NDEF_TLV_TYPE_ID 0x03U
+/* Terminator TLV identifier */
+#define ISO15693_TERMINATOR_TLV_ID 0xFEU
+
+/* UID 7th byte value shall be 0xE0 */
+#define ISO15693_7TH_BYTE_UID_VALUE 0xE0U
+#define ISO15693_BYTE_7_INDEX 0x07U
+
+/* UID 6th byte value shall be 0x04 - NXP manufacturer */
+#define ISO15693_6TH_BYTE_UID_VALUE 0x04U
+#define ISO15693_BYTE_6_INDEX 0x06U
+
+#define ISO15693_EXTRA_RESPONSE_FLAG 0x01U
+
+#define ISO15693_GET_SYS_INFO_RESP_LEN 0x0EU
+#define ISO15693_DSFID_MASK 0x01U
+#define ISO15693_AFI_MASK 0x02U
+#define ISO15693_MAX_SIZE_MASK 0x04U
+#define ISO15693_ICREF_MASK 0x08U
+#define ISO15693_SKIP_DFSID 0x01U
+#define ISO15693_SKIP_AFI 0x01U
+#define ISO15693_BLOCK_SIZE_IN_BYTES_MASK 0x1FU
+
+
+/* MAXimum size of ICODE SLI/X */
+#define ISO15693_SLI_X_MAX_SIZE 112U
+/* MAXimum size of ICODE SLI/X - S */
+#define ISO15693_SLI_X_S_MAX_SIZE 160U
+/* MAXimum size of ICODE SLI/X - L */
+#define ISO15693_SLI_X_L_MAX_SIZE 32U
+/****************************** Macro definitions end ********************************/
+
+/****************************** Data structures start ********************************/
+typedef enum phFriNfc_ISO15693_FormatSeq
+{
+ ISO15693_GET_SYS_INFO,
+ ISO15693_RD_MULTIPLE_BLKS_CHECK,
+ ISO15693_WRITE_CC_FMT,
+ ISO15693_WRITE_NDEF_TLV
+}phFriNfc_ISO15693_FormatSeq_t;
+/****************************** Data structures end ********************************/
+
+/*********************** Static function declarations start ***********************/
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProFormat (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt);
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_GetMaxDataSize (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt,
+ uint8_t *p_recv_buf,
+ uint8_t recv_length);
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_FmtReadWrite (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt,
+ uint8_t command,
+ uint8_t *p_data,
+ uint8_t data_length);
+/*********************** Static function declarations end ***********************/
+
+/*********************** Static function definitions start ***********************/
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_FmtReadWrite (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt,
+ 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*/
+ psNdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
+ psNdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0;
+ psNdefSmtCrdFmt->psDepAdditionalInfo.NAD = 0;
+
+ psNdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine =
+ phFriNfc_ISO15693_FmtProcess;
+ psNdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = psNdefSmtCrdFmt;
+
+ *psNdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
+
+ psNdefSmtCrdFmt->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd;
+
+ *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)ISO15693_FMT_FLAGS;
+ send_index = (uint8_t)(send_index + 1);
+
+ *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)command;
+ send_index = (uint8_t)(send_index + 1);
+
+ (void)memcpy ((void *)(psNdefSmtCrdFmt->SendRecvBuf + send_index),
+ (void *)psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid,
+ psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+ send_index = (uint8_t)(send_index +
+ psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength);
+
+ switch (command)
+ {
+ case ISO15693_WR_SINGLE_BLK_CMD:
+ case ISO15693_RD_MULTIPLE_BLKS_CMD:
+ {
+ *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)
+ psNdefSmtCrdFmt->AddInfo.s_iso15693_info.current_block;
+ send_index = (uint8_t)(send_index + 1);
+
+ if (data_length)
+ {
+ (void)memcpy ((void *)(psNdefSmtCrdFmt->SendRecvBuf + send_index),
+ (void *)p_data, data_length);
+ send_index = (uint8_t)(send_index + data_length);
+ }
+ else
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ }
+ break;
+ }
+
+ case ISO15693_RD_SINGLE_BLK_CMD:
+ {
+ *(psNdefSmtCrdFmt->SendRecvBuf + send_index) = (uint8_t)
+ psNdefSmtCrdFmt->AddInfo.s_iso15693_info.current_block;
+ send_index = (uint8_t)(send_index + 1);
+ break;
+ }
+
+ case ISO15693_GET_SYSTEM_INFO_CMD:
+ {
+ /* Dont do anything */
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+
+ psNdefSmtCrdFmt->SendLength = send_index;
+
+ if (!result)
+ {
+ result = phFriNfc_OvrHal_Transceive(psNdefSmtCrdFmt->LowerDevice,
+ &psNdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
+ psNdefSmtCrdFmt->psRemoteDevInfo,
+ psNdefSmtCrdFmt->Cmd,
+ &psNdefSmtCrdFmt->psDepAdditionalInfo,
+ psNdefSmtCrdFmt->SendRecvBuf,
+ psNdefSmtCrdFmt->SendLength,
+ psNdefSmtCrdFmt->SendRecvBuf,
+ psNdefSmtCrdFmt->SendRecvLength);
+ }
+
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_GetMaxDataSize (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt,
+ uint8_t *p_recv_buf,
+ uint8_t recv_length)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693_AddInfo_t *ps_iso15693_info =
+ &(psNdefSmtCrdFmt->AddInfo.s_iso15693_info);
+ phHal_sIso15693Info_t *ps_rem_iso_15693_info =
+ &(psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
+ uint8_t recv_index = 0;
+
+ if ((ISO15693_GET_SYS_INFO_RESP_LEN == recv_length)
+ && (ISO15693_MAX_SIZE_MASK == (*p_recv_buf & ISO15693_MAX_SIZE_MASK)))
+ {
+ uint8_t information_flag = *p_recv_buf;
+ /* MAX size is present in the system information and
+ also response length is correct */
+ recv_index = (uint8_t)(recv_index + 1);
+
+ if (!phOsalNfc_MemCompare ((void *)ps_rem_iso_15693_info->Uid,
+ (void *)(p_recv_buf + recv_index),
+ ps_rem_iso_15693_info->UidLength))
+ {
+ /* UID comaparision successful */
+ uint8_t no_of_blocks = 0;
+ uint8_t blk_size_in_bytes = 0;
+ uint8_t ic_reference = 0;
+
+ /* So skip the UID size compared in the received buffer */
+ recv_index = (uint8_t)(recv_index +
+ ps_rem_iso_15693_info->UidLength);
+
+ if (information_flag & ISO15693_DSFID_MASK) {
+ /* Skip DFSID */
+ recv_index = (uint8_t)(recv_index + ISO15693_SKIP_DFSID);
+ }
+ if (information_flag & ISO15693_AFI_MASK) {
+ /* Skip AFI */
+ recv_index = (uint8_t)(recv_index + ISO15693_SKIP_AFI);
+ }
+
+ /* To get the number of blocks in the card */
+ no_of_blocks = (uint8_t)(*(p_recv_buf + recv_index) + 1);
+ recv_index = (uint8_t)(recv_index + 1);
+
+ /* To get the each block size in bytes */
+ blk_size_in_bytes = (uint8_t)((*(p_recv_buf + recv_index)
+ & ISO15693_BLOCK_SIZE_IN_BYTES_MASK) + 1);
+ recv_index = (uint8_t)(recv_index + 1);
+
+ if (information_flag & ISO15693_ICREF_MASK) {
+ /* Get the IC reference */
+ ic_reference = (uint8_t)(*(p_recv_buf + recv_index));
+ if (ic_reference == 0x03) {
+ no_of_blocks = 8;
+ }
+ }
+
+ /* calculate maximum data size in the card */
+ ps_iso15693_info->max_data_size = (uint16_t)
+ (no_of_blocks * blk_size_in_bytes);
+
+ }
+ else
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ }
+ }
+ else
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ }
+
+
+ return result;
+}
+
+static
+NFCSTATUS
+phFriNfc_ISO15693_H_ProFormat (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phFriNfc_ISO15693_AddInfo_t *ps_iso15693_info =
+ &(psNdefSmtCrdFmt->AddInfo.s_iso15693_info);
+ phFriNfc_ISO15693_FormatSeq_t e_format_seq =
+ (phFriNfc_ISO15693_FormatSeq_t)
+ ps_iso15693_info->format_seq;
+ uint8_t command_type = 0;
+ uint8_t a_send_byte[ISO15693_BYTES_PER_BLOCK] = {0};
+ uint8_t send_length = 0;
+ uint8_t send_index = 0;
+ uint8_t format_complete = FALSE;
+
+ switch (e_format_seq)
+ {
+ case ISO15693_GET_SYS_INFO:
+ {
+ /* RESPONSE received for GET SYSTEM INFO */
+
+ if (!phFriNfc_ISO15693_H_GetMaxDataSize (psNdefSmtCrdFmt,
+ (psNdefSmtCrdFmt->SendRecvBuf + ISO15693_EXTRA_RESPONSE_FLAG),
+ (uint8_t)(*psNdefSmtCrdFmt->SendRecvLength -
+ ISO15693_EXTRA_RESPONSE_FLAG)))
+ {
+ /* Send the READ MULTIPLE BLOCKS COMMAND */
+ command_type = ISO15693_RD_MULTIPLE_BLKS_CMD;
+ e_format_seq = ISO15693_RD_MULTIPLE_BLKS_CHECK;
+
+ /* Prepare data for the command,
+ First add the current block */
+ *a_send_byte = (uint8_t)ps_iso15693_info->current_block;
+ send_index = (uint8_t)(send_index + 1);
+
+ /* Second, add number of blocks to read, here 2 blocks means
+ 8 bytes. 1 is decremented because to read multiple block.
+ the first block is read by default, apart from the first block,
+ next block shall be read, that means remaining block to read is 1
+ So, if for eg: 2 blocks needs to be read from block number 0, then 1
+ is number of blocks to read. This will read both block 0 and 1
+ */
+ *(a_send_byte + send_index) = (uint8_t)
+ (ISO15693_RD_2_BLOCKS - 1);
+ send_index = (uint8_t)(send_index + 1);
+
+ send_length = send_index;
+ }
+ else
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_RECEIVE_LENGTH);
+ }
+ break;
+ }
+
+ case ISO15693_RD_MULTIPLE_BLKS_CHECK:
+ {
+ /* RESPONSE received for READ MULTIPLE BLOCKS
+ received, prepare data for writing CC bytes */
+
+ command_type = ISO15693_WR_SINGLE_BLK_CMD;
+ e_format_seq = ISO15693_WRITE_CC_FMT;
+
+ /* CC magic number */
+ *a_send_byte = (uint8_t)ISO15693_CC_MAGIC_NUM;
+ send_index = (uint8_t)(send_index + 1);
+
+ /* CC Version and read/write access */
+ *(a_send_byte + send_index) = (uint8_t)
+ ISO15693_CC_VER_RW;
+ send_index = (uint8_t)(send_index + 1);
+
+ /* CC MAX data size, calculated during GET system information */
+ *(a_send_byte + send_index) = (uint8_t)
+ (ps_iso15693_info->max_data_size /
+ ISO15693_CC_MULTIPLE_FACTOR);
+ send_index = (uint8_t)(send_index + 1);
+
+ switch (ps_iso15693_info->max_data_size)
+ {
+ case ISO15693_SLI_X_MAX_SIZE:
+ {
+ /* For SLI tags : Inventory Page read not supported */
+ *(a_send_byte + send_index) = (uint8_t)
+ ISO15693_RDMULBLKS_CMD_MASK;
+ break;
+ }
+
+ case ISO15693_SLI_X_S_MAX_SIZE:
+ {
+ /* For SLI - S tags : Read multiple blocks not supported */
+ *(a_send_byte + send_index) = (uint8_t)
+ ISO15693_INVENTORY_CMD_MASK;
+ break;
+ }
+
+ case ISO15693_SLI_X_L_MAX_SIZE:
+ {
+ /* For SLI - L tags : Read multiple blocks not supported */
+ *(a_send_byte + send_index) = (uint8_t)
+ ISO15693_INVENTORY_CMD_MASK;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+
+ send_index = (uint8_t)(send_index + 1);
+
+ send_length = sizeof (a_send_byte);
+
+ break;
+ }
+
+ case ISO15693_WRITE_CC_FMT:
+ {
+ /* CC byte write succcessful.
+ Prepare data for NDEF TLV writing */
+ command_type = ISO15693_WR_SINGLE_BLK_CMD;
+ e_format_seq = ISO15693_WRITE_NDEF_TLV;
+
+ ps_iso15693_info->current_block = (uint16_t)
+ (ps_iso15693_info->current_block + 1);
+
+ /* NDEF TLV - Type byte updated to 0x03 */
+ *a_send_byte = (uint8_t)ISO15693_NDEF_TLV_TYPE_ID;
+ send_index = (uint8_t)(send_index + 1);
+
+ /* NDEF TLV - Length byte updated to 0 */
+ *(a_send_byte + send_index) = 0;
+ send_index = (uint8_t)(send_index + 1);
+
+ /* Terminator TLV - value updated to 0xFEU */
+ *(a_send_byte + send_index) = (uint8_t)
+ ISO15693_TERMINATOR_TLV_ID;
+ send_index = (uint8_t)(send_index + 1);
+
+ send_length = sizeof (a_send_byte);
+ break;
+ }
+
+ case ISO15693_WRITE_NDEF_TLV:
+ {
+ /* SUCCESSFUL formatting complete */
+ format_complete = TRUE;
+ break;
+ }
+
+ default:
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ break;
+ }
+ }
+
+ if ((!format_complete) && (!result))
+ {
+ result = phFriNfc_ISO15693_H_FmtReadWrite (psNdefSmtCrdFmt,
+ command_type, a_send_byte, send_length);
+ }
+
+ ps_iso15693_info->format_seq = (uint8_t)e_format_seq;
+ return result;
+}
+
+/*********************** Static function definitions end ***********************/
+
+/*********************** External function definitions start ***********************/
+void
+phFriNfc_ISO15693_FmtReset (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt)
+{
+ /* reset to ISO15693 data structure */
+ (void)memset((void *)&(psNdefSmtCrdFmt->AddInfo.s_iso15693_info),
+ 0x00, sizeof (phFriNfc_ISO15693_AddInfo_t));
+ psNdefSmtCrdFmt->FmtProcStatus = 0;
+}
+
+NFCSTATUS
+phFriNfc_ISO15693_Format (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ phHal_sIso15693Info_t *ps_rem_iso_15693_info =
+ &(psNdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info);
+
+
+ if ((ISO15693_7TH_BYTE_UID_VALUE ==
+ ps_rem_iso_15693_info->Uid[ISO15693_BYTE_7_INDEX])
+ && (ISO15693_6TH_BYTE_UID_VALUE ==
+ ps_rem_iso_15693_info->Uid[ISO15693_BYTE_6_INDEX]))
+ {
+ /* Check if the card is manufactured by NXP (6th byte
+ index of UID value = 0x04 and the
+ last byte of UID is 0xE0, only then the card detected
+ is NDEF compliant */
+ psNdefSmtCrdFmt->State = ISO15693_FORMAT;
+
+ /* GET system information command to get the card size */
+ result = phFriNfc_ISO15693_H_FmtReadWrite (psNdefSmtCrdFmt,
+ ISO15693_GET_SYSTEM_INFO_CMD, NULL, 0);
+ }
+ else
+ {
+ result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ }
+
+ return result;
+}
+
+void
+phFriNfc_ISO15693_FmtProcess (
+ void *pContext,
+ NFCSTATUS Status)
+{
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt =
+ (phFriNfc_sNdefSmtCrdFmt_t *)pContext;
+ phFriNfc_ISO15693_AddInfo_t *ps_iso15693_info =
+ &(psNdefSmtCrdFmt->AddInfo.s_iso15693_info);
+
+ if((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
+ {
+ if (ISO15693_FORMAT == psNdefSmtCrdFmt->State)
+ {
+ /* Check for further formatting */
+ Status = phFriNfc_ISO15693_H_ProFormat (psNdefSmtCrdFmt);
+ }
+ else
+ {
+ Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ }
+ }
+ else
+ {
+ if (ISO15693_RD_MULTIPLE_BLKS_CHECK ==
+ (phFriNfc_ISO15693_FormatSeq_t)ps_iso15693_info->format_seq)
+ {
+ /* If READ MULTIPLE BLOCKS is not working then
+ do further formatting, disable the READ MULTIPLE BLOCK
+ flag in the CC 4th byte, this says that COMMAND is not
+ supported and dont use this command
+ */
+ Status = phFriNfc_ISO15693_H_ProFormat (psNdefSmtCrdFmt);
+ }
+ }
+
+ /* Handle the all the error cases */
+ if ((NFCSTATUS_PENDING & PHNFCSTBLOWER) != (Status & PHNFCSTBLOWER))
+ {
+ /* call respective CR */
+ phFriNfc_SmtCrdFmt_HCrHandler (psNdefSmtCrdFmt, Status);
+ }
+}
+/*********************** External function definitions end ***********************/
+
+
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
+
diff --git a/src/phFriNfc_ISO15693Format.h b/src/phFriNfc_ISO15693Format.h
new file mode 100644
index 0000000..9dab3c1
--- /dev/null
+++ b/src/phFriNfc_ISO15693Format.h
@@ -0,0 +1,116 @@
+/*
+ * 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_ISO15693Format.h
+* \brief ISO-15693 Smart card formatting.
+*
+* Project: NFC-FRI
+*
+* $Date: $
+* $Author: ing02260 $
+* $Revision: 1.0 $
+* $Aliases: $
+*
+*/
+
+#ifndef PHFRINFC_ISO15693FORMAT_H
+#define PHFRINFC_ISO15693FORMAT_H
+
+/****************************** Macro definitions start ********************************/
+
+/****************************** Macro definitions end ********************************/
+
+/****************************** Data structures start ********************************/
+
+/****************************** Data structures end ********************************/
+
+/*********************** External function declarations start ***********************/
+/*!
+* \brief \copydoc page_reg Resets the component instance to the initial state and lets the component forget about
+* the list of registered items. Moreover, the lower device is set.
+*
+* \param[in] NdefSmtCrdFmt Pointer to a valid or uninitialized instance of \ref phFriNfc_sNdefSmtCrdFmt_t.
+*
+* \note This function has to be called at the beginning, after creating an instance of
+* \ref phFriNfc_sNdefSmtCrdFmt_t. Use this function to reset the instance of smart card
+formatting context variables.
+*/
+void
+phFriNfc_ISO15693_FmtReset (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt);
+
+/*!
+* \ingroup grp_fri_smart_card_formatting
+*
+* \brief Initiates the card formatting procedure for Remote Smart Card Type.
+*
+* \copydoc page_ovr The function initiates and formats the ISO-15693 Card.After this
+* operation,remote card would be properly initialized and
+* Ndef Compliant.Depending upon the different card type, this
+* function handles formatting procedure.This function also handles
+* the different recovery procedures for different types of the cards.
+* For both Format and Recovery Management same API is used.
+*
+* \param[in] phFriNfc_sNdefSmartCardFmt_t Pointer to a valid instance of the \ref phFriNfc_sNdefSmartCardFmt_t
+* structure describing the component context.
+*
+* \retval NFCSTATUS_SUCCESS Card formatting has been successfully completed.
+* \retval NFCSTATUS_PENDING The action has been successfully triggered.
+* \retval NFCSTATUS_FORMAT_ERROR Error occured during the formatting procedure.
+* \retval NFCSTATUS_INVALID_REMOTE_DEVICE Card Type is unsupported.
+* \retval NFCSTATUS_INVALID_DEVICE_REQUEST Command or Operation types are mismatching.
+*
+*/
+NFCSTATUS
+phFriNfc_ISO15693_Format (
+ phFriNfc_sNdefSmtCrdFmt_t *psNdefSmtCrdFmt);
+
+/**
+*\ingroup grp_fri_smart_card_formatting
+*
+* \brief Smart card Formatting \b Completion \b Routine or \b Process function
+*
+* \copydoc page_ovr Completion Routine: This function is called by the lower layer (OVR HAL)
+* when an I/O operation has finished. The internal state machine decides
+* whether to call into the lower device again or to complete the process
+* by calling into the upper layer's completion routine, stored within this
+* component's context (\ref phFriNfc_sNdefSmtCrdFmt_t).
+*
+* The function call scheme is according to \ref grp_interact. No State reset is performed during
+* operation.
+*
+* \param[in] Context The context of the current (not the lower/upper) instance, as set by the lower,
+* calling layer, upon its completion.
+* \param[in] Status The completion status of the lower layer (to be handled by the implementation of
+* the state machine of this function like a regular return value of an internally
+* called function).
+*
+* \note For general information about the completion routine interface please see \ref pphFriNfc_Cr_t .
+* The Different Status Values are as follows
+*
+*/
+void
+phFriNfc_ISO15693_FmtProcess (
+ void *pContext,
+ NFCSTATUS Status);
+
+/*********************** External function declarations end ***********************/
+
+#endif /* #define PHFRINFC_ISO15693FORMAT_H */
+
+
+
diff --git a/src/phFriNfc_ISO15693Map.c b/src/phFriNfc_ISO15693Map.c
index 8b6d1f1..f07b1bf 100644
--- a/src/phFriNfc_ISO15693Map.c
+++ b/src/phFriNfc_ISO15693Map.c
@@ -84,6 +84,14 @@ typedef enum phFriNfc_eRONdefSeq
/* UID bytes to differentiate ICODE cards */
#define ISO15693_UID_BYTE_4 0x04U
#define ISO15693_UID_BYTE_5 0x05U
+#define ISO15693_UID_BYTE_6 0x06U
+#define ISO15693_UID_BYTE_7 0x07U
+
+/* UID 7th byte value shall be 0xE0 */
+#define ISO15693_UIDBYTE_7_VALUE 0xE0U
+/* UID 6th byte value shall be 0x04 - NXP manufacturer */
+#define ISO15693_UIDBYTE_6_VALUE 0x04U
+
/* UID value for
SL2 ICS20
@@ -159,8 +167,6 @@ Magic number */
#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
@@ -205,7 +211,7 @@ Inputs are
(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)) >= \
+ (((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) \
@@ -281,15 +287,17 @@ phFriNfc_ISO15693_H_ProcessWriteNdef (
{
case ISO15693_RD_BEFORE_WR_NDEF_L_0:
{
- p_recv_buf = (psNdefMap->SendRecvBuf +
- ISO15693_EXTRA_RESP_BYTE);
+ /* L byte is read */
+ 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)
{
+ /* Response length is correct */
uint8_t byte_index = 0;
+ /* Copy the recevied buffer */
(void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
recv_length);
@@ -298,12 +306,14 @@ phFriNfc_ISO15693_H_ProcessWriteNdef (
ps_iso_15693_con->ndef_tlv_type_byte,
psNdefMap->ApduBufferSize);
- /* Writing length field to 0 */
+ /* Writing length field to 0, Update length field to 0 */
*(a_write_buf + byte_index) = 0x00;
if ((ISO15693_BYTES_PER_BLOCK - 1) != byte_index)
{
+ /* User data is updated in the buffer */
byte_index = (uint8_t)(byte_index + 1);
+ /* Block number shall be udate */
remaining_size = (ISO15693_BYTES_PER_BLOCK - byte_index);
if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
@@ -314,15 +324,17 @@ phFriNfc_ISO15693_H_ProcessWriteNdef (
}
/* Go to next byte to fill the write buffer */
-
(void)memcpy ((void *)(a_write_buf + byte_index),
(void *)(psNdefMap->ApduBuffer +
psNdefMap->ApduBuffIndex), remaining_size);
+ /* Write index updated */
psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex +
remaining_size);
}
+ /* After this write, user data can be written.
+ Update the sequence accordingly */
e_wr_ndef_seq = ISO15693_WRITE_DATA;
write_flag = TRUE;
} /* if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) */
@@ -415,7 +427,9 @@ phFriNfc_ISO15693_H_ProcessWriteNdef (
}
} /* switch (e_wr_ndef_seq) */
- if (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex)
+ if (((0 == psNdefMap->ApduBuffIndex)
+ || (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex))
+ && (!result))
{
if (FALSE == write_flag)
{
@@ -621,7 +635,7 @@ phFriNfc_ISO15693_H_ProcessReadNdef (
}
if (ps_iso_15693_con->store_length)
{
- /* Continue read option selected
+ /* Continue Offset option selected
So stored data already existing,
copy the information to the user buffer
*/
@@ -632,7 +646,7 @@ phFriNfc_ISO15693_H_ProcessReadNdef (
to the user expected size */
(void)memcpy ((void *)(psNdefMap->ApduBuffer +
psNdefMap->ApduBuffIndex),
- (void *)p_recv_buf,
+ (void *)ps_iso_15693_con->store_read_data,
ps_iso_15693_con->store_length);
psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
@@ -653,6 +667,8 @@ phFriNfc_ISO15693_H_ProcessReadNdef (
(void *)ps_iso_15693_con->store_read_data,
remaining_data_size);
+ /* As stored data is more than the user expected data. So store
+ the remaining bytes again into the data structure */
(void)memcpy ((void *)ps_iso_15693_con->store_read_data,
(void *)(ps_iso_15693_con->store_read_data +
remaining_data_size),
@@ -660,13 +676,19 @@ phFriNfc_ISO15693_H_ProcessReadNdef (
psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
remaining_data_size);
+
+ ps_iso_15693_con->store_length = (uint8_t)
+ (ps_iso_15693_con->store_length - remaining_data_size);
}
} /* if (ps_iso_15693_con->store_length) */
else
{
+ /* Data is read from the card. */
uint8_t byte_index = 0;
remaining_data_size = ps_iso_15693_con->remaining_size_to_read;
+
+ /* Check if the block number is to read the first VALUE field */
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)
@@ -683,44 +705,53 @@ phFriNfc_ISO15693_H_ProcessReadNdef (
if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
< remaining_data_size)
{
+ remaining_data_size = (uint8_t)
+ (recv_length - byte_index);
+ /* user input is less than the remaining card size */
if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)
- < (uint16_t)(recv_length - byte_index))
+ < (uint16_t)remaining_data_size)
{
+ /* user data required is less than the data read */
remaining_data_size = (uint8_t)(psNdefMap->ApduBufferSize -
psNdefMap->ApduBuffIndex);
+
+ if (0 != (recv_length - (byte_index +
+ remaining_data_size)))
+ {
/* 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));
+ (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);
+ (recv_length - (byte_index +
+ remaining_data_size));
}
- else
- {
- remaining_data_size = (uint8_t)
- (recv_length - byte_index);
}
}
else
{
+ /* user data required is equal or greater than the data read */
if (remaining_data_size > (recv_length - byte_index))
{
remaining_data_size = (uint8_t)
(recv_length - byte_index);
}
}
+
+ /* Copy data in the user buffer */
(void)memcpy ((void *)(psNdefMap->ApduBuffer +
psNdefMap->ApduBuffIndex),
(void *)(p_recv_buf + byte_index),
remaining_data_size);
+ /* Update the read index */
psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
remaining_data_size);
- } /* if (ps_iso_15693_con->store_length) */
+ } /* else part of if (ps_iso_15693_con->store_length) */
/* Remaining size is decremented */
ps_iso_15693_con->remaining_size_to_read = (uint8_t)
@@ -744,7 +775,9 @@ phFriNfc_ISO15693_H_ProcessReadNdef (
}
else
{
- /* Read completed */
+ /* Read completed, EITHER index has reached to the user size
+ OR end of the card is reached
+ update the user data structure with read data size */
*psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
}
if (reformatted_buf != NULL) {
@@ -764,22 +797,27 @@ phFriNfc_ISO15693_H_CheckCCBytes (
uint8_t recv_index = 0;
uint8_t *p_recv_buf = (psNdefMap->SendRecvBuf + 1);
+ /* expected CC byte : E1 40 "MAX SIZE depends on tag" */
if (ISO15693_CC_MAGIC_BYTE == *p_recv_buf)
{
+ /* 0xE1 magic byte found*/
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)
{
+ /* Correct mapping version found */
switch (*(p_recv_buf + recv_index) & ISO15693_LSB_NIBBLE_MASK)
{
case ISO15693_RD_WR_PERMISSION:
{
+ /* READ/WRITE possible */
psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
break;
}
case ISO15693_RD_ONLY_PERMISSION:
{
+ /* ONLY READ possible, WRITE NOT possible */
psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
break;
}
@@ -795,6 +833,7 @@ phFriNfc_ISO15693_H_CheckCCBytes (
if (!result)
{
+ /* Update MAX SIZE */
ps_iso_15693_con->max_data_size = (uint16_t)
(*(p_recv_buf + recv_index) *
ISO15693_MULT_FACTOR);
@@ -856,7 +895,8 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
else
{
/* Propreitary TLVs VALUE can end in between a block,
- so when that block is read, dont read the proprietary data */
+ so when that block is read, update the parse_index
+ with byte address value */
if (ISO15693_PROP_TLV_V == e_chk_ndef_seq)
{
parse_index = ps_iso_15693_con->ndef_tlv_type_byte;
@@ -868,20 +908,28 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
&& (NFCSTATUS_SUCCESS == result)
&& (ISO15693_NDEF_TLV_V != e_chk_ndef_seq))
{
+ /* Parse
+ 1. till the received length of the block
+ 2. till there is no error during parse
+ 3. till LENGTH field of NDEF TLV is found
+ */
switch (e_chk_ndef_seq)
{
case ISO15693_NDEF_TLV_T:
{
+ /* Expected value is 0x03 TYPE identifier
+ of the NDEF TLV */
prop_ndef_index = 0;
switch (*(p_recv_buf + parse_index))
{
case ISO15693_NDEF_TLV_TYPE_ID:
{
+ /* Update the data structure with the byte address and
+ the block number */
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;
}
@@ -912,27 +960,36 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
case ISO15693_PROP_TLV_L:
{
+ /* Length field of the proprietary TLV */
switch (prop_ndef_index)
{
+ /* Length field can have 1 or 3 bytes depending
+ on the data size, so check for each index byte */
case 0:
{
+ /* 1st index of the length field of the TLV */
if (0 == *(p_recv_buf + parse_index))
{
+ /* LENGTH is 0, not possible, so error */
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))
{
+ /* 3 byte LENGTH field identified, so increment the
+ index, so next time 2nd byte is parsed */
prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
}
else
{
+ /* 1 byte LENGTH field identified, so "static"
+ index is set to 0 and actual ndef size is
+ copied to the data structure
+ */
ps_iso_15693_con->actual_ndef_size =
*(p_recv_buf + parse_index);
e_chk_ndef_seq = ISO15693_PROP_TLV_V;
@@ -944,6 +1001,8 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
case 1:
{
+ /* 2nd index of the LENGTH field that is MSB of the length,
+ so the length is left shifted by 8 */
ps_iso_15693_con->actual_ndef_size = (uint16_t)
(*(p_recv_buf + parse_index) <<
ISO15693_BTYE_SHIFT);
@@ -953,6 +1012,8 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
case 2:
{
+ /* 3rd index of the LENGTH field that is LSB of the length,
+ so the length ORed with the previously stored size */
ps_iso_15693_con->actual_ndef_size = (uint16_t)
(ps_iso_15693_con->actual_ndef_size |
*(p_recv_buf + parse_index));
@@ -984,6 +1045,7 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
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) +
@@ -1039,12 +1101,17 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
case ISO15693_NDEF_TLV_L:
{
+ /* Length field of the NDEF TLV */
switch (prop_ndef_index)
{
+ /* Length field can have 1 or 3 bytes depending
+ on the data size, so check for each index byte */
case 0:
{
+ /* 1st index of the length field of the TLV */
if (0 == *(p_recv_buf + parse_index))
{
+ /* LENGTH is 0, card is in INITILIASED STATE */
e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
ps_iso_15693_con->actual_ndef_size = 0;
}
@@ -1055,6 +1122,8 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
if (ISO15693_THREE_BYTE_LENGTH_ID ==
*(p_recv_buf + parse_index))
{
+ /* At present no CARD supports more than 255 bytes,
+ so error is returned */
prop_ndef_index = (uint8_t)(prop_ndef_index + 1);
result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_NO_NDEF_SUPPORT);
@@ -1062,8 +1131,13 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
}
else
{
+ /* 1 byte LENGTH field identified, so "static"
+ index is set to 0 and actual ndef size is
+ copied to the data structure
+ */
ps_iso_15693_con->actual_ndef_size =
*(p_recv_buf + parse_index);
+ /* next values are the DATA field of the NDEF TLV */
e_chk_ndef_seq = ISO15693_NDEF_TLV_V;
prop_ndef_index = 0;
}
@@ -1073,6 +1147,8 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
case 1:
{
+ /* 2nd index of the LENGTH field that is MSB of the length,
+ so the length is left shifted by 8 */
ps_iso_15693_con->actual_ndef_size = (uint16_t)
(*(p_recv_buf + parse_index) <<
ISO15693_BTYE_SHIFT);
@@ -1082,6 +1158,8 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
case 2:
{
+ /* 3rd index of the LENGTH field that is LSB of the length,
+ so the length ORed with the previously stored size */
ps_iso_15693_con->actual_ndef_size = (uint16_t)
(ps_iso_15693_con->actual_ndef_size |
*(p_recv_buf + parse_index));
@@ -1102,7 +1180,7 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
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 >
+ "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) ?
@@ -1162,6 +1240,7 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
}
else
{
+ /* Proprietary TLV detected, so skip the proprietary blocks */
ps_iso_15693_con->current_block = ps_iso_15693_con->ndef_tlv_type_blk;
}
@@ -1179,6 +1258,7 @@ phFriNfc_ISO15693_H_ProcessCheckNdef (
}
else
{
+ /* End of card reached, error no NDEF information found */
e_chk_ndef_seq = ISO15693_NDEF_TLV_T;
prop_ndef_index = 0;
/* Error, no size to parse */
@@ -1241,25 +1321,37 @@ phFriNfc_ISO15693_H_ProcessReadOnly (
{
if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length)
{
+ result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap);
+ /* Check CC bytes and also the card state for READ ONLY,
+ if the card is already read only, then dont continue with
+ next operation */
+ if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState)
+ && (!result))
+ {
+ /* CC byte read successful */
(void)memcpy ((void *)a_write_buf, (void *)p_recv_buf,
sizeof (a_write_buf));
+ /* Change the read write access to read only */
*(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,
+ ISO15693_WRITE_COMMAND, a_write_buf,
sizeof (a_write_buf));
e_ro_ndef_seq = ISO15693_WRITE_CC;
}
+ }
break;
}
case ISO15693_WRITE_CC:
{
+ /* Write to CC is successful. */
e_ro_ndef_seq = ISO15693_LOCK_BLOCK;
+ /* Start the lock block command to lock the blocks */
result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
ISO15693_LOCK_BLOCK_CMD, NULL, 0);
break;
@@ -1268,14 +1360,17 @@ phFriNfc_ISO15693_H_ProcessReadOnly (
case ISO15693_LOCK_BLOCK:
{
if (ps_iso_15693_con->current_block ==
- (ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK))
+ ((ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK) -
+ 1))
{
- /* READ ONLY successful */
+ /* End of card reached, READ ONLY successful */
}
else
{
+ /* current block is incremented */
ps_iso_15693_con->current_block = (uint16_t)
(ps_iso_15693_con->current_block + 1);
+ /* Lock the current block */
result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
ISO15693_LOCK_BLOCK_CMD, NULL, 0);
}
@@ -1323,10 +1418,22 @@ phFriNfc_ISO15693_ChkNdef (
psNdefMap->ISO15693Container.remaining_size_to_read = 0;
psNdefMap->ISO15693Container.read_capabilities = 0;
+ if ((ISO15693_UIDBYTE_6_VALUE ==
+ ps_iso_15693_info->Uid[ISO15693_UID_BYTE_6])
+ && (ISO15693_UIDBYTE_7_VALUE ==
+ ps_iso_15693_info->Uid[ISO15693_UID_BYTE_7]))
+ {
+ /* Check if the card is manufactured by NXP (6th byte
+ index of UID value = 0x04 and the
+ last byte i.e., 7th byte of UID is 0xE0, only then the card detected
+ is NDEF compliant */
switch (ps_iso_15693_info->Uid[ISO15693_UID_BYTE_5])
{
+ /* Check for supported tags, by checking the 5th byte index of UID */
case ISO15693_UIDBYTE_5_VALUE_SLI_X:
{
+ /* ISO 15693 card type is ICODE SLI
+ so maximum size is 112 */
psNdefMap->ISO15693Container.max_data_size =
ISO15693_SL2_S2002_ICS20;
break;
@@ -1334,12 +1441,17 @@ phFriNfc_ISO15693_ChkNdef (
case ISO15693_UIDBYTE_5_VALUE_SLI_X_S:
{
+ /* ISO 15693 card type is ICODE SLI/X S
+ so maximum size depends on the 4th UID byte index */
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:
{
+ /* Supported tags are with value (4th byte UID index)
+ of 0x00, 0x80 and 0x40
+ For these cards max size is 160 bytes */
psNdefMap->ISO15693Container.max_data_size =
ISO15693_SL2_S5302_ICS53_ICS54;
break;
@@ -1347,6 +1459,7 @@ phFriNfc_ISO15693_ChkNdef (
default:
{
+ /* Tag not supported */
result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_INVALID_DEVICE_REQUEST);
break;
@@ -1357,11 +1470,16 @@ phFriNfc_ISO15693_ChkNdef (
case ISO15693_UIDBYTE_5_VALUE_SLI_X_L:
{
+ /* ISO 15693 card type is ICODE SLI/X L
+ so maximum size depends on the 4th UID byte index */
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:
{
+ /* Supported tags are with value (4th byte UID index)
+ of 0x00 and 0x80
+ For these cards max size is 32 bytes */
psNdefMap->ISO15693Container.max_data_size =
ISO15693_SL2_S5002_ICS50_ICS51;
break;
@@ -1369,6 +1487,7 @@ phFriNfc_ISO15693_ChkNdef (
default:
{
+ /* Tag not supported */
result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_INVALID_DEVICE_REQUEST);
break;
@@ -1379,14 +1498,23 @@ phFriNfc_ISO15693_ChkNdef (
default:
{
+ /* Tag not supported */
result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_INVALID_DEVICE_REQUEST);
break;
}
}
+ }
+ else
+ {
+ /* Tag not supported */
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_DEVICE_REQUEST);
+ }
if (!result)
{
+ /* Start reading the data */
result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND,
NULL, 0);
}
@@ -1432,21 +1560,27 @@ phFriNfc_ISO15693_RdNdef (
if ((!ps_iso_15693_con->remaining_size_to_read)
&& (!psNdefMap->Offset))
{
+ /* Entire data is already read from the card.
+ There is no data to give */
result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
}
else if (0 == ps_iso_15693_con->actual_ndef_size)
{
+ /* Card is NDEF, but no data in the card. */
result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_READ_FAILED);
}
else if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
{
+ /* Card is NDEF, but no data in the card. */
result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_READ_FAILED);
}
else if (psNdefMap->Offset)
{
+ /* BEGIN offset, so reset the remaining read size and
+ also the curretn block */
ps_iso_15693_con->remaining_size_to_read =
ps_iso_15693_con->actual_ndef_size;
ps_iso_15693_con->current_block =
@@ -1466,16 +1600,19 @@ phFriNfc_ISO15693_RdNdef (
}
else
{
+ /* CONTINUE offset */
if (ps_iso_15693_con->store_length > 0)
{
+ /* Previous read had extra bytes, so data is stored, so give that take
+ that data from store. If more data is required, then read remaining bytes */
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);
+ result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
+ ISO15693_READ_COMMAND, NULL, 0);
}
}
@@ -1550,6 +1687,7 @@ phFriNfc_ISO15693_WrNdef (
/* Store the offset in the context */
psNdefMap->Offset = Offset;
+ /* Set the current block correctly to write the length field to 0 */
ps_iso_15693_con->current_block =
ISO15693_GET_LEN_FIELD_BLOCK_NO(
ps_iso_15693_con->ndef_tlv_type_blk,
@@ -1561,12 +1699,18 @@ phFriNfc_ISO15693_WrNdef (
ps_iso_15693_con->ndef_tlv_type_byte,
*pPacketDataLength))
{
+ /* Check the byte address to write. If length byte address is in between or
+ is the last byte of the block, then READ before write
+ reason, write should not corrupt other data
+ */
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
{
+ /* If length byte address is at the beginning of the block then WRITE
+ length field to 0 and as also write user DATA */
ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_WRITE_DATA;
/* Length is made 0x00 */
@@ -1577,10 +1721,12 @@ phFriNfc_ISO15693_WrNdef (
(void *)psNdefMap->ApduBuffer,
(ISO15693_BYTES_PER_BLOCK - 1));
+ /* Write data */
result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap,
ISO15693_WRITE_COMMAND,
a_write_buf, ISO15693_BYTES_PER_BLOCK);
+ /* Increment the index to keep track of bytes sent for write */
psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex
+ (ISO15693_BYTES_PER_BLOCK - 1));
}
@@ -1599,6 +1745,7 @@ phFriNfc_ISO15693_ConvertToReadOnly (
&(psNdefMap->ISO15693Container);
psNdefMap->State = ISO15693_READ_ONLY_NDEF;
+ /* READ CC bytes */
ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_CC;
ps_iso_15693_con->current_block = 0;
@@ -1625,18 +1772,21 @@ phFriNfc_ISO15693_Process (
{
case ISO15693_CHECK_NDEF:
{
+ /* State = CHECK NDEF in progress */
Status = phFriNfc_ISO15693_H_ProcessCheckNdef (psNdefMap);
break;
}
case ISO15693_READ_NDEF:
{
+ /* State = READ NDEF in progress */
Status = phFriNfc_ISO15693_H_ProcessReadNdef (psNdefMap);
break;
}
case ISO15693_WRITE_NDEF:
{
+ /* State = WRITE NDEF in progress */
Status = phFriNfc_ISO15693_H_ProcessWriteNdef (psNdefMap);
break;
}
@@ -1644,6 +1794,7 @@ phFriNfc_ISO15693_Process (
#ifdef FRINFC_READONLY_NDEF
case ISO15693_READ_ONLY_NDEF:
{
+ /* State = RAD ONLY NDEF in progress */
Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap);
break;
}
diff --git a/src/phFriNfc_ISO15693Map.h b/src/phFriNfc_ISO15693Map.h
index f696019..596534a 100644
--- a/src/phFriNfc_ISO15693Map.h
+++ b/src/phFriNfc_ISO15693Map.h
@@ -41,7 +41,7 @@
/* 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)) >= \
+ (((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) \
diff --git a/src/phFriNfc_NdefMap.c b/src/phFriNfc_NdefMap.c
index 28f39f7..b25e9ec 100644
--- a/src/phFriNfc_NdefMap.c
+++ b/src/phFriNfc_NdefMap.c
@@ -674,16 +674,16 @@ phFriNfc_NdefMap_ConvertToReadOnly (
break;
}
- default:
+ case PH_FRINFC_NDEFMAP_ISO15693_CARD:
{
- result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
- NFCSTATUS_INVALID_REMOTE_DEVICE);
+ result = phFriNfc_ISO15693_ConvertToReadOnly (NdefMap);
break;
}
- case PH_FRINFC_NDEFMAP_ISO15693_CARD:
+ default:
{
- result = phFriNfc_ISO15693_ConvertToReadOnly (NdefMap);
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_REMOTE_DEVICE);
break;
}
}
@@ -1407,7 +1407,7 @@ NFCSTATUS phFriNfc_NdefMap_GetContainerSize(const phFriNfc_NdefMap_t *NdefMap,ui
#ifndef PH_FRINFC_MAP_ISO15693_DISABLED
case PH_FRINFC_NDEFMAP_ISO15693_CARD:
{
-#if 0
+#if 1
uint16_t block_no = 0;
uint8_t byte_no = 0;
@@ -1423,14 +1423,12 @@ NFCSTATUS phFriNfc_NdefMap_GetContainerSize(const phFriNfc_NdefMap_t *NdefMap,ui
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 */
+ ((block_no * ISO15693_BYTES_PER_BLOCK) + byte_no));
+#else /* #if 1 */
/* 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 */
+#endif /* #if 1 */
*actualSize = NdefMap->ISO15693Container.actual_ndef_size;
break;
}
diff --git a/src/phFriNfc_SmtCrdFmt.c b/src/phFriNfc_SmtCrdFmt.c
index 0174c2d..0e250b9 100644
--- a/src/phFriNfc_SmtCrdFmt.c
+++ b/src/phFriNfc_SmtCrdFmt.c
@@ -21,10 +21,10 @@
*
* Project: NFC-FRI
*
- * $Date: Wed Sep 23 14:41:56 2009 $
- * $Author: ing07336 $
- * $Revision: 1.8 $
- * $Aliases: NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $
+ * $Date: Mon Dec 13 14:14:13 2010 $
+ * $Author: ing02260 $
+ * $Revision: 1.9 $
+ * $Aliases: $
*
*/
@@ -39,6 +39,9 @@
#include <phFriNfc_MifULFormat.h>
#include <phFriNfc_DesfireFormat.h>
#include <phFriNfc_MifStdFormat.h>
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+ #include <phFriNfc_ISO15693Format.h>
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
/*! \ingroup grp_file_attributes
@@ -146,6 +149,10 @@ NFCSTATUS phFriNfc_NdefSmtCrd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdF
phFriNfc_MfUL_Reset(NdefSmtCrdFmt);
#endif /* #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED */
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+ phFriNfc_ISO15693_FmtReset (NdefSmtCrdFmt);
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
+
#ifdef PHFRINFC_OVRHAL_MOCKUP
/*Reset Desfire Cap Container elements*/
// phFriNfc_Mockup_H_Reset(NdefSmtCrdFmt);
@@ -392,6 +399,13 @@ NFCSTATUS phFriNfc_NdefSmtCrd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt,
break;
#endif /* PHFRINFC_OVRHAL_MOCKUP */
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+ case phHal_eISO15693_PICC:
+ {
+ Result = phFriNfc_ISO15693_Format (NdefSmtCrdFmt);
+ break;
+ }
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
default :
/* Remote device is not recognised.
Probably not NDEF compliant */
@@ -474,6 +488,14 @@ void phFriNfc_NdefSmtCrd_Process(void *Context,
#endif /* PH_FRINFC_FMT_TOPAZ_DISABLED*/
break;
+#ifndef PH_FRINFC_FMT_ISO15693_DISABLED
+ case phHal_eISO15693_PICC :
+ {
+ phFriNfc_ISO15693_FmtProcess (NdefSmtCrdFmt, Status);
+ break;
+ }
+#endif /* #ifndef PH_FRINFC_FMT_ISO15693_DISABLED */
+
#ifdef PHFRINFC_OVRHAL_MOCKUP
case phHal_eOpModesMockup:
/* Remote device is Desfire card */
diff --git a/src/phFriNfc_SmtCrdFmt.h b/src/phFriNfc_SmtCrdFmt.h
index 46b0d0d..4800c41 100644
--- a/src/phFriNfc_SmtCrdFmt.h
+++ b/src/phFriNfc_SmtCrdFmt.h
@@ -246,6 +246,27 @@ typedef struct phFriNfc_Type4_AddInfo
uint8_t UpdMADBlk;
} phFriNfc_MfStd_AddInfo_t;
+
+ /*
+ * \ingroup grp_fri_smart_card_formatting
+ * \brief NFC Smart Card Formatting Component ISO-15693 Additional Information Structure
+ *
+ * This structure is used to specify additional information required to format the ISO-15693 card.
+ * \note
+ * On requirement basis,structure will be filled/modified with other parametes
+ * during the implementation phase.
+ *
+ */
+ typedef struct phFriNfc_ISO15693_AddInfo
+ {
+ /* Stores the current block executed */
+ uint16_t current_block;
+ /* Sequence executed */
+ uint8_t format_seq;
+ /* Maximum data size in the card */
+ uint16_t max_data_size;
+ }phFriNfc_ISO15693_AddInfo_t;
+
/**
* \ingroup grp_fri_smart_card_formatting
*
@@ -264,6 +285,7 @@ typedef struct phFriNfc_sNdefSmtCrdFmt_AddInfo
phFriNfc_Type2_AddInfo_t Type2Info;
phFriNfc_Type4_AddInfo_t Type4Info;
phFriNfc_MfStd_AddInfo_t MfStdInfo;
+ phFriNfc_ISO15693_AddInfo_t s_iso15693_info;
}phFriNfc_sNdefSmtCrdFmt_AddInfo_t;
diff --git a/src/phLibNfc_ndef_raw.c b/src/phLibNfc_ndef_raw.c
index 1da598a..1e5b395 100644
--- a/src/phLibNfc_ndef_raw.c
+++ b/src/phLibNfc_ndef_raw.c
@@ -19,10 +19,10 @@
* Project: NFC FRI 1.1
*
- * $Date: Thu Apr 22 13:59:50 2010 $
- * $Author: ing07385 $
- * $Revision: 1.70 $
- * $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $
+ * $Date: Mon Dec 13 14:14:15 2010 $
+ * $Author: ing02260 $
+ * $Revision: 1.74 $
+ * $Aliases: $
*
*/
@@ -1441,6 +1441,7 @@ phLibNfc_ConvertToReadOnlyNdef (
}
case phHal_eJewel_PICC:
+ case phHal_eISO15693_PICC:
{
// MC: Got the feedback this was #if 0'd because it was resetting the lock bits
// read in check NDEF, and these should not be reset here already.