From 4f3ef022906e5d3b763fbcfe81e3f5cd53976ab5 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Thu, 20 Jan 2011 01:27:17 +0100 Subject: Support formatting / makeReadOnly() of NDEF on ICODE. Change-Id: I2a7a185ead5de8f2b165c81dcc8ab8fb46c1ddc0 --- Android.mk | 1 + src/phFriNfc.h | 1 + src/phFriNfc_ISO15693Format.c | 594 ++++++++++++++++++++++++++++++++++++++++++ src/phFriNfc_ISO15693Format.h | 116 +++++++++ src/phFriNfc_ISO15693Map.c | 215 ++++++++++++--- src/phFriNfc_ISO15693Map.h | 2 +- src/phFriNfc_NdefMap.c | 20 +- src/phFriNfc_SmtCrdFmt.c | 30 ++- src/phFriNfc_SmtCrdFmt.h | 22 ++ src/phLibNfc_ndef_raw.c | 9 +- 10 files changed, 958 insertions(+), 52 deletions(-) create mode 100644 src/phFriNfc_ISO15693Format.c create mode 100644 src/phFriNfc_ISO15693Format.h diff --git a/Android.mk b/Android.mk index 5dc9682..0557a87 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 +#include +#include +#include + + +/****************************** 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 #include #include +#ifndef PH_FRINFC_FMT_ISO15693_DISABLED + #include +#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. -- cgit v1.1