| /* |
| * |
| * Copyright (C) 2010 NXP Semiconductors |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /*! |
| * \file phFriNfc_ISO15693Map.c |
| * \brief This component encapsulates read/write/check ndef/process functionalities, |
| * for the ISO-15693 Card. |
| * |
| * Project: NFC-FRI |
| * |
| * $Date: $ |
| * $Author: ing02260 $ |
| * $Revision: $ |
| * $Aliases: $ |
| * |
| */ |
| |
| #ifndef PH_FRINFC_MAP_ISO15693_DISABLED |
| |
| #include <phNfcTypes.h> |
| #include <phNfcConfig.h> |
| #include <phNfcInterface.h> |
| #include <phNfcHalTypes.h> |
| #include <phFriNfc.h> |
| #include <phFriNfc_NdefMap.h> |
| #include <phFriNfc_OvrHal.h> |
| #include <phFriNfc_MapTools.h> |
| #include <phFriNfc_ISO15693Map.h> |
| |
| /************************** START DATA STRUCTURE *********************/ |
| |
| typedef enum phFriNfc_eChkNdefSeq |
| { |
| ISO15693_NDEF_TLV_T, |
| ISO15693_NDEF_TLV_L, |
| ISO15693_NDEF_TLV_V, |
| ISO15693_PROP_TLV_L, |
| ISO15693_PROP_TLV_V |
| |
| }phFriNfc_eChkNdefSeq_t; |
| |
| typedef enum phFriNfc_eWrNdefSeq |
| { |
| ISO15693_RD_BEFORE_WR_NDEF_L_0, |
| ISO15693_WRITE_DATA, |
| ISO15693_RD_BEFORE_WR_NDEF_L, |
| ISO15693_WRITE_NDEF_TLV_L |
| |
| }phFriNfc_eWrNdefSeq_t; |
| |
| #ifdef FRINFC_READONLY_NDEF |
| |
| typedef enum phFriNfc_eRONdefSeq |
| { |
| ISO15693_RD_BEFORE_WR_CC, |
| ISO15693_WRITE_CC, |
| ISO15693_LOCK_BLOCK |
| |
| }phFriNfc_eRONdefSeq_t; |
| |
| #endif /* #ifdef FRINFC_READONLY_NDEF */ |
| |
| /************************** END DATA STRUCTURE *********************/ |
| |
| /************************** START MACROS definition *********************/ |
| |
| |
| |
| |
| /* UID bytes to differentiate ICODE cards */ |
| #define ISO15693_UID_BYTE_4 0x04U |
| #define ISO15693_UID_BYTE_5 0x05U |
| #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 |
| SL2S2002 |
| */ |
| #define ISO15693_UIDBYTE_5_VALUE_SLI_X 0x01U |
| /* Card size SL2 ICS20 / SL2S2002 */ |
| #define ISO15693_SL2_S2002_ICS20 112U |
| |
| /* UID value for |
| SL2 ICS53, |
| SL2 ICS54 |
| SL2S5302 |
| */ |
| #define ISO15693_UIDBYTE_5_VALUE_SLI_X_S 0x02U |
| #define ISO15693_UIDBYTE_4_VALUE_SLI_X_S 0x00U |
| #define ISO15693_UIDBYTE_4_VALUE_SLI_X_SHC 0x80U |
| #define ISO15693_UIDBYTE_4_VALUE_SLI_X_SY 0x40U |
| /* SL2 ICS53, SL2 ICS54 and SL2S5302 */ |
| #define ISO15693_SL2_S5302_ICS53_ICS54 160U |
| |
| /* UID value for |
| SL2 ICS50 |
| SL2 ICS51 |
| SL2S5002 |
| */ |
| #define ISO15693_UIDBYTE_5_VALUE_SLI_X_L 0x03U |
| #define ISO15693_UIDBYTE_4_VALUE_SLI_X_L 0x00U |
| #define ISO15693_UIDBYTE_4_VALUE_SLI_X_LHC 0x80U |
| /* SL2 ICS50, SL2 ICS51 and SL2S5002 */ |
| #define ISO15693_SL2_S5002_ICS50_ICS51 32U |
| |
| |
| /* State Machine declaration |
| CHECK NDEF state */ |
| #define ISO15693_CHECK_NDEF 0x01U |
| /* READ NDEF state */ |
| #define ISO15693_READ_NDEF 0x02U |
| /* WRITE NDEF state */ |
| #define ISO15693_WRITE_NDEF 0x03U |
| #ifdef FRINFC_READONLY_NDEF |
| |
| /* READ ONLY NDEF state */ |
| #define ISO15693_READ_ONLY_NDEF 0x04U |
| |
| /* READ ONLY MASK byte for CC */ |
| #define ISO15693_CC_READ_ONLY_MASK 0x03U |
| |
| /* CC READ WRITE index */ |
| #define ISO15693_RW_BTYE_INDEX 0x01U |
| |
| /* LOCK BLOCK command */ |
| #define ISO15693_LOCK_BLOCK_CMD 0x22U |
| |
| #endif /* #ifdef FRINFC_READONLY_NDEF */ |
| |
| /* CC Bytes |
| Magic number */ |
| #define ISO15693_CC_MAGIC_BYTE 0xE1U |
| /* Expected mapping version */ |
| #define ISO15693_MAPPING_VERSION 0x01U |
| /* Major version is in upper 2 bits */ |
| #define ISO15693_MAJOR_VERSION_MASK 0xC0U |
| |
| /* CC indicating tag is capable of multi-block read */ |
| #define ISO15693_CC_USE_MBR 0x01U |
| /* CC indicating tag is capable of inventory page read */ |
| #define ISO15693_CC_USE_IPR 0x02U |
| /* EXTRA byte in the response */ |
| #define ISO15693_EXTRA_RESP_BYTE 0x01U |
| |
| /* Maximum card size multiplication factor */ |
| #define ISO15693_MULT_FACTOR 0x08U |
| /* NIBBLE mask for READ WRITE access */ |
| #define ISO15693_LSB_NIBBLE_MASK 0x0FU |
| #define ISO15693_RD_WR_PERMISSION 0x00U |
| #define ISO15693_RD_ONLY_PERMISSION 0x03U |
| |
| /* READ command identifier */ |
| #define ISO15693_READ_COMMAND 0x20U |
| |
| /* READ multiple command identifier */ |
| #define ISO15693_READ_MULTIPLE_COMMAND 0x23U |
| |
| /* INVENTORY pageread command identifier */ |
| #define ICODE_INVENTORY_PAGEREAD_COMMAND 0xB0U |
| #define INVENTORY_PAGEREAD_FLAGS 0x24U |
| #define NXP_MANUFACTURING_CODE 0x04U |
| |
| /* WRITE command identifier */ |
| #define ISO15693_WRITE_COMMAND 0x21U |
| /* FLAG option */ |
| #define ISO15693_FLAGS 0x20U |
| |
| /* RESPONSE length expected for single block READ */ |
| #define ISO15693_SINGLE_BLK_RD_RESP_LEN 0x04U |
| /* NULL TLV identifier */ |
| #define ISO15693_NULL_TLV_ID 0x00U |
| /* NDEF TLV, TYPE identifier */ |
| #define ISO15693_NDEF_TLV_TYPE_ID 0x03U |
| |
| /* 8 BIT shift */ |
| #define ISO15693_BTYE_SHIFT 0x08U |
| |
| /* Proprietary TLV TYPE identifier */ |
| #define ISO15693_PROP_TLV_ID 0xFDU |
| |
| /* CC SIZE in BYTES */ |
| #define ISO15693_CC_SIZE 0x04U |
| |
| /* To get the remaining size in the card. |
| Inputs are |
| 1. maximum data size |
| 2. block number |
| 3. index of the block number */ |
| #define ISO15693_GET_REMAINING_SIZE(max_data_size, blk, index) \ |
| (max_data_size - ((blk * ISO15693_BYTES_PER_BLOCK) + index)) |
| |
| #define ISO15693_GET_LEN_FIELD_BLOCK_NO(blk, byte_addr, ndef_size) \ |
| (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) > \ |
| (ISO15693_BYTES_PER_BLOCK - 1)) ? (blk + 1) : blk) |
| |
| #define ISO15693_GET_LEN_FIELD_BYTE_NO(blk, byte_addr, ndef_size) \ |
| (((byte_addr + ((ndef_size >= ISO15693_THREE_BYTE_LENGTH_ID) ? 3 : 1)) % \ |
| ISO15693_BYTES_PER_BLOCK)) |
| |
| |
| |
| /************************** END MACROS definition *********************/ |
| |
| /************************** START static functions declaration *********************/ |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessReadOnly ( |
| phFriNfc_NdefMap_t *psNdefMap); |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessWriteNdef ( |
| phFriNfc_NdefMap_t *psNdefMap); |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessReadNdef ( |
| phFriNfc_NdefMap_t *psNdefMap); |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessCheckNdef ( |
| phFriNfc_NdefMap_t *psNdefMap); |
| |
| static |
| void |
| phFriNfc_ISO15693_H_Complete ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| NFCSTATUS Status); |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ReadWrite ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| uint8_t command, |
| uint8_t *p_data, |
| uint8_t data_length); |
| |
| static |
| NFCSTATUS |
| phFriNfc_ReadRemainingInMultiple ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| uint32_t startBlock); |
| |
| /************************** END static functions declaration *********************/ |
| |
| /************************** START static functions definition *********************/ |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessWriteNdef ( |
| phFriNfc_NdefMap_t *psNdefMap) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| phFriNfc_eWrNdefSeq_t e_wr_ndef_seq = (phFriNfc_eWrNdefSeq_t) |
| psNdefMap->ISO15693Container.ndef_seq; |
| uint8_t *p_recv_buf = NULL; |
| uint8_t recv_length = 0; |
| uint8_t write_flag = FALSE; |
| uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0}; |
| uint8_t remaining_size = 0; |
| |
| switch (e_wr_ndef_seq) |
| { |
| case ISO15693_RD_BEFORE_WR_NDEF_L_0: |
| { |
| /* 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); |
| |
| byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO( |
| ps_iso_15693_con->ndef_tlv_type_blk, |
| ps_iso_15693_con->ndef_tlv_type_byte, |
| psNdefMap->ApduBufferSize); |
| |
| /* Writing length field to 0, 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) |
| < remaining_size) |
| { |
| remaining_size = (uint8_t)(psNdefMap->ApduBufferSize - |
| psNdefMap->ApduBuffIndex); |
| } |
| |
| /* Go to next byte to fill the write buffer */ |
| (void)memcpy ((void *)(a_write_buf + byte_index), |
| (void *)(psNdefMap->ApduBuffer + |
| psNdefMap->ApduBuffIndex), remaining_size); |
| |
| /* 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) */ |
| else |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_RECEIVE_LENGTH); |
| } |
| break; |
| } /* case ISO15693_RD_BEFORE_WR_NDEF_L_0: */ |
| |
| case ISO15693_RD_BEFORE_WR_NDEF_L: |
| { |
| p_recv_buf = (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE); |
| recv_length = (uint8_t)(*psNdefMap->SendRecvLength - |
| ISO15693_EXTRA_RESP_BYTE); |
| |
| if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) |
| { |
| uint8_t byte_index = 0; |
| |
| (void)memcpy ((void *)a_write_buf, (void *)p_recv_buf, |
| recv_length); |
| |
| byte_index = ISO15693_GET_LEN_FIELD_BYTE_NO( |
| ps_iso_15693_con->ndef_tlv_type_blk, |
| ps_iso_15693_con->ndef_tlv_type_byte, |
| psNdefMap->ApduBuffIndex); |
| |
| *(a_write_buf + byte_index) = (uint8_t)psNdefMap->ApduBuffIndex; |
| e_wr_ndef_seq = ISO15693_WRITE_NDEF_TLV_L; |
| write_flag = TRUE; |
| } |
| else |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_RECEIVE_LENGTH); |
| } |
| break; |
| } |
| |
| case ISO15693_WRITE_DATA: |
| { |
| if ((psNdefMap->ApduBufferSize == psNdefMap->ApduBuffIndex) |
| || (ps_iso_15693_con->current_block == |
| (ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK))) |
| { |
| ps_iso_15693_con->current_block = |
| ISO15693_GET_LEN_FIELD_BLOCK_NO( |
| ps_iso_15693_con->ndef_tlv_type_blk, |
| ps_iso_15693_con->ndef_tlv_type_byte, |
| psNdefMap->ApduBuffIndex); |
| e_wr_ndef_seq = ISO15693_RD_BEFORE_WR_NDEF_L; |
| } |
| else |
| { |
| remaining_size = ISO15693_BYTES_PER_BLOCK; |
| |
| ps_iso_15693_con->current_block = (uint16_t) |
| (ps_iso_15693_con->current_block + 1); |
| |
| if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex) |
| < remaining_size) |
| { |
| remaining_size = (uint8_t)(psNdefMap->ApduBufferSize - |
| psNdefMap->ApduBuffIndex); |
| } |
| |
| (void)memcpy ((void *)a_write_buf, (void *) |
| (psNdefMap->ApduBuffer + |
| psNdefMap->ApduBuffIndex), remaining_size); |
| |
| psNdefMap->ApduBuffIndex = (uint8_t)(psNdefMap->ApduBuffIndex + |
| remaining_size); |
| write_flag = TRUE; |
| } |
| break; |
| } /* case ISO15693_WRITE_DATA: */ |
| |
| case ISO15693_WRITE_NDEF_TLV_L: |
| { |
| *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex; |
| ps_iso_15693_con->actual_ndef_size = psNdefMap->ApduBuffIndex; |
| break; |
| } |
| |
| default: |
| { |
| break; |
| } |
| } /* switch (e_wr_ndef_seq) */ |
| |
| if (((0 == psNdefMap->ApduBuffIndex) |
| || (*psNdefMap->WrNdefPacketLength != psNdefMap->ApduBuffIndex)) |
| && (!result)) |
| { |
| if (FALSE == write_flag) |
| { |
| result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, |
| ISO15693_READ_COMMAND, NULL, 0); |
| } |
| else |
| { |
| result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, |
| ISO15693_WRITE_COMMAND, |
| a_write_buf, sizeof (a_write_buf)); |
| } |
| } |
| |
| psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_wr_ndef_seq; |
| return result; |
| } |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ReadWrite ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| uint8_t command, |
| uint8_t *p_data, |
| uint8_t data_length) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| uint8_t send_index = 0; |
| |
| /* set the data for additional data exchange*/ |
| psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; |
| psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; |
| psNdefMap->psDepAdditionalInfo.NAD = 0; |
| |
| psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process; |
| psNdefMap->MapCompletionInfo.Context = psNdefMap; |
| |
| *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength; |
| |
| psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd; |
| |
| *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)ISO15693_FLAGS; |
| send_index = (uint8_t)(send_index + 1); |
| |
| *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command; |
| send_index = (uint8_t)(send_index + 1); |
| |
| (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), |
| (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid, |
| psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength); |
| send_index = (uint8_t)(send_index + |
| psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength); |
| |
| *(psNdefMap->SendRecvBuf + send_index) = (uint8_t) |
| psNdefMap->ISO15693Container.current_block; |
| send_index = (uint8_t)(send_index + 1); |
| |
| if ((ISO15693_WRITE_COMMAND == command) || |
| (ISO15693_READ_MULTIPLE_COMMAND == command)) |
| { |
| (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), |
| (void *)p_data, data_length); |
| send_index = (uint8_t)(send_index + data_length); |
| } |
| |
| psNdefMap->SendLength = send_index; |
| result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice, |
| &psNdefMap->MapCompletionInfo, |
| psNdefMap->psRemoteDevInfo, |
| psNdefMap->Cmd, |
| &psNdefMap->psDepAdditionalInfo, |
| psNdefMap->SendRecvBuf, |
| psNdefMap->SendLength, |
| psNdefMap->SendRecvBuf, |
| psNdefMap->SendRecvLength); |
| |
| return result; |
| } |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_Inventory_Page_Read ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| uint8_t command, |
| uint8_t page, |
| uint8_t numPages) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| uint8_t send_index = 0; |
| |
| /* set the data for additional data exchange*/ |
| psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; |
| psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; |
| psNdefMap->psDepAdditionalInfo.NAD = 0; |
| |
| psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_ISO15693_Process; |
| psNdefMap->MapCompletionInfo.Context = psNdefMap; |
| |
| *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength; |
| |
| psNdefMap->Cmd.Iso15693Cmd = phHal_eIso15693_Cmd; |
| |
| *(psNdefMap->SendRecvBuf + send_index) = INVENTORY_PAGEREAD_FLAGS; |
| send_index = (uint8_t)(send_index + 1); |
| |
| *(psNdefMap->SendRecvBuf + send_index) = (uint8_t)command; |
| send_index = (uint8_t)(send_index + 1); |
| |
| *(psNdefMap->SendRecvBuf + send_index) = NXP_MANUFACTURING_CODE; |
| send_index = (uint8_t)(send_index + 1); |
| |
| *(psNdefMap->SendRecvBuf + send_index) = 0x40; |
| send_index = (uint8_t)(send_index + 1); |
| |
| (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), |
| (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid, |
| psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength); |
| send_index = (uint8_t)(send_index + |
| psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength); |
| |
| *(psNdefMap->SendRecvBuf + send_index) = (uint8_t) |
| page; |
| send_index = (uint8_t)(send_index + 1); |
| |
| *(psNdefMap->SendRecvBuf + send_index) = (uint8_t) |
| numPages; |
| send_index = (uint8_t)(send_index + 1); |
| |
| psNdefMap->SendLength = send_index; |
| |
| result = phFriNfc_OvrHal_Transceive(psNdefMap->LowerDevice, |
| &psNdefMap->MapCompletionInfo, |
| psNdefMap->psRemoteDevInfo, |
| psNdefMap->Cmd, |
| &psNdefMap->psDepAdditionalInfo, |
| psNdefMap->SendRecvBuf, |
| psNdefMap->SendLength, |
| psNdefMap->SendRecvBuf, |
| psNdefMap->SendRecvLength); |
| |
| return result; |
| } |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_Reformat_Pageread_Buffer ( |
| uint8_t *p_recv_buf, |
| uint8_t recv_length, |
| uint8_t *p_dst_buf, |
| uint8_t dst_length) |
| { |
| // Inventory page reads return an extra security byte per page |
| // So we need to reformat the returned buffer in memory |
| uint32_t i = 0; |
| uint32_t reformatted_index = 0; |
| while (i < recv_length) { |
| // Going for another page of 16 bytes, check for space in dst buffer |
| if (reformatted_index + 16 > dst_length) { |
| break; |
| } |
| if (p_recv_buf[i] == 0x0F) { |
| // Security, insert 16 0 bytes |
| memset(&(p_dst_buf[reformatted_index]), 0, 16); |
| reformatted_index += 16; |
| i++; |
| } else { |
| // Skip security byte |
| i++; |
| if (i + 16 <= recv_length) { |
| memcpy(&(p_dst_buf[reformatted_index]), &(p_recv_buf[i]), 16); |
| reformatted_index += 16; |
| } else { |
| break; |
| } |
| i+=16; |
| } |
| } |
| return reformatted_index; |
| } |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessReadNdef ( |
| phFriNfc_NdefMap_t *psNdefMap) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| uint16_t remaining_data_size = 0; |
| uint8_t *p_recv_buf = |
| (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE); |
| uint8_t recv_length = (uint8_t) |
| (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE); |
| |
| uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size); |
| |
| if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR) |
| { |
| uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length, |
| reformatted_buf, ps_iso_15693_con->max_data_size); |
| p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK); |
| recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK); |
| } |
| if (ps_iso_15693_con->store_length) |
| { |
| /* Continue Offset option selected |
| So stored data already existing, |
| copy the information to the user buffer |
| */ |
| if (ps_iso_15693_con->store_length |
| <= (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)) |
| { |
| /* Stored data length is less than or equal |
| to the user expected size */ |
| (void)memcpy ((void *)(psNdefMap->ApduBuffer + |
| psNdefMap->ApduBuffIndex), |
| (void *)ps_iso_15693_con->store_read_data, |
| ps_iso_15693_con->store_length); |
| |
| psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + |
| ps_iso_15693_con->store_length); |
| |
| remaining_data_size = ps_iso_15693_con->store_length; |
| |
| ps_iso_15693_con->store_length = 0; |
| } |
| else |
| { |
| /* stored length is more than the user expected size */ |
| remaining_data_size = (uint16_t)(ps_iso_15693_con->store_length - |
| (psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex)); |
| |
| (void)memcpy ((void *)(psNdefMap->ApduBuffer + |
| psNdefMap->ApduBuffIndex), |
| (void *)ps_iso_15693_con->store_read_data, |
| remaining_data_size); |
| |
| /* 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), |
| (ps_iso_15693_con->store_length - remaining_data_size)); |
| |
| 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) |
| == ps_iso_15693_con->current_block) |
| { |
| /* Read from the beginning option selected, |
| BYTE number may start from the middle */ |
| byte_index = (uint8_t)ISO15693_GET_VALUE_FIELD_BYTE_NO( |
| ps_iso_15693_con->ndef_tlv_type_blk, |
| ps_iso_15693_con->ndef_tlv_type_byte, |
| ps_iso_15693_con->actual_ndef_size); |
| } |
| |
| if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex) |
| < remaining_data_size) |
| { |
| 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)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))); |
| |
| ps_iso_15693_con->store_length = (uint8_t) |
| (recv_length - (byte_index + |
| remaining_data_size)); |
| } |
| } |
| } |
| 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); |
| |
| } /* else part of if (ps_iso_15693_con->store_length) */ |
| |
| /* Remaining size is decremented */ |
| ps_iso_15693_con->remaining_size_to_read = (uint8_t) |
| (ps_iso_15693_con->remaining_size_to_read - |
| remaining_data_size); |
| |
| if ((psNdefMap->ApduBuffIndex != psNdefMap->ApduBufferSize) |
| && (0 != ps_iso_15693_con->remaining_size_to_read)) |
| { |
| ps_iso_15693_con->current_block = (uint16_t) |
| (ps_iso_15693_con->current_block + 1); |
| /* READ again */ |
| if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) || |
| (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) { |
| result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block); |
| } |
| else { |
| result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND, |
| NULL, 0); |
| } |
| } |
| else |
| { |
| /* Read completed, 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) { |
| phOsalNfc_FreeMemory(reformatted_buf); |
| } |
| return result; |
| } |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_CheckCCBytes ( |
| phFriNfc_NdefMap_t *psNdefMap) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| uint8_t recv_index = 0; |
| uint8_t *p_recv_buf = (psNdefMap->SendRecvBuf + 1); |
| |
| /* 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; |
| } |
| |
| default: |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_NO_NDEF_SUPPORT); |
| break; |
| } |
| } |
| recv_index = (uint8_t)(recv_index + 1); |
| |
| if (!result) |
| { |
| /* Update MAX SIZE */ |
| ps_iso_15693_con->max_data_size = (uint16_t) |
| (*(p_recv_buf + recv_index) * |
| ISO15693_MULT_FACTOR); |
| recv_index = (uint8_t)(recv_index + 1); |
| ps_iso_15693_con->read_capabilities = (*(p_recv_buf + recv_index)); |
| |
| |
| } |
| } |
| else |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| } |
| else |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| return result; |
| } |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessCheckNdef ( |
| phFriNfc_NdefMap_t *psNdefMap) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| phFriNfc_eChkNdefSeq_t e_chk_ndef_seq = (phFriNfc_eChkNdefSeq_t) |
| psNdefMap->ISO15693Container.ndef_seq; |
| |
| uint8_t *p_recv_buf = |
| (psNdefMap->SendRecvBuf + ISO15693_EXTRA_RESP_BYTE); |
| uint8_t recv_length = (uint8_t) |
| (*psNdefMap->SendRecvLength - ISO15693_EXTRA_RESP_BYTE); |
| uint8_t parse_index = 0; |
| static uint16_t prop_ndef_index = 0; |
| uint8_t *reformatted_buf = (uint8_t*) phOsalNfc_GetMemory(ps_iso_15693_con->max_data_size); |
| |
| if (0 == ps_iso_15693_con->current_block) |
| { |
| /* Check CC byte */ |
| result = phFriNfc_ISO15693_H_CheckCCBytes (psNdefMap); |
| parse_index = (uint8_t)(parse_index + recv_length); |
| } |
| else if (1 == ps_iso_15693_con->current_block && |
| (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) |
| { |
| |
| uint8_t reformatted_size = phFriNfc_ISO15693_Reformat_Pageread_Buffer(p_recv_buf, recv_length, |
| reformatted_buf, ps_iso_15693_con->max_data_size); |
| // Skip initial CC bytes |
| p_recv_buf = reformatted_buf + (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK); |
| recv_length = reformatted_size - (ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK); |
| } |
| else |
| { |
| /* Propreitary TLVs VALUE can end in between a block, |
| so when that block is read, 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; |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_T; |
| } |
| } |
| |
| while ((parse_index < recv_length) |
| && (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; |
| |
| break; |
| } |
| |
| case ISO15693_NULL_TLV_ID: |
| { |
| /* Dont do any thing, go to next byte */ |
| break; |
| } |
| |
| case ISO15693_PROP_TLV_ID: |
| { |
| /* Move the sequence to find the length |
| of the proprietary TLV */ |
| e_chk_ndef_seq = ISO15693_PROP_TLV_L; |
| break; |
| } |
| |
| default: |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_NO_NDEF_SUPPORT); |
| break; |
| } |
| } /* switch (*(p_recv_buf + parse_index)) */ |
| break; |
| } |
| |
| case ISO15693_PROP_TLV_L: |
| { |
| /* 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 |
| { |
| 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; |
| prop_ndef_index = 0; |
| } |
| } |
| break; |
| } |
| |
| 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); |
| prop_ndef_index = (uint8_t)(prop_ndef_index + 1); |
| break; |
| } |
| |
| 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)); |
| |
| e_chk_ndef_seq = ISO15693_PROP_TLV_V; |
| prop_ndef_index = 0; |
| break; |
| } |
| |
| default: |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_DEVICE_REQUEST); |
| break; |
| } |
| } /* switch (prop_ndef_index) */ |
| |
| if ((ISO15693_PROP_TLV_V == e_chk_ndef_seq) |
| && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size, |
| ps_iso_15693_con->current_block, parse_index) |
| <= ps_iso_15693_con->actual_ndef_size)) |
| { |
| /* Check for the length field value has not exceeded the card size, |
| if size is exceeded or then return error */ |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_T; |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| else |
| { |
| uint16_t prop_byte_addr = 0; |
| |
| /* skip the proprietary TLVs value field */ |
| prop_byte_addr = (uint16_t) |
| ((ps_iso_15693_con->current_block * ISO15693_BYTES_PER_BLOCK) + |
| parse_index + ps_iso_15693_con->actual_ndef_size); |
| |
| ps_iso_15693_con->ndef_tlv_type_byte = (uint8_t)(prop_byte_addr % |
| ISO15693_BYTES_PER_BLOCK); |
| ps_iso_15693_con->ndef_tlv_type_blk = (uint16_t)(prop_byte_addr / |
| ISO15693_BYTES_PER_BLOCK); |
| if (parse_index + ps_iso_15693_con->actual_ndef_size >= |
| recv_length) |
| { |
| parse_index = (uint8_t)recv_length; |
| } |
| else |
| { |
| parse_index = (uint8_t)(parse_index + |
| ps_iso_15693_con->actual_ndef_size); |
| } |
| |
| } |
| break; |
| } /* case ISO15693_PROP_TLV_L: */ |
| |
| case ISO15693_PROP_TLV_V: |
| { |
| uint8_t remaining_length = (uint8_t)(recv_length - |
| parse_index); |
| |
| if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index) |
| > remaining_length) |
| { |
| parse_index = (uint8_t)(parse_index + remaining_length); |
| prop_ndef_index = (uint8_t)(prop_ndef_index + remaining_length); |
| } |
| else if ((ps_iso_15693_con->actual_ndef_size - prop_ndef_index) |
| == remaining_length) |
| { |
| parse_index = (uint8_t)(parse_index + remaining_length); |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_T; |
| prop_ndef_index = 0; |
| } |
| else |
| { |
| parse_index = (uint8_t)(parse_index + |
| (ps_iso_15693_con->actual_ndef_size - |
| prop_ndef_index)); |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_T; |
| prop_ndef_index = 0; |
| } |
| break; |
| } /* case ISO15693_PROP_TLV_V: */ |
| |
| case ISO15693_NDEF_TLV_L: |
| { |
| /* 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; |
| } |
| else |
| { |
| prop_ndef_index = (uint8_t)(prop_ndef_index + 1); |
| |
| 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); |
| prop_ndef_index = 0; |
| } |
| 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; |
| } |
| } |
| break; |
| } |
| |
| 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); |
| prop_ndef_index = (uint8_t)(prop_ndef_index + 1); |
| break; |
| } |
| |
| 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)); |
| |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_V; |
| prop_ndef_index = 0; |
| break; |
| } |
| |
| default: |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_DEVICE_REQUEST); |
| break; |
| } |
| } /* switch (prop_ndef_index) */ |
| |
| if ((ISO15693_NDEF_TLV_V == e_chk_ndef_seq) |
| && (ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size, |
| /* parse_index + 1 is done because the data starts from the next index. |
| "MOD" operation is used to know that parse_index > |
| ISO15693_BYTES_PER_BLOCK, then block shall be incremented |
| */ |
| (((parse_index + 1) % ISO15693_BYTES_PER_BLOCK) ? |
| ps_iso_15693_con->current_block : |
| ps_iso_15693_con->current_block + 1), ((parse_index + 1) % |
| ISO15693_BYTES_PER_BLOCK)) |
| < ps_iso_15693_con->actual_ndef_size)) |
| { |
| /* Check for the length field value has not exceeded the card size */ |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_T; |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| else |
| { |
| psNdefMap->CardState = (uint8_t) |
| ((PH_NDEFMAP_CARD_STATE_READ_ONLY |
| == psNdefMap->CardState) ? |
| PH_NDEFMAP_CARD_STATE_READ_ONLY : |
| ((ps_iso_15693_con->actual_ndef_size) ? |
| PH_NDEFMAP_CARD_STATE_READ_WRITE : |
| PH_NDEFMAP_CARD_STATE_INITIALIZED)); |
| } |
| break; |
| } /* case ISO15693_NDEF_TLV_L: */ |
| |
| case ISO15693_NDEF_TLV_V: |
| { |
| break; |
| } |
| |
| default: |
| { |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_DEVICE_REQUEST); |
| break; |
| } |
| } /* switch (e_chk_ndef_seq) */ |
| parse_index = (uint8_t)(parse_index + 1); |
| } /* while ((parse_index < recv_length) |
| && (NFCSTATUS_SUCCESS == result) |
| && (ISO15693_NDEF_TLV_V != e_chk_ndef_seq)) */ |
| |
| if (result) |
| { |
| /* Error returned while parsing, so STOP read */ |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_T; |
| prop_ndef_index = 0; |
| } |
| else if (ISO15693_NDEF_TLV_V != e_chk_ndef_seq) |
| { |
| /* READ again */ |
| if (ISO15693_PROP_TLV_V != e_chk_ndef_seq) |
| { |
| ps_iso_15693_con->current_block = (uint16_t) |
| (ps_iso_15693_con->current_block + 1); |
| } |
| else |
| { |
| /* Proprietary TLV detected, so skip the proprietary blocks */ |
| ps_iso_15693_con->current_block = ps_iso_15693_con->ndef_tlv_type_blk; |
| } |
| |
| uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size, |
| ps_iso_15693_con->current_block, 0); |
| if (remaining_size > 0) |
| { |
| if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) || |
| (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) { |
| result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block); |
| } else { |
| result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND, |
| NULL, 0); |
| } |
| } |
| else |
| { |
| /* 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 */ |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_NO_NDEF_SUPPORT); |
| } |
| |
| } |
| else |
| { |
| /* Successful read with proper NDEF information updated */ |
| prop_ndef_index = 0; |
| e_chk_ndef_seq = ISO15693_NDEF_TLV_T; |
| psNdefMap->CardType = (uint8_t)PH_FRINFC_NDEFMAP_ISO15693_CARD; |
| } |
| |
| psNdefMap->ISO15693Container.ndef_seq = (uint8_t)e_chk_ndef_seq; |
| |
| if (reformatted_buf != NULL) { |
| phOsalNfc_FreeMemory(reformatted_buf); |
| } |
| return result; |
| } |
| |
| static |
| void |
| phFriNfc_ISO15693_H_Complete ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| NFCSTATUS Status) |
| { |
| /* set the state back to the RESET_INIT state*/ |
| psNdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; |
| |
| /* set the completion routine*/ |
| psNdefMap->CompletionRoutine[psNdefMap->ISO15693Container.cr_index]. |
| CompletionRoutine (psNdefMap->CompletionRoutine->Context, Status); |
| } |
| |
| #ifdef FRINFC_READONLY_NDEF |
| |
| static |
| NFCSTATUS |
| phFriNfc_ISO15693_H_ProcessReadOnly ( |
| phFriNfc_NdefMap_t *psNdefMap) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| phFriNfc_eRONdefSeq_t e_ro_ndef_seq = (phFriNfc_eRONdefSeq_t) |
| ps_iso_15693_con->ndef_seq; |
| uint8_t *p_recv_buf = (psNdefMap->SendRecvBuf + |
| ISO15693_EXTRA_RESP_BYTE); |
| uint8_t recv_length = (uint8_t)(*psNdefMap->SendRecvLength - |
| ISO15693_EXTRA_RESP_BYTE); |
| uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0}; |
| |
| switch (e_ro_ndef_seq) |
| { |
| case ISO15693_RD_BEFORE_WR_CC: |
| { |
| if (ISO15693_SINGLE_BLK_RD_RESP_LEN == recv_length) |
| { |
| 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_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; |
| } |
| |
| case ISO15693_LOCK_BLOCK: |
| { |
| if (ps_iso_15693_con->current_block == |
| ((ps_iso_15693_con->max_data_size / ISO15693_BYTES_PER_BLOCK) - |
| 1)) |
| { |
| /* 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); |
| } |
| break; |
| } |
| |
| default: |
| { |
| break; |
| } |
| } |
| |
| ps_iso_15693_con->ndef_seq = (uint8_t)e_ro_ndef_seq; |
| return result; |
| } |
| |
| #endif /* #ifdef FRINFC_READONLY_NDEF */ |
| /************************** END static functions definition *********************/ |
| |
| /************************** START external functions *********************/ |
| |
| NFCSTATUS |
| phFriNfc_ISO15693_ChkNdef ( |
| phFriNfc_NdefMap_t *psNdefMap) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phHal_sIso15693Info_t *ps_iso_15693_info = |
| &(psNdefMap->psRemoteDevInfo->RemoteDevInfo.Iso15693_Info); |
| |
| /* Update the previous operation with current operation. |
| This becomes the previous operation after this execution */ |
| psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; |
| /* Update the CR index to know from which operation completion |
| routine has to be called */ |
| psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_CHK_NDEF; |
| /* State update */ |
| psNdefMap->State = ISO15693_CHECK_NDEF; |
| /* Reset the NDEF sequence */ |
| psNdefMap->ISO15693Container.ndef_seq = 0; |
| psNdefMap->ISO15693Container.current_block = 0; |
| psNdefMap->ISO15693Container.actual_ndef_size = 0; |
| psNdefMap->ISO15693Container.ndef_tlv_type_blk = 0; |
| psNdefMap->ISO15693Container.ndef_tlv_type_byte = 0; |
| psNdefMap->ISO15693Container.store_length = 0; |
| psNdefMap->ISO15693Container.remaining_size_to_read = 0; |
| psNdefMap->ISO15693Container.read_capabilities = 0; |
| |
| 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; |
| } |
| |
| 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; |
| } |
| |
| default: |
| { |
| /* Tag not supported */ |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_DEVICE_REQUEST); |
| break; |
| } |
| } |
| break; |
| } |
| |
| 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; |
| } |
| |
| default: |
| { |
| /* Tag not supported */ |
| result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, |
| NFCSTATUS_INVALID_DEVICE_REQUEST); |
| break; |
| } |
| } |
| break; |
| } |
| |
| 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); |
| } |
| |
| |
| return result; |
| } |
| |
| NFCSTATUS |
| phFriNfc_ISO15693_RdNdef ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| uint8_t *pPacketData, |
| uint32_t *pPacketDataLength, |
| uint8_t Offset) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| |
| /* Update the previous operation with current operation. |
| This becomes the previous operation after this execution */ |
| psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; |
| /* Update the CR index to know from which operation completion |
| routine has to be called */ |
| psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_RD_NDEF; |
| /* State update */ |
| psNdefMap->State = ISO15693_READ_NDEF; |
| /* Copy user buffer to the context */ |
| psNdefMap->ApduBuffer = pPacketData; |
| /* Copy user length to the context */ |
| psNdefMap->ApduBufferSize = *pPacketDataLength; |
| /* Update the user memory size to a context variable */ |
| psNdefMap->NumOfBytesRead = pPacketDataLength; |
| /* Number of bytes read from the card is zero. |
| This variable returns the number of bytes read |
| from the card. */ |
| *psNdefMap->NumOfBytesRead = 0; |
| /* Index to know the length read */ |
| psNdefMap->ApduBuffIndex = 0; |
| /* Store the offset in the context */ |
| psNdefMap->Offset = Offset; |
| |
| if ((!ps_iso_15693_con->remaining_size_to_read) |
| && (!psNdefMap->Offset)) |
| { |
| /* 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 = |
| ISO15693_GET_VALUE_FIELD_BLOCK_NO( |
| ps_iso_15693_con->ndef_tlv_type_blk, |
| ps_iso_15693_con->ndef_tlv_type_byte, |
| ps_iso_15693_con->actual_ndef_size); |
| |
| // Check capabilities |
| if ((ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) || |
| (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR)) { |
| result = phFriNfc_ReadRemainingInMultiple(psNdefMap, ps_iso_15693_con->current_block); |
| } else { |
| result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_COMMAND, |
| NULL, 0); |
| } |
| } |
| else |
| { |
| /* 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); |
| } |
| } |
| |
| return result; |
| } |
| |
| static |
| NFCSTATUS |
| phFriNfc_ReadRemainingInMultiple ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| uint32_t startBlock) |
| { |
| NFCSTATUS result = NFCSTATUS_FAILED; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = &(psNdefMap->ISO15693Container); |
| |
| uint32_t remaining_size = ISO15693_GET_REMAINING_SIZE(ps_iso_15693_con->max_data_size, |
| startBlock, 0); |
| // Check capabilities |
| if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_MBR) { |
| // Multi-page read command |
| uint8_t mbread[1]; |
| mbread[0] = (remaining_size / ISO15693_BYTES_PER_BLOCK) - 1; |
| result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, ISO15693_READ_MULTIPLE_COMMAND, |
| mbread, 1); |
| } else if (ps_iso_15693_con->read_capabilities & ISO15693_CC_USE_IPR) { |
| uint32_t page = 0; |
| uint32_t pagesToRead = (remaining_size / ISO15693_BYTES_PER_BLOCK / 4) - 1; |
| if ((remaining_size % (ISO15693_BYTES_PER_BLOCK * ISO15693_BLOCKS_PER_PAGE)) != 0) { |
| pagesToRead++; |
| } |
| result = phFriNfc_ISO15693_H_Inventory_Page_Read (psNdefMap, ICODE_INVENTORY_PAGEREAD_COMMAND, |
| page, pagesToRead); |
| // Inventory |
| } else { |
| result = NFCSTATUS_FAILED; |
| } |
| return result; |
| } |
| |
| NFCSTATUS |
| phFriNfc_ISO15693_WrNdef ( |
| phFriNfc_NdefMap_t *psNdefMap, |
| uint8_t *pPacketData, |
| uint32_t *pPacketDataLength, |
| uint8_t Offset) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| uint8_t a_write_buf[ISO15693_BYTES_PER_BLOCK] = {0}; |
| |
| /* Update the previous operation with current operation. |
| This becomes the previous operation after this execution */ |
| psNdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; |
| /* Update the CR index to know from which operation completion |
| routine has to be called */ |
| psNdefMap->ISO15693Container.cr_index = PH_FRINFC_NDEFMAP_CR_WR_NDEF; |
| /* State update */ |
| psNdefMap->State = ISO15693_WRITE_NDEF; |
| /* Copy user buffer to the context */ |
| psNdefMap->ApduBuffer = pPacketData; |
| /* Copy user length to the context */ |
| psNdefMap->ApduBufferSize = *pPacketDataLength; |
| /* Update the user memory size to a context variable */ |
| psNdefMap->NumOfBytesRead = pPacketDataLength; |
| /* Number of bytes written to the card is zero. |
| This variable returns the number of bytes written |
| to the card. */ |
| *psNdefMap->WrNdefPacketLength = 0; |
| /* Index to know the length read */ |
| psNdefMap->ApduBuffIndex = 0; |
| /* Store the offset in the context */ |
| psNdefMap->Offset = Offset; |
| |
| /* 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, |
| ps_iso_15693_con->ndef_tlv_type_byte, |
| *pPacketDataLength); |
| |
| if (ISO15693_GET_LEN_FIELD_BYTE_NO( |
| ps_iso_15693_con->ndef_tlv_type_blk, |
| ps_iso_15693_con->ndef_tlv_type_byte, |
| *pPacketDataLength)) |
| { |
| /* 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 */ |
| *a_write_buf = 0x00; |
| |
| /* Write remaining data */ |
| (void)memcpy ((void *)(a_write_buf + 1), |
| (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)); |
| } |
| |
| return result; |
| } |
| |
| #ifdef FRINFC_READONLY_NDEF |
| |
| NFCSTATUS |
| phFriNfc_ISO15693_ConvertToReadOnly ( |
| phFriNfc_NdefMap_t *psNdefMap) |
| { |
| NFCSTATUS result = NFCSTATUS_SUCCESS; |
| phFriNfc_ISO15693Cont_t *ps_iso_15693_con = |
| &(psNdefMap->ISO15693Container); |
| |
| psNdefMap->State = ISO15693_READ_ONLY_NDEF; |
| /* READ CC bytes */ |
| ps_iso_15693_con->ndef_seq = (uint8_t)ISO15693_RD_BEFORE_WR_CC; |
| ps_iso_15693_con->current_block = 0; |
| |
| result = phFriNfc_ISO15693_H_ReadWrite (psNdefMap, |
| ISO15693_READ_COMMAND, NULL, 0); |
| |
| return result; |
| } |
| |
| #endif /* #ifdef FRINFC_READONLY_NDEF */ |
| |
| |
| void |
| phFriNfc_ISO15693_Process ( |
| void *pContext, |
| NFCSTATUS Status) |
| { |
| phFriNfc_NdefMap_t *psNdefMap = |
| (phFriNfc_NdefMap_t *)pContext; |
| |
| if ((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER)) |
| { |
| switch (psNdefMap->State) |
| { |
| case ISO15693_CHECK_NDEF: |
| { |
| /* 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; |
| } |
| |
| #ifdef FRINFC_READONLY_NDEF |
| case ISO15693_READ_ONLY_NDEF: |
| { |
| /* State = RAD ONLY NDEF in progress */ |
| Status = phFriNfc_ISO15693_H_ProcessReadOnly (psNdefMap); |
| break; |
| } |
| #endif /* #ifdef FRINFC_READONLY_NDEF */ |
| |
| default: |
| { |
| break; |
| } |
| } |
| } |
| |
| /* Call for the Completion Routine*/ |
| if (NFCSTATUS_PENDING != Status) |
| { |
| phFriNfc_ISO15693_H_Complete(psNdefMap, Status); |
| } |
| } |
| |
| /************************** END external functions *********************/ |
| |
| #endif /* #ifndef PH_FRINFC_MAP_ISO15693_DISABLED */ |