2 * Copyright (C) 2010 NXP Semiconductors
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * \file phFriNfc_TopazDynamicMap.c
19 * \brief NFC Ndef Mapping For Remote Devices.
23 * $Date: Wed Oct 27 10:21:29 2010 $
32 #include <phFriNfc_NdefMap.h>
33 #include <phFriNfc_TopazMap.h>
34 #include <phFriNfc_MapTools.h>
35 #include <phFriNfc_OvrHal.h>
37 #if !(defined(PH_FRINFC_MAP_TOPAZ_DISABLED ) || defined (PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED ))
39 /*! \ingroup grp_file_attributes
42 * File: \ref phFriNfcNdefMap.c
46 #define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.41 $"
47 #define PHFRINFCTOPAZMAP_FILEALIASES "$Aliases: $"
50 * \name Topaz Mapping - Helper data structures and macros
55 /********************************** Start of data structures *********************************/
56 #ifdef FRINFC_READONLY_NDEF
58 #define DYN_CC_BLOCK_NUMBER (0x01U)
59 #define DYN_STATIC_LOCK_BLOCK_NUM (0x0EU)
61 #define DYN_STATIC_LOCK0_BYTE_NUM (0x00U)
62 #define DYN_STATIC_LOCK0_BYTE_VALUE (0xFFU)
64 #define DYN_STATIC_LOCK1_BYTE_NUM (0x01U)
65 #define DYN_STATIC_LOCK1_BYTE_VALUE (0x7FU)
67 #define DYN_CC_RWA_BYTE_NUMBER (0x03U)
68 #define DYN_CC_READ_ONLY_VALUE (0x0FU)
70 #endif /* #ifdef FRINFC_READONLY_NDEF */
73 * \brief \copydoc page_ovr enum for the topaz sequence of execution.
75 typedef enum phFriNfc_Tpz_ParseSeq
86 }phFriNfc_Tpz_ParseSeq_t;
88 typedef enum phFriNfc_Tpz_WrSeq
101 }phFriNfc_Tpz_WrSeq_t;
103 #ifdef FRINFC_READONLY_NDEF
105 typedef enum phFriNfc_Tpz_RO_Seq
110 RD_STATIC_LOCK_BYTE0,
111 WR_STATIC_LOCK_BYTE0,
113 }phFriNfc_Tpz_RO_Seq_t;
115 #endif /* #ifdef FRINFC_READONLY_NDEF */
117 /********************************** End of data structures *********************************/
119 /********************************** Start of Macros *********************************/
120 /* New state for TOPAZ dynamic card*/
121 #define PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF (0x10U)
123 #ifdef FRINFC_READONLY_NDEF
124 #define PH_FRINFC_TOPAZ_STATE_READ_ONLY (0x11U)
125 #endif /* #ifdef FRINFC_READONLY_NDEF */
127 #define NIBBLE_SIZE (0x04U)
128 /* Byte shifting for the topaz */
129 #define TOPAZ_BYTE_SHIFT (0x08U)
130 /* Lock and memory control TLV length. Always 3 bytes */
131 #define TOPAZ_MEM_LOCK_TLV_LENGTH (0x03U)
132 /* UID byte length */
133 #define TOPAZ_UID_BYTES_LENGTH (0x08U)
135 /* Number os static lock and reserved bytes */
136 #define TOPAZ_STATIC_LOCK_RES_BYTES (0x18U)
137 /* Number of static lock and reserved memory. This value is 3 (because
138 block number D, E and F are lock and reserved blocks */
139 #define TOPAZ_STATIC_LOCK_BLOCK_AREAS (0x03U)
140 /* First lock or reserved block in the static area of the card */
141 #define TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO (0x0DU)
142 /* First lock or reserved byte number in the static area of the card */
143 #define TOPAZ_STATIC_LOCK_RES_START (0x68U)
144 /* End lock or reserved byte number in the static area of the card */
145 #define TOPAZ_STATIC_LOCK_RES_END (0x78U)
148 #define TOPAZ_CC_BYTES_LENGTH (0x04U)
150 /* In TOPAZ card each block has 8 bytes */
151 #define TOPAZ_BYTES_PER_BLOCK (0x08U)
152 /* Each byte has 8 bites */
153 #define TOPAZ_BYTE_SIZE_IN_BITS (0x08U)
155 /* This mask is to get the least significant NIBBLE from a BYTE */
156 #define TOPAZ_NIBBLE_MASK (0x0FU)
157 /* This is used to mask the least significant BYTE from a TWO BYTE value */
158 #define TOPAZ_BYTE_LENGTH_MASK (0x00FFU)
160 /* Total segments in TOPAZ 512 bytes card. Each segment = 128 bytes,
161 so there are 4 segements in the card */
162 #define TOPAZ_TOTAL_SEG_TO_READ (0x04U)
163 /* SPEC version value shall be 0x10 as per the TYPE 1 specification */
164 #define TOPAZ_SPEC_VERSION (0x10U)
166 /* Response length for READ SEGMENT command is 128 bytes */
167 #define TOPAZ_SEGMENT_READ_LENGTH (0x80U)
168 /* Response length for WRITE-1E command is 1 byte */
169 #define TOPAZ_WRITE_1_RESPONSE (0x01U)
170 /* Response length for WRITE-8E command is 8 bytes */
171 #define TOPAZ_WRITE_8_RESPONSE (0x08U)
172 /* Response length for READ-8 command is 8 bytes */
173 #define TOPAZ_READ_8_RESPONSE (0x08U)
175 /* Data bytes that can be written for the WRITE-8E command is 8 bytes */
176 #define TOPAZ_WRITE_8_DATA_LENGTH (0x08U)
178 /* Get the exact byte address of the card from the segment number
179 and the parse index of each segment */
180 #define TOPAZ_BYTE_ADR_FROM_SEG(seg, parse_index) \
181 (((seg) * TOPAZ_SEGMENT_READ_LENGTH) + (parse_index))
183 /* Get the segment number of the card from the byte address */
184 #define TOPAZ_SEG_FROM_BYTE_ADR(byte_addr) \
185 ((byte_addr) / TOPAZ_SEGMENT_READ_LENGTH)
186 /* Get the block number of the card from the byte address */
187 #define TOPAZ_BLK_FROM_BYTE_ADR(byte_addr) \
188 ((byte_addr) / TOPAZ_BYTES_PER_BLOCK)
189 /* Get the block offset of a block number of the card from the byte address */
190 #define TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR(byte_addr) \
191 ((byte_addr) % TOPAZ_BYTES_PER_BLOCK)
192 /* Get the exact byte address of the card from the block number
193 and the byte offset of the block number */
194 #define TOPAZ_BYTE_ADR_FROM_BLK(block_no, byte_offset) \
195 (((block_no) * TOPAZ_BYTES_PER_BLOCK) + (byte_offset))
196 /* To increment the block number and if block number overlaps with the
197 static lock and reserved blocks, then skip the blocks */
198 #define TOPAZ_INCREMENT_SKIP_STATIC_BLOCK(block_no) \
199 ((((block_no) + 1) == TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO) ? \
200 (((block_no) + 1) + TOPAZ_STATIC_LOCK_BLOCK_AREAS) : \
203 #ifdef FRINFC_READONLY_NDEF
205 #define TOPAZ_CONVERT_BITS_TO_BYTES(bits_to_bytes) \
206 (((bits_to_bytes % TOPAZ_BYTE_SIZE_IN_BITS) > 0) ? \
207 ((bits_to_bytes / TOPAZ_BYTE_SIZE_IN_BITS) + 1) : \
208 (bits_to_bytes / TOPAZ_BYTE_SIZE_IN_BITS))
210 #endif /* #ifdef FRINFC_READONLY_NDEF */
211 /********************************** End of Macros *********************************/
217 * \name Topaz Mapping - Helper Functions
223 * \brief \copydoc page_ovr Helper function for Topaz. This function shall read defined
224 * bytes from the card.
228 phFriNfc_Tpz_H_NxpRead (
229 phFriNfc_NdefMap_t *psNdefMap);
232 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
233 * received read id command.
237 phFriNfc_Tpz_H_ChkReadID (
238 phFriNfc_NdefMap_t *psNdefMap);
242 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
247 phFriNfc_Tpz_H_ProReadResp (
248 phFriNfc_NdefMap_t *psNdefMap);
251 * \brief \copydoc page_ovr Helper function for Topaz. This function calls the
256 phFriNfc_Tpz_H_Complete (
257 phFriNfc_NdefMap_t *NdefMap,
262 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
263 * the lock bits and set a card state
267 phFriNfc_Tpz_H_ChkLockBits (
268 phFriNfc_NdefMap_t *psNdefMap);
271 * \brief \copydoc page_ovr Helper function for Topaz. This function writes defined
272 * bytes into the card
276 phFriNfc_Tpz_H_NxpWrite (
277 phFriNfc_NdefMap_t *psNdefMap,
278 uint8_t *p_write_data,
279 uint8_t wr_data_len);
283 * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
284 * till the NDEF TLV is found. Also, it returns error if it founds wrong TLVs.
288 phFriNfc_Tpz_H_ParseTLVs (
289 phFriNfc_NdefMap_t *psNdefMap);
292 * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
293 * till the TYPE of the LOCK control TLV is found.
294 * Also, it returns error if it founds wrong TYPE.
298 phFriNfc_Tpz_H_ParseLockTLVType (
299 phFriNfc_NdefMap_t *psNdefMap,
300 uint8_t *p_parse_data,
301 uint16_t *p_parse_index,
302 uint16_t total_len_to_parse,
303 phFriNfc_Tpz_ParseSeq_t *seq_to_execute);
306 * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
307 * till the TYPE of the MEMORY control TLV is found.
308 * Also, it returns error if it founds wrong TYPE.
312 phFriNfc_Tpz_H_ParseMemTLVType (
313 phFriNfc_NdefMap_t *psNdefMap,
314 uint8_t *p_parse_data,
315 uint16_t *p_parse_index,
316 uint16_t total_len_to_parse,
317 phFriNfc_Tpz_ParseSeq_t *seq_to_execute);
320 * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
321 * till the TYPE of the NDEF control TLV is found.
322 * Also, it returns error if it founds wrong TYPE.
326 phFriNfc_Tpz_H_ParseNdefTLVType (
327 phFriNfc_NdefMap_t *psNdefMap,
328 uint8_t *p_parse_data,
329 uint16_t *p_parse_index,
330 uint16_t total_len_to_parse,
331 phFriNfc_Tpz_ParseSeq_t *seq_to_execute);
334 * \brief \copydoc page_ovr Helper function for Topaz. This function gets the lock bytes
339 phFriNfc_Tpz_H_GetLockBytesInfo (
340 phFriNfc_NdefMap_t *psNdefMap,
341 uint8_t *p_lock_info);
344 * \brief \copydoc page_ovr Helper function for Topaz. This function gets the reserved bytes
349 phFriNfc_Tpz_H_GetMemBytesInfo (
350 phFriNfc_NdefMap_t *psNdefMap,
351 uint8_t *p_mem_info);
354 * \brief \copydoc page_ovr Helper function for Topaz. This function copies and checks the CC bytes.
355 * This function checks for the lock bytes value and card state also.
359 phFriNfc_Tpz_H_CheckCCBytes (
360 phFriNfc_NdefMap_t *psNdefMap);
363 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC bytes.
368 phFriNfc_Tpz_H_CheckCCBytesForWrite (
369 phFriNfc_NdefMap_t *psNdefMap);
373 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the read bytes.
374 * This function also checks for the lock and reserved bytes and skips the bytes before copying it
379 phFriNfc_Tpz_H_CopyReadData (
380 phFriNfc_NdefMap_t *psNdefMap);
383 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the stored read bytes.
384 * This function is used only for the offset " PH_FRINFC_NDEFMAP_SEEK_CUR ".
388 phFriNfc_Tpz_H_RemainingReadDataCopy (
389 phFriNfc_NdefMap_t *psNdefMap);
392 * \brief \copydoc page_ovr Helper function for Topaz. This function gives the exact byte address
393 * of the value field after the NDEF TYPE field
397 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
398 phFriNfc_NdefMap_t *psNdefMap);
401 * \brief \copydoc page_ovr Helper function for Topaz. This function gives the exact byte address
402 * of the value field after the NDEF TYPE field
406 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (
407 phFriNfc_NdefMap_t *psNdefMap,
408 uint16_t size_to_write);
411 * \brief \copydoc page_ovr Helper function for Topaz. This function gives the number of bytes to skip.
412 * This function checks the input byte address and checks if any lock or reserved bytes matches with the
413 * given address. if yes, then it will return number od bytes to skip.
417 phFriNfc_Tpz_H_GetSkipSize (
418 phFriNfc_NdefMap_t *psNdefMap,
419 uint16_t byte_adr_card);
422 * \brief \copydoc page_ovr Helper function for Topaz. This function gives the actual data that can
423 * be read and written in the card.
424 * This function checks for the lock and reserved bytes and subtracts the remaining size to give the
429 phFriNfc_Tpz_H_ActualCardSize (
430 phFriNfc_NdefMap_t *psNdefMap);
433 * \brief \copydoc page_ovr Helper function for Topaz. This function processes the response for
438 phFriNfc_Tpz_H_ProWrResp (
439 phFriNfc_NdefMap_t *psNdefMap);
442 * \brief \copydoc page_ovr Helper function for Topaz. This function processes the read 8 commands,
443 * that is required for writing the data
447 phFriNfc_Tpz_H_ProRdForWrResp (
448 phFriNfc_NdefMap_t *psNdefMap);
451 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the user data to the
452 * write buffer and writes the data to the card. If the lock or memory blocks are in between the
453 * write data, then read the current block
457 phFriNfc_Tpz_H_CopySendWrData (
458 phFriNfc_NdefMap_t *psNdefMap);
461 * \brief \copydoc page_ovr Helper function for Topaz. This function compares the input block
462 * number with lock bytes block number and returns the p_skip_size which is the lock bytes
467 phFriNfc_Tpz_H_CompareLockBlocks (
468 phFriNfc_NdefMap_t *psNdefMap,
470 uint16_t *p_skip_size);
473 * \brief \copydoc page_ovr Helper function for Topaz. This function compares the input block
474 * number with reserved bytes block number and returns the p_skip_size which is the reserved bytes
479 phFriNfc_Tpz_H_CompareMemBlocks (
480 phFriNfc_NdefMap_t *psNdefMap,
482 uint16_t *p_skip_size);
485 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the read data and update
486 * the user bytes by skipping lock or memory control areas. Also, used while updating the value field
487 * skips the initial bytes and to start at the proper value field byte offset of the block
491 phFriNfc_Tpz_H_CopyReadDataAndWrite (
492 phFriNfc_NdefMap_t *psNdefMap);
496 * \brief \copydoc page_ovr Helper function for Topaz. This function reads the required block for writing,
497 * as some of the bytes shall not be overwritten
501 phFriNfc_Tpz_H_RdForWrite (
502 phFriNfc_NdefMap_t *psNdefMap);
505 * \brief \copydoc page_ovr Helper function for Topaz. This function reads the length block for writing,
506 * updates the length bytes with 0
510 phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (
511 phFriNfc_NdefMap_t *psNdefMap);
514 * \brief \copydoc page_ovr Helper function for Topaz. This function reads the length block for writing,
515 * updates the length bytes with exact bytes that was written in the card
519 phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (
520 phFriNfc_NdefMap_t *psNdefMap);
523 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the NDEF TYPE of the
524 * NDEF TLV to the specific byte address. This function is called only if the previous write is
525 * failed or there is no NDEF TLV with correct CC bytes
529 phFriNfc_Tpz_H_UpdateNdefTypeField (
530 phFriNfc_NdefMap_t *psNdefMap);
532 #ifdef FRINFC_READONLY_NDEF
536 phFriNfc_Tpz_H_ProcessReadOnly (
537 phFriNfc_NdefMap_t *psNdefMap);
541 phFriNfc_Tpz_H_UpdateAndWriteLockBits (
542 phFriNfc_NdefMap_t *psNdefMap);
545 #endif /* #ifdef FRINFC_READONLY_NDEF */
549 * \brief Check whether a particular Remote Device is NDEF compliant.
551 * The function checks whether the peer device is NDEF compliant.
553 * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t
554 * structure describing the component context.
556 * \retval NFCSTATUS_PENDING The action has been successfully triggered.
557 * \retval Others An error has occurred.
560 NFCSTATUS phFriNfc_TopazDynamicMap_ChkNdef( phFriNfc_NdefMap_t *NdefMap)
562 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
563 NFCSTATUS_INVALID_PARAMETER);
564 if ( NdefMap != NULL)
566 /* Update the previous operation */
567 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
568 /* Update the CR index to know from which operation completion
569 routine has to be called */
570 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
571 NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
572 NdefMap->TopazContainer.CurrentSeg = 0;
573 NdefMap->TopazContainer.NdefTLVByteAddress = 0;
574 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
576 NdefMap->TopazContainer.CurrentBlock = 0;
577 NdefMap->TopazContainer.WriteSeq = 0;
578 NdefMap->TopazContainer.ExpectedSeq = 0;
580 (void)memset ((void *)&(NdefMap->LockTlv), 0,
581 sizeof (phFriNfc_LockCntrlTLVCont_t));
583 (void)memset ((void *)&(NdefMap->MemTlv), 0,
584 sizeof (phFriNfc_ResMemCntrlTLVCont_t));
587 NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_DYNAMIC_CARD;
589 /* Change the state to Read */
590 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
592 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_DYNAMIC_INIT_CHK_NDEF;
593 #ifdef TOPAZ_RAW_SUPPORT
595 *NdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
599 #ifdef PH_HAL4_ENABLE
600 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
602 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
605 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
607 Result = phFriNfc_Tpz_H_NxpRead(NdefMap);
615 * \brief Initiates Reading of NDEF information from the Remote Device.
617 * The function initiates the reading of NDEF information from a Remote Device.
618 * It performs a reset of the state and starts the action (state machine).
619 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
620 * has been triggered.
623 NFCSTATUS phFriNfc_TopazDynamicMap_RdNdef( phFriNfc_NdefMap_t *NdefMap,
625 uint32_t *PacketDataLength,
628 NFCSTATUS Result = NFCSTATUS_SUCCESS;
630 /* Copy user buffer to the context */
631 NdefMap->ApduBuffer = PacketData;
632 /* Copy user length to the context */
633 NdefMap->ApduBufferSize = *PacketDataLength;
634 /* Update the user memory size to a context variable */
635 NdefMap->NumOfBytesRead = PacketDataLength;
636 /* Number of bytes read from the card is zero.
637 This variable returns the number of bytes read
639 *NdefMap->NumOfBytesRead = 0;
640 /* Index to know the length read */
641 NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;
642 /* Store the offset in the context */
643 NdefMap->Offset = Offset;
644 /* Update the CR index to know from which operation completion
645 routine has to be called */
646 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
647 NdefMap->TopazContainer.SkipLockBlkFlag = 0;
649 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
650 if ((PH_FRINFC_NDEFMAP_SEEK_CUR == Offset) &&
651 (TRUE == NdefMap->TopazContainer.ReadWriteCompleteFlag))
653 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
654 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
656 else if ((PH_NDEFMAP_CARD_STATE_INITIALIZED ==
657 NdefMap->CardState) ||
658 (0 == NdefMap->TopazContainer.ActualNDEFMsgSize))
660 /* Length field of NDEF TLV is 0, so read cannot proceed */
661 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
662 NFCSTATUS_READ_FAILED);
664 else if ((PH_FRINFC_NDEFMAP_SEEK_BEGIN == Offset) ||
665 (PH_FRINFC_NDEFMAP_READ_OPE != NdefMap->PrevOperation))
667 /* If previous operation is not read then the read shall
669 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
670 /* Initialise byte number */
671 NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
673 NdefMap->TopazContainer.RemainingReadSize = 0;
674 NdefMap->TopazContainer.ReadBufferSize = 0;
675 NdefMap->TopazContainer.ReadWriteCompleteFlag = FALSE;
676 NdefMap->TopazContainer.CurrentBlock = 0;
677 NdefMap->TopazContainer.WriteSeq = 0;
679 NdefMap->TopazContainer.CurrentSeg = (uint8_t)TOPAZ_SEG_FROM_BYTE_ADR (
680 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (NdefMap));
682 /* Change the state to Read ID */
683 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID;
684 /*Change the state to Read ID*/
685 NdefMap->TopazContainer.ReadWriteCompleteFlag = 0;
686 #ifdef TOPAZ_RAW_SUPPORT
688 NdefMap->SendRecvBuf[0] = PH_FRINFC_TOPAZ_CMD_READID;
692 #ifdef PH_HAL4_ENABLE
693 NdefMap->Cmd.JewelCmd = phHal_eJewel_RID;
695 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid;
698 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
699 Result = phFriNfc_Tpz_H_NxpRead(NdefMap);
704 /* Change the state to Read */
705 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
706 Result = phFriNfc_Tpz_H_RemainingReadDataCopy (NdefMap);
713 #ifdef FRINFC_READONLY_NDEF
716 phFriNfc_TopazDynamicMap_ConvertToReadOnly (
717 phFriNfc_NdefMap_t *psNdefMap)
719 NFCSTATUS result = NFCSTATUS_SUCCESS;
720 uint8_t cc_read_only_byte = 0x0FU;
722 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_READ_ONLY;
724 psNdefMap->TopazContainer.read_only_seq = 0;
728 psNdefMap->TopazContainer.CurrentBlock = 0x01U;
729 psNdefMap->TopazContainer.ByteNumber = 0x03U;
731 #ifdef TOPAZ_RAW_SUPPORT
732 *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
734 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
735 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
737 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &cc_read_only_byte,
740 if (NFCSTATUS_PENDING == result)
742 psNdefMap->TopazContainer.read_only_seq = (uint8_t)WR_READONLY_CC;
749 #endif /* #ifdef FRINFC_READONLY_NDEF */
752 * \brief Initiates Writing of NDEF information to the Remote Device.
754 * The function initiates the writing of NDEF information to a Remote Device.
755 * It performs a reset of the state and starts the action (state machine).
756 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
757 * has been triggered.
759 NFCSTATUS phFriNfc_TopazDynamicMap_WrNdef( phFriNfc_NdefMap_t *NdefMap,
761 uint32_t *PacketDataLength,
764 NFCSTATUS Result = NFCSTATUS_SUCCESS;
766 /* Copy user buffer to the context */
767 NdefMap->ApduBuffer = PacketData;
768 /* Copy user length to the context */
769 NdefMap->ApduBufferSize = *PacketDataLength;
770 /* Index to know the length written */
771 NdefMap->ApduBuffIndex = 0;
772 /* Update the user memory size to a context variable */
773 NdefMap->WrNdefPacketLength = PacketDataLength;
774 /* Number of bytes written to the card is zero.
775 This variable returns the number of bytes written
777 *NdefMap->WrNdefPacketLength = 0;
778 /* Update the CR index to know from which operation completion
779 routine has to be called */
780 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
781 /* Store the offset in the context */
782 NdefMap->Offset = Offset;
784 /* Update the previous operation to write operation */
785 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
787 if (PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState)
789 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
790 NFCSTATUS_WRITE_FAILED);
792 else if ((PH_FRINFC_NDEFMAP_SEEK_CUR == Offset) &&
793 (TRUE == NdefMap->TopazContainer.ReadWriteCompleteFlag))
795 /* Offset = Current, but the read has reached the End of Card */
796 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
797 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
799 else if (0 == NdefMap->TopazContainer.NdefTLVByteAddress)
801 /* No NDEF TLV found in the card, so write not possible */
802 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
803 NFCSTATUS_NO_NDEF_SUPPORT);
805 else if ((PH_FRINFC_NDEFMAP_SEEK_BEGIN == Offset) ||
806 (PH_FRINFC_NDEFMAP_WRITE_OPE != NdefMap->PrevOperation))
808 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
809 /* Initialise byte number */
810 NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
811 /* State has to be changed */
812 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
813 NdefMap->TopazContainer.ReadWriteCompleteFlag = FALSE;
815 NdefMap->TopazContainer.CurrentSeg = 0;
816 NdefMap->TopazContainer.CurrentBlock = 1;
817 NdefMap->TopazContainer.WriteSeq = 0;
819 #ifdef TOPAZ_RAW_SUPPORT
821 *NdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
825 /* Topaz command = Jewel Nxp Read */
826 #ifdef PH_HAL4_ENABLE
827 NdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
829 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
832 NdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
834 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
835 /* Call read segment */
836 Result = phFriNfc_Tpz_H_NxpRead (NdefMap);
841 /* This part is to handle the Current offset,
842 Current offset is not yet validated */
843 Result = phFriNfc_Tpz_H_NxpWrite(NdefMap);
852 * \brief Completion Routine, Processing function, needed to avoid long blocking.
853 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
854 * Routine in order to be able to notify the component that an I/O has finished and data are
855 * ready to be processed.
859 void phFriNfc_TopazDynamicMap_Process( void *Context,
863 phFriNfc_NdefMap_t *NdefMap;
865 NdefMap = (phFriNfc_NdefMap_t *)Context;
868 if((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
870 switch(NdefMap->State)
872 case PH_FRINFC_TOPAZ_STATE_READ:
874 Status = phFriNfc_Tpz_H_ProReadResp (NdefMap);
878 case PH_FRINFC_TOPAZ_STATE_WRITE:
880 Status = phFriNfc_Tpz_H_ProWrResp (NdefMap);
884 case PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF:
886 Status = phFriNfc_Tpz_H_ProRdForWrResp (NdefMap);
890 case PH_FRINFC_TOPAZ_STATE_READID:
892 Status = phFriNfc_Tpz_H_ChkReadID(NdefMap);
896 #ifdef FRINFC_READONLY_NDEF
897 case PH_FRINFC_TOPAZ_STATE_READ_ONLY:
899 Status = phFriNfc_Tpz_H_ProcessReadOnly (NdefMap);
902 #endif /* #ifdef FRINFC_READONLY_NDEF */
906 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
907 NFCSTATUS_INVALID_DEVICE_REQUEST);
913 /* Call for the Completion Routine*/
914 if(Status != NFCSTATUS_PENDING)
916 phFriNfc_Tpz_H_Complete(NdefMap, Status);
920 #ifdef FRINFC_READONLY_NDEF
924 phFriNfc_Tpz_H_UpdateAndWriteLockBits (
925 phFriNfc_NdefMap_t *psNdefMap)
927 NFCSTATUS result = NFCSTATUS_SUCCESS;
928 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
929 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
930 uint8_t remaining_lock_bits = 0;
931 uint8_t byte_index = 0;
932 uint8_t lock_bytes_value[TOPAZ_BYTES_PER_BLOCK] = {0};
933 uint8_t lock_byte_index = 0;
934 uint8_t no_of_bits_left_in_block = 0;
936 ps_tpz_info = &(psNdefMap->TopazContainer);
937 ps_locktlv_info = &(psNdefMap->LockTlv);
939 (void)memcpy ((void *)lock_bytes_value, (void *)psNdefMap->SendRecvBuf,
940 TOPAZ_BYTES_PER_BLOCK);
942 if (ps_tpz_info->CurrentBlock == ps_locktlv_info->BlkNum)
944 /* Get the lock bits that has to locked */
945 remaining_lock_bits = ps_locktlv_info->LockTlvBuff[1];
946 byte_index = (uint8_t)ps_locktlv_info->ByteNum;
950 /* This condition applies only for the lock bits not ending with
951 " ps_locktlv_info->BlkNum ".
952 Calculate the remaining lock bits */
953 remaining_lock_bits = (uint8_t)(ps_locktlv_info->LockTlvBuff[1] -
954 ps_tpz_info->lock_bytes_written);
957 no_of_bits_left_in_block = (uint8_t)((TOPAZ_BYTES_PER_BLOCK - byte_index) *
958 TOPAZ_BYTE_SIZE_IN_BITS);
960 if (no_of_bits_left_in_block >= remaining_lock_bits)
962 /* Entire lock bits can be written */
963 uint8_t mod_value = 0;
965 mod_value = (uint8_t)(remaining_lock_bits % TOPAZ_BYTES_PER_BLOCK);
969 /* The lock bits ends in between of a byte */
970 /* lock bits to write is greater than 8 bits */
971 if (mod_value > TOPAZ_BYTE_SIZE_IN_BITS)
973 while (lock_byte_index <
974 (TOPAZ_CONVERT_BITS_TO_BYTES(remaining_lock_bits) - 1))
976 /* Set 1b to all bits left in the block */
977 lock_bytes_value[byte_index] = 0xFF;
978 lock_byte_index = (uint8_t)(lock_byte_index + 1);
979 byte_index = (uint8_t)(byte_index + 1);
981 /* Last byte of the lock bits shall be filled partially,
982 Set only the remaining lock bits and dont change
983 the other bit value */
984 lock_bytes_value[byte_index] = 0;
985 lock_bytes_value[byte_index] = (uint8_t)
986 SET_BITS8 (lock_bytes_value[byte_index], 0,
991 /* lock bits to write is less than 8 bits, so
992 there is only one byte to write.
993 Set only the remaining lock bits and dont change
994 the other bit value */
995 lock_bytes_value[0] = (uint8_t)
996 SET_BITS8 (lock_bytes_value[0], 0,
999 } /* if (mod_value) */
1002 /* The lock bits exactly ends at a byte
1003 MOD operation is 00, that means entire byte value shall be 0xFF, means
1004 every bit shall be to 1 */
1006 while (lock_byte_index < TOPAZ_CONVERT_BITS_TO_BYTES(remaining_lock_bits))
1008 /* Set 1b to all bits left in the block */
1009 lock_bytes_value[byte_index] = 0xFF;
1010 lock_byte_index = (uint8_t)(lock_byte_index + 1);
1011 byte_index = (uint8_t)(byte_index + 1);
1013 } /* else of if (mod_value) */
1014 ps_tpz_info->lock_bytes_written = remaining_lock_bits;
1016 else /* if (no_of_bits_left_in_block >= remaining_lock_bits) */
1018 /* Partial lock bits can be written. use next read to write
1019 the remaining lock bits */
1020 while (lock_byte_index < (no_of_bits_left_in_block /
1021 TOPAZ_BYTES_PER_BLOCK))
1023 /* Set 1b to all bits left in the block */
1024 lock_bytes_value[byte_index] = 0xFF;
1025 lock_byte_index = (uint8_t)(lock_byte_index + 1);
1026 byte_index = (uint8_t)(byte_index + 1);
1028 ps_tpz_info->lock_bytes_written = (uint8_t)(no_of_bits_left_in_block /
1029 TOPAZ_BYTES_PER_BLOCK);
1030 } /* else of if (no_of_bits_left_in_block >= remaining_lock_bits) */
1032 #ifdef TOPAZ_RAW_SUPPORT
1033 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
1035 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
1036 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1038 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, lock_bytes_value,
1039 sizeof (lock_bytes_value));
1045 phFriNfc_Tpz_H_ProcessReadOnly (
1046 phFriNfc_NdefMap_t *psNdefMap)
1048 NFCSTATUS result = NFCSTATUS_SUCCESS;
1049 phFriNfc_Tpz_RO_Seq_t e_readonly_seq = RD_LOCK_BYTES;
1050 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
1051 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
1052 static uint8_t static_lock_bytes[2] = {0};
1054 ps_tpz_info = &(psNdefMap->TopazContainer);
1055 ps_locktlv_info = &(psNdefMap->LockTlv);
1056 e_readonly_seq = (phFriNfc_Tpz_RO_Seq_t)psNdefMap->TopazContainer.read_only_seq;
1058 switch (e_readonly_seq)
1060 case WR_READONLY_CC:
1062 if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1064 psNdefMap->TopazContainer.CurrentBlock = (uint8_t)
1065 psNdefMap->LockTlv.BlkNum;
1067 e_readonly_seq = RD_LOCK_BYTES;
1068 #ifdef TOPAZ_RAW_SUPPORT
1070 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
1074 /* Topaz command = Jewel Nxp Read */
1075 #ifdef PH_HAL4_ENABLE
1076 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1078 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1081 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
1083 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1084 /* Call read segment */
1085 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1089 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1090 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1097 if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
1099 result = phFriNfc_Tpz_H_UpdateAndWriteLockBits (psNdefMap);
1101 if (NFCSTATUS_PENDING == result)
1103 e_readonly_seq = WR_LOCK_BYTES;
1108 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1109 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1116 if (TOPAZ_WRITE_8_RESPONSE == *psNdefMap->SendRecvLength)
1118 ps_tpz_info->CurrentBlock = (uint8_t)
1119 (ps_tpz_info->CurrentBlock + 1);
1120 if (ps_locktlv_info->LockTlvBuff[1] -
1121 ps_tpz_info->lock_bytes_written)
1123 #ifdef TOPAZ_RAW_SUPPORT
1125 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
1129 /* Topaz command = Jewel Nxp Read */
1130 #ifdef PH_HAL4_ENABLE
1131 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1133 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1136 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
1138 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1139 /* Call read segment */
1140 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1141 e_readonly_seq = RD_LOCK_BYTES;
1145 ps_tpz_info->CurrentBlock = (uint8_t)
1146 DYN_STATIC_LOCK_BLOCK_NUM;
1147 ps_tpz_info->ByteNumber = (uint8_t)
1148 DYN_STATIC_LOCK0_BYTE_NUM;
1149 #ifdef TOPAZ_RAW_SUPPORT
1151 *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_READ8;
1155 /* Topaz command = Jewel Nxp Read */
1156 #ifdef PH_HAL4_ENABLE
1157 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1159 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1162 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
1164 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1165 /* Call read segment */
1166 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1167 e_readonly_seq = RD_STATIC_LOCK_BYTE0;
1173 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1174 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1179 case RD_STATIC_LOCK_BYTE0:
1181 if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
1183 uint8_t lock_byte_value = 0;
1185 (void)memcpy ((void *)static_lock_bytes,
1186 (void *)(psNdefMap->SendRecvBuf +
1187 ps_tpz_info->ByteNumber),
1188 sizeof (static_lock_bytes));
1191 lock_byte_value = (uint8_t)(static_lock_bytes[0] |
1192 DYN_STATIC_LOCK0_BYTE_VALUE);
1194 #ifdef TOPAZ_RAW_SUPPORT
1195 *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1197 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1198 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1200 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &lock_byte_value,
1203 if (NFCSTATUS_PENDING == result)
1205 e_readonly_seq = (uint8_t)WR_STATIC_LOCK_BYTE0;
1210 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1211 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1216 case WR_STATIC_LOCK_BYTE0:
1218 if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1220 uint8_t lock_byte_value =
1221 (static_lock_bytes[1] |
1222 DYN_STATIC_LOCK1_BYTE_VALUE);
1224 ps_tpz_info->CurrentBlock = (uint8_t)
1225 DYN_STATIC_LOCK_BLOCK_NUM;
1226 ps_tpz_info->ByteNumber = (uint8_t)
1227 DYN_STATIC_LOCK1_BYTE_NUM;
1228 #ifdef TOPAZ_RAW_SUPPORT
1229 *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1231 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1232 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1234 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &lock_byte_value,
1237 if (NFCSTATUS_PENDING == result)
1239 e_readonly_seq = (uint8_t)WR_STATIC_LOCK_BYTE1;
1244 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1245 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1250 case WR_STATIC_LOCK_BYTE1:
1252 if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1254 /* READ ONLY successful */
1258 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1259 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1266 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1267 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1272 psNdefMap->TopazContainer.read_only_seq = (uint8_t)e_readonly_seq;
1276 #endif /* #ifdef FRINFC_READONLY_NDEF */
1280 phFriNfc_Tpz_H_ProWrResp (
1281 phFriNfc_NdefMap_t *psNdefMap)
1283 NFCSTATUS result = NFCSTATUS_SUCCESS;
1284 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
1285 phFriNfc_Tpz_WrSeq_t write_seq;
1286 uint8_t write_buf[] = {0x00};
1287 uint8_t write_index = 0;
1288 uint16_t write_len = 0;
1289 uint16_t len_byte_addr = 0;
1291 ps_tpz_info = &(psNdefMap->TopazContainer);
1292 write_seq = (phFriNfc_Tpz_WrSeq_t)(ps_tpz_info->WriteSeq);
1293 write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
1294 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
1300 /* TYPE field of the NDEF TLV write is complete */
1301 if (TOPAZ_WRITE_8_RESPONSE == *psNdefMap->SendRecvLength)
1303 psNdefMap->State = (uint8_t)
1304 PH_FRINFC_TOPAZ_STATE_WRITE;
1306 /* Now, Write 0 to the magic number byte */
1307 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_0;
1308 write_seq = WR_NMN_0;
1309 ps_tpz_info->CurrentBlock = 1;
1310 ps_tpz_info->ByteNumber = 0;
1312 #ifdef TOPAZ_RAW_SUPPORT
1313 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1315 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1316 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1317 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
1318 sizeof (write_buf));
1322 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1323 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1330 /* Magic number set to 0 write is complete */
1331 if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1333 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1334 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1335 /* Now the sequence = WR_LEN_1_0, so Length block is read,
1336 and only length bytes are made 0, before writing data to 0
1338 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1342 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1343 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1350 /* Length field is updated with the value 0 */
1351 if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1353 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1354 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1356 else if (write_len >= 0xFF)
1358 ps_tpz_info->ByteNumber = 0;
1360 ps_tpz_info->CurrentBlock = (uint8_t)
1361 TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1362 ps_tpz_info->CurrentBlock);
1364 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1365 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1366 /* Now the sequence = WR_LEN_1_1, so Length block is read,
1367 and only length bytes are made 0, before writing data to 0
1369 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1373 /* NDEF data length < 0xFF */
1374 len_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite
1375 (psNdefMap, write_len);
1376 ps_tpz_info->CurrentBlock = (uint8_t)
1377 TOPAZ_BLK_FROM_BYTE_ADR (len_byte_addr);
1378 ps_tpz_info->ByteNumber = (uint8_t)
1379 TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (len_byte_addr);
1382 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
1383 write_seq = WR_DATA;
1385 if (0 != ps_tpz_info->ByteNumber)
1387 /* If data starts in between the block then read
1389 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1393 /* Data starts at the beginning of the block, so start
1394 writing the user data */
1395 result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
1402 case WR_LEN_2_VALUE:
1404 /* 2nd length field is updated with the value 0 or the correct
1406 if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1408 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1409 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1413 ps_tpz_info->ByteNumber = 0;
1414 ps_tpz_info->CurrentBlock = (uint8_t)
1415 TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1416 ps_tpz_info->CurrentBlock);
1417 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1418 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1419 /* If length byte starts in between the block then read
1421 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1428 /* 3rd length field is updated with the value 0 */
1429 if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1431 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1432 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1436 len_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite
1437 (psNdefMap, write_len);
1438 ps_tpz_info->CurrentBlock = (uint8_t)
1439 TOPAZ_BLK_FROM_BYTE_ADR (len_byte_addr);
1440 ps_tpz_info->ByteNumber = (uint8_t)
1441 TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (len_byte_addr);
1443 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1444 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1446 if (0 != ps_tpz_info->ByteNumber)
1448 /* If data starts in between the block then read
1450 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1454 /* Data starts at the beginning of the block, so start
1455 writing the user data */
1456 result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
1464 /* Data is written from the input buffer */
1465 if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1467 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1468 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1470 else if (write_len == psNdefMap->ApduBuffIndex)
1472 /* Data to be written is completely written to the card */
1473 *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex;
1474 ps_tpz_info->WriteSeq = (uint8_t)WR_LEN_1_VALUE;
1475 write_seq = WR_LEN_1_VALUE;
1476 /* To write the first length byte, it has to be read and then
1477 the length has to be updated */
1478 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1482 ps_tpz_info->ByteNumber = 0;
1483 /* Go to the next block */
1484 ps_tpz_info->CurrentBlock = (uint8_t)
1485 TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1486 ps_tpz_info->CurrentBlock);
1487 /* Copy and write the user data */
1488 result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
1493 case WR_DATA_READ_REQD:
1495 /* This sequence is executed, if the first read has some
1496 lock or reserved blocks bytes and the lock or reserved
1497 blocks are extended to the next block */
1498 if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1500 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1501 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1505 ps_tpz_info->ByteNumber = 0;
1506 /* Go to the next block */
1507 ps_tpz_info->CurrentBlock = (uint8_t)
1508 TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1509 ps_tpz_info->CurrentBlock);
1510 /* Write is complete for one block, now because lock bytes are
1511 shifted to next blocks, the next block is read and update
1512 the written data by skipping the lock or reserved memory bytes */
1513 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1518 case WR_LEN_3_VALUE:
1520 /* 3rd LENGTH field byte is updated with correct written value */
1521 if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1523 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1524 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1528 #ifdef TOPAZ_RAW_SUPPORT
1529 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1531 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1532 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1534 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
1536 write_buf[write_index] = PH_FRINFC_TOPAZ_CC_BYTE0;
1537 write_index = (uint8_t)(write_index + 1);
1539 ps_tpz_info->ByteNumber = 0;
1540 ps_tpz_info->CurrentBlock = 1;
1542 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_E1;
1543 write_seq = WR_NMN_E1;
1545 /* Length byte write is complete, so now update the magic
1546 number byte with value 0xE1 */
1547 result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf,
1553 case WR_LEN_1_VALUE:
1555 /* 1st LENGTH field byte is updated */
1556 if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1558 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1559 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1561 else if (write_len < 0xFF)
1563 /* Total length to write is less than 0xFF, so LENGTH field has
1564 only one byte, then update the magic number byte with
1566 #ifdef TOPAZ_RAW_SUPPORT
1567 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1569 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1570 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1571 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
1573 write_buf[write_index] = PH_FRINFC_TOPAZ_CC_BYTE0;
1574 write_index = (uint8_t)(write_index + 1);
1576 ps_tpz_info->ByteNumber = 0;
1577 ps_tpz_info->CurrentBlock = 1;
1579 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_E1;
1580 write_seq = WR_NMN_E1;
1581 result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf,
1586 /* 2nd byte of the LENGTH field has to be updated so,
1587 read the block, before updating it */
1588 ps_tpz_info->ByteNumber = 0;
1589 ps_tpz_info->CurrentBlock = (uint8_t)
1590 TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1591 ps_tpz_info->CurrentBlock);
1592 ps_tpz_info->WriteSeq = (uint8_t)WR_LEN_2_VALUE;
1593 write_seq = WR_LEN_2_VALUE;
1594 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1601 /* Magic number is written, so update the actual ndef length. */
1602 if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1604 *psNdefMap->WrNdefPacketLength = (uint32_t)
1605 psNdefMap->ApduBuffIndex;
1606 ps_tpz_info->ActualNDEFMsgSize = (uint16_t)
1607 psNdefMap->ApduBuffIndex;
1611 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1612 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1628 phFriNfc_Tpz_H_UpdateNdefTypeField (
1629 phFriNfc_NdefMap_t *psNdefMap)
1631 NFCSTATUS result = NFCSTATUS_SUCCESS;
1632 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
1633 uint8_t write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
1635 ps_tpz_info = &(psNdefMap->TopazContainer);
1637 (void)memcpy ((void *)write_buf, (void *)
1638 psNdefMap->SendRecvBuf, TOPAZ_WRITE_8_DATA_LENGTH);
1640 /* Update the TYPE field of the NDEF TLV */
1641 write_buf[ps_tpz_info->ByteNumber] = PH_FRINFC_TOPAZ_NDEF_T;
1643 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
1645 #ifdef TOPAZ_RAW_SUPPORT
1646 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
1648 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
1649 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1650 result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf,
1651 sizeof (write_buf));
1658 phFriNfc_Tpz_H_ProRdForWrResp (
1659 phFriNfc_NdefMap_t *psNdefMap)
1661 /* This function is used during the write operation */
1662 NFCSTATUS result = NFCSTATUS_SUCCESS;
1663 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
1665 ps_tpz_info = &(psNdefMap->TopazContainer);
1667 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1669 if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
1671 switch ((phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq)
1675 /* Read bytes are for updating the TYPE field of the NDEF TLV */
1676 result = phFriNfc_Tpz_H_UpdateNdefTypeField (psNdefMap);
1684 /* Read bytes are for updating the LENGTH field to 0 of the NDEF TLV and
1685 also to update the data from the user buffer */
1686 result = phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (psNdefMap);
1691 case WR_DATA_READ_REQD:
1693 /* Read bytes are for skipping the lock and reserved bytes */
1694 result = phFriNfc_Tpz_H_CopyReadDataAndWrite (psNdefMap);
1698 case WR_LEN_1_VALUE:
1699 case WR_LEN_2_VALUE:
1700 case WR_LEN_3_VALUE:
1702 /* Read bytes are for updating the LENGTH field to the correct values
1704 result = phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (psNdefMap);
1710 /* Code must not come come here */
1717 /* Error in the length, wither the HW has sent wrong response length or
1718 the response length byte is corrupted */
1719 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1720 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1729 phFriNfc_Tpz_H_ChkReadID(
1730 phFriNfc_NdefMap_t *psNdefMap)
1732 NFCSTATUS result = NFCSTATUS_SUCCESS;
1733 int compare_result = 0;
1734 uint8_t recv_index = 0;
1737 if (PH_FRINFC_TOPAZ_VAL6 == *psNdefMap->SendRecvLength)
1739 if (((psNdefMap->SendRecvBuf[recv_index] &
1740 PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_DYNAMIC_HEADROM0_VAL))
1742 /* Copy UID to the context*/
1743 compare_result = phOsalNfc_MemCompare (
1744 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid,
1745 &psNdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
1746 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1747 if (0 == compare_result)
1749 /* State has to be changed */
1750 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
1752 /* Topaz command = READSEG */
1753 #ifdef TOPAZ_RAW_SUPPORT
1755 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
1759 #ifdef PH_HAL4_ENABLE
1760 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1762 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1764 psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
1766 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1767 /* Read bytes from the card */
1768 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1772 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1773 NFCSTATUS_NO_NDEF_SUPPORT);
1780 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1781 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1787 #define TOPAZ_READ_ID_ZERO_LENGTH (0x06U)
1790 phFriNfc_Tpz_H_NxpRead (
1791 phFriNfc_NdefMap_t *psNdefMap)
1793 NFCSTATUS result = NFCSTATUS_SUCCESS;
1794 uint8_t send_index = 0;
1795 #ifdef TOPAZ_RAW_SUPPORT
1796 uint8_t read_append[] = { 0x00, 0x00, 0x00, 0x00,
1797 0x00, 0x00, 0x00, 0x00};
1798 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1800 /* set the data for additional data exchange*/
1801 psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
1802 psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
1803 psNdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
1805 psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazDynamicMap_Process;
1806 psNdefMap->MapCompletionInfo.Context = psNdefMap;
1808 *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
1810 /* Depending on the jewel command, the send length is decided */
1811 #ifdef TOPAZ_RAW_SUPPORT
1813 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1814 /* " send_index " is incremented because already received buffer is filled with
1816 send_index = (uint8_t)(send_index + 1);
1818 switch (*psNdefMap->SendRecvBuf)
1820 switch(psNdefMap->Cmd.JewelCmd)
1821 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1823 #ifdef TOPAZ_RAW_SUPPORT
1825 case PH_FRINFC_TOPAZ_CMD_READID:
1827 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
1828 (void *)read_append, TOPAZ_READ_ID_ZERO_LENGTH);
1829 send_index = (uint8_t)(send_index + TOPAZ_READ_ID_ZERO_LENGTH);
1833 case PH_FRINFC_TOPAZ_CMD_READ8:
1835 psNdefMap->SendRecvBuf[send_index] =
1836 psNdefMap->TopazContainer.CurrentBlock;
1837 send_index = (uint8_t)(send_index + 1);
1841 case PH_FRINFC_TOPAZ_CMD_RSEG:
1843 psNdefMap->SendRecvBuf[send_index] = (uint8_t)
1844 (psNdefMap->TopazContainer.CurrentSeg
1846 send_index = (uint8_t)(send_index + 1);
1850 #else /* #ifdef TOPAZ_RAW_SUPPORT */
1852 #ifdef PH_HAL4_ENABLE
1853 case phHal_eJewel_RID:
1854 case phHal_eJewel_ReadAll:
1856 case phHal_eJewelCmdListJewelRid:
1857 case phHal_eJewelCmdListJewelReadAll:
1860 /* For READ ID and READ ALL, send length is 0 */
1861 psNdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
1865 #ifdef PH_HAL4_ENABLE
1866 case phHal_eJewel_Read:
1868 case phHal_eJewelCmdListJewelRead:
1871 /* Need to check the User data size request*/
1873 psNdefMap->SendLength = PH_FRINFC_TOPAZ_VAL3;
1877 case phHal_eJewel_ReadSeg:
1879 psNdefMap->SendRecvBuf[send_index] = (uint8_t)
1880 (psNdefMap->TopazContainer.CurrentSeg
1882 send_index = (uint8_t)(send_index + 1);
1883 psNdefMap->SendLength = send_index;
1887 case phHal_eJewel_Read8:
1889 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read4;
1890 psNdefMap->SendRecvBuf[send_index] = psNdefMap->TopazContainer.CurrentBlock;
1891 send_index = (uint8_t)(send_index + 1);
1892 psNdefMap->SendLength = send_index;
1896 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1900 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1901 NFCSTATUS_INVALID_DEVICE_REQUEST);
1905 if(result == NFCSTATUS_SUCCESS)
1907 #ifdef TOPAZ_RAW_SUPPORT
1909 if (PH_FRINFC_TOPAZ_CMD_READID != *psNdefMap->SendRecvBuf)
1911 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
1912 (void *)read_append, sizeof (read_append));
1913 send_index = (uint8_t)(send_index + sizeof (read_append));
1915 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
1916 (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid,
1917 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1918 send_index = (uint8_t)(send_index +
1919 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1922 psNdefMap->SendLength = send_index;
1924 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1925 /* Call the Overlapped HAL Transceive function */
1926 result = phFriNfc_OvrHal_Transceive( psNdefMap->LowerDevice,
1927 &psNdefMap->MapCompletionInfo,
1928 psNdefMap->psRemoteDevInfo,
1930 &psNdefMap->psDepAdditionalInfo,
1931 psNdefMap->SendRecvBuf,
1932 psNdefMap->SendLength,
1933 psNdefMap->SendRecvBuf,
1934 psNdefMap->SendRecvLength);
1942 phFriNfc_Tpz_H_NxpWrite(
1943 phFriNfc_NdefMap_t *psNdefMap,
1944 uint8_t *p_write_data,
1945 uint8_t wr_data_len)
1947 NFCSTATUS result = NFCSTATUS_SUCCESS;
1948 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
1949 uint8_t send_index = 0;
1951 ps_tpz_info = &(psNdefMap->TopazContainer);
1953 /* set the data for additional data exchange*/
1954 psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
1955 psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
1956 psNdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
1958 psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazDynamicMap_Process;
1959 psNdefMap->MapCompletionInfo.Context = psNdefMap;
1961 *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
1963 #ifdef TOPAZ_RAW_SUPPORT
1964 /* " send_index " is incremented because already received buffer is filled with
1966 send_index = (uint8_t)(send_index + 1);
1967 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1969 switch (*psNdefMap->SendRecvBuf)
1971 #else /* #ifdef TOPAZ_RAW_SUPPORT */
1973 switch (psNdefMap->Cmd.JewelCmd)
1975 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1977 #ifdef TOPAZ_RAW_SUPPORT
1979 case PH_FRINFC_TOPAZ_CMD_WRITE_1E:
1981 psNdefMap->SendRecvBuf[send_index] = (uint8_t)((ps_tpz_info->CurrentBlock
1982 << (NIBBLE_SIZE - 1)) |
1983 ps_tpz_info->ByteNumber);
1984 send_index = (uint8_t)(send_index + 1);
1988 case PH_FRINFC_TOPAZ_CMD_WRITE_E8:
1990 psNdefMap->SendRecvBuf[send_index] = ps_tpz_info->CurrentBlock;
1991 send_index = (uint8_t)(send_index + 1);
1995 #else /* #ifdef TOPAZ_RAW_SUPPORT */
1997 case phHal_eJewel_Write1E:
1999 psNdefMap->SendRecvBuf[send_index] = (uint8_t)((ps_tpz_info->CurrentBlock
2000 << (NIBBLE_SIZE - 1)) |
2001 ps_tpz_info->ByteNumber);
2002 send_index = (uint8_t)(send_index + 1);
2008 case phHal_eJewel_Write8E:
2010 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write4E;
2011 psNdefMap->SendRecvBuf[send_index] = ps_tpz_info->CurrentBlock;
2012 send_index = (uint8_t)(send_index + 1);
2016 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2020 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2021 NFCSTATUS_INVALID_DEVICE_REQUEST);
2027 if (NFCSTATUS_SUCCESS == result)
2029 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
2030 (void *)p_write_data, wr_data_len);
2032 send_index = (uint8_t)(send_index + wr_data_len);
2034 #ifdef TOPAZ_RAW_SUPPORT
2036 (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index),
2037 (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid,
2038 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
2039 send_index = (uint8_t)(send_index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
2041 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2043 psNdefMap->SendLength = send_index;
2045 /* Call the Overlapped HAL Transceive function */
2046 result = phFriNfc_OvrHal_Transceive( psNdefMap->LowerDevice,
2047 &psNdefMap->MapCompletionInfo,
2048 psNdefMap->psRemoteDevInfo,
2050 &psNdefMap->psDepAdditionalInfo,
2051 psNdefMap->SendRecvBuf,
2052 psNdefMap->SendLength,
2053 psNdefMap->SendRecvBuf,
2054 psNdefMap->SendRecvLength);
2061 phFriNfc_Tpz_H_ProReadResp(
2062 phFriNfc_NdefMap_t *psNdefMap)
2064 NFCSTATUS result = NFCSTATUS_SUCCESS;
2065 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
2066 uint8_t write_buffer[] = {0x00};
2068 ps_tpz_info = &(psNdefMap->TopazContainer);
2070 switch (psNdefMap->PrevOperation)
2072 case PH_FRINFC_NDEFMAP_CHECK_OPE:
2074 if (PH_FRINFC_TOPAZ_DYNAMIC_READSEG_RESP ==
2075 *psNdefMap->SendRecvLength)
2077 if (0 == ps_tpz_info->CurrentSeg)
2079 result = phFriNfc_Tpz_H_CheckCCBytes (psNdefMap);
2082 if (NFCSTATUS_SUCCESS == result)
2084 result = phFriNfc_Tpz_H_ParseTLVs (psNdefMap);
2089 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2090 NFCSTATUS_INVALID_RECEIVE_LENGTH);
2095 case PH_FRINFC_NDEFMAP_READ_OPE:
2097 if (PH_FRINFC_TOPAZ_DYNAMIC_READSEG_RESP ==
2098 *psNdefMap->SendRecvLength)
2100 /* call the data bytes to internal buffer*/
2101 result = phFriNfc_Tpz_H_CopyReadData (psNdefMap);
2105 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2106 NFCSTATUS_INVALID_RECEIVE_LENGTH);
2111 case PH_FRINFC_NDEFMAP_WRITE_OPE:
2113 /* read the bytes for cheking the CC bytes and lock bit status*/
2114 if(TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
2116 (void)memcpy ((void *)ps_tpz_info->CCByteBuf,
2117 (void *)(psNdefMap->SendRecvBuf),
2118 TOPAZ_CC_BYTES_LENGTH);
2120 result = phFriNfc_Tpz_H_CheckCCBytesForWrite (psNdefMap);
2121 if (NFCSTATUS_SUCCESS == result)
2123 if ((0x00 == *ps_tpz_info->CCByteBuf) ||
2124 (NDEF_T_TLV == ps_tpz_info->ExpectedSeq))
2126 /* This statement is for getting the new
2127 NDEF TLV byte address, because 1st CC byte is
2128 corrupted or no NDEF TLV in the card
2130 If the 1st CC byte (NDEF magic number) in the
2131 card is 0, means that previous write has failed,
2132 so to write the exact file
2134 The NDEF TLV is not present in the entire card, and
2135 the sequence is NDEF_T_TLV (this means, that lock and
2136 memory control TLV is found in the card)
2138 psNdefMap->State = (uint8_t)
2139 PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF;
2140 ps_tpz_info->WriteSeq = (uint8_t)WR_NDEF_T_TLV;
2142 ps_tpz_info->CurrentBlock = (uint8_t)
2143 TOPAZ_BLK_FROM_BYTE_ADR (
2144 ps_tpz_info->NdefTLVByteAddress);
2146 ps_tpz_info->ByteNumber = (uint8_t)
2147 TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (
2148 ps_tpz_info->NdefTLVByteAddress);
2150 #ifdef TOPAZ_RAW_SUPPORT
2151 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
2153 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
2154 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2156 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
2160 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_0;
2161 ps_tpz_info->CurrentBlock = 1;
2162 ps_tpz_info->ByteNumber = 0;
2163 psNdefMap->State = (uint8_t)
2164 PH_FRINFC_TOPAZ_STATE_WRITE;
2165 #ifdef TOPAZ_RAW_SUPPORT
2166 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
2168 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
2169 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2172 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buffer,
2173 sizeof (write_buffer));
2180 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2181 NFCSTATUS_INVALID_RECEIVE_LENGTH);
2188 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2189 NFCSTATUS_INVALID_DEVICE_REQUEST);
2199 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t *NdefMap,
2202 /* set the state back to the Reset_Init state*/
2203 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
2205 /* set the completion routine*/
2206 NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex].
2207 CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
2212 phFriNfc_Tpz_H_ChkLockBits(
2213 phFriNfc_NdefMap_t *psNdefMap)
2215 NFCSTATUS result = NFCSTATUS_SUCCESS;
2216 #ifdef ENABLE_LOCK_BITS_CHECK
2217 uint8_t *p_recv_buf = psNdefMap->SendRecvBuf;
2218 #endif /* #ifdef ENABLE_LOCK_BITS_CHECK */
2219 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
2221 #ifdef ENABLE_LOCK_BITS_CHECK
2223 /* Set the card state */
2224 psNdefMap->CardState = (uint8_t)
2225 (((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_0] ==
2226 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_0) &&
2227 ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_1] ==
2228 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_1)) &&
2229 ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_2] ==
2230 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2231 ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_3] ==
2232 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2233 ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_4] ==
2234 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2235 ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_5] ==
2236 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2237 ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_6] ==
2238 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7))) &&
2239 ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_7] ==
2240 PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) ?
2241 PH_NDEFMAP_CARD_STATE_INITIALIZED :
2242 PH_NDEFMAP_CARD_STATE_READ_ONLY);
2244 #endif /* #ifdef ENABLE_LOCK_BITS_CHECK */
2246 /* Set the card state from CC bytes */
2247 if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
2249 switch ((psNdefMap->TopazContainer.CCByteBuf[3] & 0xFF))
2251 case PH_FRINFC_TOPAZ_CC_READWRITE:
2253 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
2257 case PH_FRINFC_TOPAZ_CC_READONLY:
2259 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
2265 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2266 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2267 NFCSTATUS_NO_NDEF_SUPPORT);
2278 phFriNfc_Tpz_H_CheckCCBytes (
2279 phFriNfc_NdefMap_t *psNdefMap)
2281 NFCSTATUS result = NFCSTATUS_SUCCESS;
2282 phFriNfc_TopazCont_t *ps_tpz_info = &(psNdefMap->TopazContainer);
2283 uint8_t *p_recv_buf = psNdefMap->SendRecvBuf;
2284 uint16_t parse_index = 0;
2286 parse_index = (uint16_t)(parse_index + TOPAZ_UID_BYTES_LENGTH);
2288 (void)memcpy ((void *)ps_tpz_info->CCByteBuf,
2289 (void *)(p_recv_buf + parse_index),
2290 TOPAZ_CC_BYTES_LENGTH);
2292 p_recv_buf = ps_tpz_info->CCByteBuf;
2295 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2296 /* 1st CC byte value = 0 or 0xE1 */
2297 if ((PH_FRINFC_TOPAZ_CC_BYTE0 == p_recv_buf[parse_index])
2298 #ifdef TOPAZ_MAGIC_NO_0_CHK_ENABLE
2299 || (0 == p_recv_buf[parse_index])
2300 #endif /* #if TOPAZ_MAGIC_NO_0_CHK_ENABLE */
2302 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2304 parse_index = (uint16_t)(parse_index + 1);
2305 /* 2nd CC byte value = 0x10 */
2306 result = phFriNfc_Tpz_H_ChkSpcVer (psNdefMap, p_recv_buf[parse_index]);
2308 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2311 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2312 NFCSTATUS_NO_NDEF_SUPPORT);
2314 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2316 if (NFCSTATUS_SUCCESS == result)
2318 parse_index = (uint16_t)(parse_index + 1);
2319 /* 3rd CC byte value = 0x3F for 512 card */
2320 if (PH_FRINFC_TOPAZ_DYNAMIC_CC_BYTE2_MMSIZE == p_recv_buf[parse_index])
2322 /* Card size calculated as ((3rd CC byte * 8) - 4 CC bytes) */
2323 psNdefMap->CardMemSize = (uint16_t)((p_recv_buf[parse_index] *
2324 TOPAZ_BYTES_PER_BLOCK) -
2325 TOPAZ_CC_BYTES_LENGTH);
2326 ps_tpz_info->RemainingSize = (uint16_t)(psNdefMap->CardMemSize +
2327 TOPAZ_UID_BYTES_LENGTH +
2328 TOPAZ_CC_BYTES_LENGTH);
2329 result = phFriNfc_Tpz_H_ChkLockBits (psNdefMap);
2333 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2334 NFCSTATUS_NO_NDEF_SUPPORT);
2338 if (NFCSTATUS_SUCCESS != result)
2340 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2348 phFriNfc_Tpz_H_CheckCCBytesForWrite (
2349 phFriNfc_NdefMap_t *psNdefMap)
2351 NFCSTATUS result = NFCSTATUS_SUCCESS;
2352 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
2353 uint8_t check_cc_rw[] = {TOPAZ_SPEC_VERSION,
2354 PH_FRINFC_TOPAZ_DYNAMIC_CC_BYTE2_MMSIZE,
2355 PH_FRINFC_TOPAZ_CC_READWRITE};
2356 uint8_t check_index = 0;
2358 ps_tpz_info = &(psNdefMap->TopazContainer);
2360 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2362 (PH_FRINFC_TOPAZ_CC_BYTE0 == ps_tpz_info->CCByteBuf[check_index])
2363 #if TOPAZ_MAGIC_NO_0_CHK_ENABLE
2364 || (0 == ps_tpz_info->CCByteBuf[check_index])
2365 #endif /* #if TOPAZ_MAGIC_NO_0_CHK_ENABLE */
2367 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2369 check_index = (uint8_t)(check_index + 1);
2371 if ((check_cc_rw[0] != ps_tpz_info->CCByteBuf[1]) ||
2372 (check_cc_rw[1] != ps_tpz_info->CCByteBuf[2]) ||
2373 (check_cc_rw[2] != ps_tpz_info->CCByteBuf[3]))
2375 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2376 NFCSTATUS_NO_NDEF_SUPPORT);
2379 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2382 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2383 NFCSTATUS_NO_NDEF_SUPPORT);
2385 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2391 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
2392 phFriNfc_NdefMap_t *psNdefMap)
2394 phFriNfc_TopazCont_t *ps_tpz_info = &(psNdefMap->TopazContainer);
2395 uint16_t skip_size = 0;
2396 uint16_t byte_addr = 0;
2397 uint8_t exit_index = 0;
2399 byte_addr = ps_tpz_info->NdefTLVByteAddress;
2401 while (exit_index < ((ps_tpz_info->ActualNDEFMsgSize >= 0xFF) ? 3 : 1))
2403 byte_addr = (uint16_t)(byte_addr + 1);
2404 if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2406 byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2408 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2410 byte_addr = (uint16_t)(byte_addr + skip_size);
2411 exit_index = (uint8_t)(exit_index + 1);
2414 byte_addr = (uint16_t)(byte_addr + 1);
2415 if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2417 byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2419 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2421 byte_addr = (uint16_t)(byte_addr + skip_size);
2428 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (
2429 phFriNfc_NdefMap_t *psNdefMap,
2430 uint16_t size_to_write)
2432 phFriNfc_TopazCont_t *ps_tpz_info = &(psNdefMap->TopazContainer);
2433 uint16_t skip_size = 0;
2434 uint16_t byte_addr = 0;
2435 uint8_t exit_index = 0;
2437 byte_addr = ps_tpz_info->NdefTLVByteAddress;
2439 while (exit_index < ((size_to_write >= 0xFF) ? 3 : 1))
2441 byte_addr = (uint16_t)(byte_addr + 1);
2442 if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2444 byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2446 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2448 byte_addr = (uint16_t)(byte_addr + skip_size);
2449 exit_index = (uint8_t)(exit_index + 1);
2452 byte_addr = (uint16_t)(byte_addr + 1);
2453 if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2455 byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2457 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2459 byte_addr = (uint16_t)(byte_addr + skip_size);
2467 phFriNfc_Tpz_H_RemainingReadDataCopy (
2468 phFriNfc_NdefMap_t *psNdefMap)
2470 NFCSTATUS result = NFCSTATUS_SUCCESS;
2471 phFriNfc_TopazCont_t *ps_tpz_info = &(psNdefMap->TopazContainer);
2472 uint8_t copy_temp_buf[PH_FRINFC_NDEFMAP_TOPAZ_MAX_SIZE];
2473 uint16_t copy_length = 0;
2474 uint16_t read_copy_length = 0;
2477 if (0 != ps_tpz_info->ReadBufferSize)
2479 /* Data is already copied, so give it from the stored buffer */
2480 if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex) >=
2481 ps_tpz_info->ReadBufferSize)
2483 read_copy_length = ps_tpz_info->ReadBufferSize;
2484 (void)memcpy ((void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
2485 (void *)ps_tpz_info->ReadBuffer, ps_tpz_info->ReadBufferSize);
2489 read_copy_length = (uint16_t)(psNdefMap->ApduBufferSize -
2490 psNdefMap->ApduBuffIndex);
2492 copy_length = (uint16_t)(ps_tpz_info->ReadBufferSize -
2495 /* Copy data to user buffer */
2496 (void)memcpy ((void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
2497 (void *)ps_tpz_info->ReadBuffer, read_copy_length);
2499 /* Copy data from " ReadBuffer " to temporary buffer */
2500 (void)memcpy ((void *)copy_temp_buf,
2501 (void *)(ps_tpz_info->ReadBuffer + read_copy_length),
2504 /* Copy data from temporary buffer to " ReadBuffer " */
2505 (void)memcpy ((void *)ps_tpz_info->ReadBuffer,
2506 (void *)copy_temp_buf, copy_length);
2510 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
2512 ps_tpz_info->ReadBufferSize = (uint8_t)
2513 (ps_tpz_info->ReadBufferSize -
2515 ps_tpz_info->RemainingReadSize = (uint16_t)(
2516 ps_tpz_info->RemainingReadSize - read_copy_length);
2519 if (0 == ps_tpz_info->RemainingReadSize)
2521 /* No data to read, so return */
2522 *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
2523 ps_tpz_info->ReadBufferSize = 0;
2524 ps_tpz_info->ReadWriteCompleteFlag = TRUE;
2526 else if (psNdefMap->ApduBuffIndex == psNdefMap->ApduBufferSize)
2528 /* User data length is read completely */
2529 *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
2533 /* Stored data is not enough, so continue reading the next segment */
2534 ps_tpz_info->CurrentSeg = (uint8_t)
2535 (ps_tpz_info->CurrentSeg + 1);
2536 #ifdef TOPAZ_RAW_SUPPORT
2538 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
2542 psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
2544 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2545 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
2553 phFriNfc_Tpz_H_CopyReadData (
2554 phFriNfc_NdefMap_t *psNdefMap)
2556 NFCSTATUS result = NFCSTATUS_SUCCESS;
2557 phFriNfc_TopazCont_t *ps_tpz_info = &(psNdefMap->TopazContainer);
2558 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
2559 phFriNfc_ResMemCntrlTLVCont_t *ps_memtlv_info = NULL;
2560 uint16_t copy_index = 0;
2561 uint16_t copy_length = 0;
2562 uint16_t recv_length = 0;
2563 static uint16_t skip_size = 0;
2564 /* byte address read */
2565 uint16_t copy_till_address = 0;
2566 uint16_t exact_copy_length = 0;
2567 uint16_t actual_ndef_length = 0;
2570 recv_length = *(psNdefMap->SendRecvLength);
2572 actual_ndef_length = ps_tpz_info->ActualNDEFMsgSize;
2573 if (PH_FRINFC_NDEFMAP_SEEK_CUR == psNdefMap->Offset)
2575 actual_ndef_length = (uint16_t)(
2576 ps_tpz_info->RemainingReadSize +
2577 psNdefMap->ApduBuffIndex);
2580 exact_copy_length = (uint16_t)((psNdefMap->ApduBufferSize >
2581 actual_ndef_length) ? actual_ndef_length :
2582 psNdefMap->ApduBufferSize);
2584 if (0 == ps_tpz_info->CurrentSeg)
2586 /* Skip copying the UID bytes, CC bytes, and lock and reserved memory bytes
2588 recv_length = (*(psNdefMap->SendRecvLength) - TOPAZ_STATIC_LOCK_RES_BYTES);
2591 if (TOPAZ_SEG_FROM_BYTE_ADR (
2592 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (psNdefMap)) ==
2593 ps_tpz_info->CurrentSeg)
2595 copy_index = (uint16_t)(copy_index + (
2596 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
2597 psNdefMap) % TOPAZ_SEGMENT_READ_LENGTH));
2603 copy_index = (copy_index + skip_size);
2607 while (copy_index < recv_length)
2609 copy_length = (uint16_t)(recv_length - copy_index);
2610 copy_till_address = 0;
2611 /* IF MORE THAN ONE TLV EXISTS THEN ADD A WHILE LOOP HERE, AND PLACE THE
2612 IF STATEMENT INSIDE THE WHILE LOOP. ALSO,
2613 ps_locktlv_info = &(psNdefMap->LockTlv) change this to
2614 ps_locktlv_info = &(psNdefMap->LockTlv[index])
2616 ps_locktlv_info = &(psNdefMap->LockTlv);
2618 /* Check the lock bytes belong to this segment */
2619 (ps_tpz_info->CurrentSeg ==
2620 (ps_locktlv_info->ByteAddr / TOPAZ_SEGMENT_READ_LENGTH)) &&
2621 /* Now to check if the copy_index has surpassed the lock byte address */
2622 (TOPAZ_BYTE_ADR_FROM_SEG(ps_tpz_info->CurrentSeg, copy_index)
2623 <= ps_locktlv_info->ByteAddr)
2626 if ((ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_START) ||
2627 (ps_locktlv_info->ByteAddr >= (TOPAZ_STATIC_LOCK_RES_END + 8)))
2629 copy_till_address = ps_locktlv_info->ByteAddr;
2631 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
2632 ps_locktlv_info->ByteAddr);
2635 /* IF MORE THAN ONE TLV EXISTS THEN ADD A WHILE LOOP HERE, AND PLACE THE
2636 IF STATEMENT INSIDE THE WHILE LOOP. ALSO,
2637 ps_memtlv_info = &(psNdefMap->MemTlv) change this to
2638 ps_memtlv_info = &(psNdefMap->MemTlv[index])
2640 ps_memtlv_info = &(psNdefMap->MemTlv);
2642 /* Check the reserved bytes belong to this segment */
2643 (ps_tpz_info->CurrentSeg ==
2644 (ps_memtlv_info->ByteAddr / TOPAZ_SEGMENT_READ_LENGTH)) &&
2645 /* Now to check if the copy_index has surpassed the reserved byte address */
2646 (TOPAZ_BYTE_ADR_FROM_SEG(ps_tpz_info->CurrentSeg, copy_index)
2647 <= ps_memtlv_info->ByteAddr)
2650 if ((ps_memtlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_START) ||
2651 (ps_memtlv_info->ByteAddr >= (TOPAZ_STATIC_LOCK_RES_END + 8)))
2653 copy_till_address = (uint16_t)
2654 (((ps_memtlv_info->ByteAddr < copy_till_address) ||
2655 (0 == copy_till_address))?
2656 ps_memtlv_info->ByteAddr : copy_till_address);
2659 if (copy_till_address == ps_memtlv_info->ByteAddr)
2661 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
2662 ps_memtlv_info->ByteAddr);
2667 copy_length = (uint16_t) ((copy_till_address == 0) ? copy_length :
2668 ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
2671 /* After lock bytes, there are immediate reserved bytes, so " copy_length "
2673 if (0 != copy_length)
2675 /* If complete user buffer is not filled and the
2676 read data is greater than the user data buffer, then get the
2677 remaining size that should be copied.
2678 The below " if " statement is used for the above scenario */
2679 if ((copy_length > (uint16_t)
2680 (exact_copy_length - psNdefMap->ApduBuffIndex)) &&
2681 (exact_copy_length != psNdefMap->ApduBuffIndex))
2683 copy_length = (uint16_t)(exact_copy_length -
2684 psNdefMap->ApduBuffIndex);
2687 if (exact_copy_length != psNdefMap->ApduBuffIndex)
2689 (void)memcpy ((void *)(psNdefMap->ApduBuffer +
2690 psNdefMap->ApduBuffIndex),
2691 (void *)(psNdefMap->SendRecvBuf + copy_index),
2694 if (((copy_till_address == 0) ? copy_length :
2695 ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
2696 copy_index)) > (uint16_t)
2697 (exact_copy_length - psNdefMap->ApduBuffIndex))
2699 /* Copy remaining buffer in the static memory */
2700 (void)memcpy ((void *)(ps_tpz_info->ReadBuffer +
2701 ps_tpz_info->ReadBufferSize),
2702 (void *)(psNdefMap->SendRecvBuf + copy_index),
2703 (((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
2704 copy_index) - copy_length));
2706 ps_tpz_info->ReadBufferSize = (uint16_t)(((copy_till_address %
2707 TOPAZ_SEGMENT_READ_LENGTH) -
2708 copy_index) - copy_length);
2710 /* Copy the data in the user buffer */
2711 copy_index = (uint16_t)(copy_index +
2712 ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
2718 /* Copy the data in the user buffer */
2719 copy_index = (uint16_t)(copy_index + copy_length);
2722 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
2729 copy_length = (uint16_t) ((copy_till_address == 0) ? copy_length :
2730 ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) -
2733 /* Actual NDEF message size is greater than the last index copied in
2735 if (actual_ndef_length > (psNdefMap->ApduBuffIndex +
2736 ps_tpz_info->ReadBufferSize))
2738 /* The statement is correct, check the remaining length */
2739 copy_length = ((copy_length > (actual_ndef_length -
2740 psNdefMap->ApduBuffIndex)) ?
2741 (actual_ndef_length -
2742 psNdefMap->ApduBuffIndex) :
2745 /* Copy remaining buffer in the static memory */
2746 (void)memcpy ((void *)(ps_tpz_info->ReadBuffer +
2747 ps_tpz_info->ReadBufferSize),
2748 (void *)(psNdefMap->SendRecvBuf + copy_index),
2751 ps_tpz_info->ReadBufferSize = (uint8_t)(
2752 ps_tpz_info->ReadBufferSize +
2756 /* Copy the data in the user buffer */
2757 copy_index = (uint16_t)(copy_index + copy_length);
2761 if (copy_index != copy_till_address)
2766 if ((copy_index + skip_size) <= recv_length)
2768 copy_index = (uint16_t)(copy_index + skip_size);
2773 skip_size = (uint16_t)((skip_size > 0) ?
2774 (recv_length - copy_index) : 0);
2775 copy_index = (uint16_t)recv_length;
2779 if (exact_copy_length != psNdefMap->ApduBuffIndex)
2781 ps_tpz_info->CurrentSeg = (uint8_t)
2782 (ps_tpz_info->CurrentSeg + 1);
2783 #ifdef TOPAZ_RAW_SUPPORT
2785 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
2789 psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
2791 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2792 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
2796 *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
2797 if (psNdefMap->ApduBuffIndex == actual_ndef_length)
2799 ps_tpz_info->ReadBufferSize = 0;
2800 ps_tpz_info->ReadWriteCompleteFlag = TRUE;
2804 ps_tpz_info->RemainingReadSize = (actual_ndef_length -
2805 psNdefMap->ApduBuffIndex);
2814 phFriNfc_Tpz_H_ParseTLVs (
2815 phFriNfc_NdefMap_t *psNdefMap)
2817 NFCSTATUS result = NFCSTATUS_SUCCESS;
2818 phFriNfc_TopazCont_t *ps_tpz_info = &(psNdefMap->TopazContainer);
2819 uint8_t *p_recv_buf = NULL;
2820 uint16_t recv_length = 0;
2821 uint16_t parse_index = 0;
2822 phFriNfc_Tpz_ParseSeq_t expected_seq = (phFriNfc_Tpz_ParseSeq_t)
2823 ps_tpz_info->ExpectedSeq;
2824 uint16_t byte_addr = 0;
2825 /* This variable is kept static because if the size to skip LOCK or RESERVED
2826 bytes extends to next read then it shall be stored and used to skip the next
2829 static uint16_t skip_size = 0;
2830 /* This variable is kept static because if the bytes extends from the read segment,
2831 then the index shall be stored
2832 This is to store index copied from the
2833 1. lock memory VALUE field bytes in the LOCK and MEMORY CONTROL TLV.
2834 2. Also, LENGTH field of the NDEF TLV */
2835 static uint8_t lock_mem_ndef_index = 0;
2836 /* This variable is kept static because if the bytes extends from the read segment,
2837 then it has to stored
2838 This is to store the
2839 1. lock memory VALUE field bytes in the LOCK and MEMORY CONTROL TLV.
2840 2. Also, LENGTH field of the NDEF TLV */
2841 static uint8_t lock_mem_buf[TOPAZ_MEM_LOCK_TLV_LENGTH] = {0};
2842 /* This is used in case if there is no MAGIC NUMBER found
2844 TYPE field is not found after reading entire card */
2845 static uint16_t ndef_tlv_byte_addr = 0;
2847 p_recv_buf = psNdefMap->SendRecvBuf;
2848 recv_length = *psNdefMap->SendRecvLength;
2850 if (0 == ps_tpz_info->CurrentSeg)
2852 /* First read, so reset all the static variables */
2853 lock_mem_ndef_index = 0;
2855 ndef_tlv_byte_addr = 0;
2857 /* Skip copying the UID bytes and CC bytes, which is first 12 bytes */
2858 parse_index = (uint16_t)(TOPAZ_UID_BYTES_LENGTH +
2859 TOPAZ_CC_BYTES_LENGTH);
2860 /* Delete the lock and reserved memory bytes
2861 (which are the last 24 bytes in the card) */
2862 recv_length = (uint16_t)(*(psNdefMap->SendRecvLength) -
2863 TOPAZ_STATIC_LOCK_RES_BYTES);
2866 while ((parse_index < recv_length) && (NFCSTATUS_SUCCESS == result) &&
2867 (NDEF_V_TLV != expected_seq))
2871 /* Macro used to get the exact byte address of the card.
2872 This is done by using the current segment and the parse index */
2873 byte_addr = TOPAZ_BYTE_ADR_FROM_SEG (ps_tpz_info->CurrentSeg, parse_index);
2874 /* Skip size is to skip the lock or memory reserved bytes */
2875 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2880 if ((recv_length - parse_index) >= skip_size)
2882 parse_index = (uint16_t)(parse_index + skip_size);
2887 parse_index = (uint16_t)(parse_index + (recv_length -
2889 skip_size = (uint16_t)(skip_size - (recv_length -
2895 switch (expected_seq)
2899 /* Parse the bytes till TYPE field of LOCK TLV is found, Once the
2900 TYPE field is found then change the sequence to LOCK_L_TLV */
2901 result = phFriNfc_Tpz_H_ParseLockTLVType (psNdefMap, p_recv_buf,
2902 &parse_index, recv_length, &expected_seq);
2909 /* Parse the length field of LOCK TLV. Length field value of the
2910 LOCK TLV is always 3 */
2911 if (TOPAZ_MEM_LOCK_TLV_LENGTH != p_recv_buf[parse_index])
2913 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2914 NFCSTATUS_NO_NDEF_SUPPORT);
2918 parse_index = (uint16_t)(parse_index + 1);
2919 expected_seq = LOCK_V_TLV;
2926 /* Parse the VALUE field of the LOCK TLV */
2927 lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
2928 parse_index = (uint16_t)(parse_index + 1);
2929 lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
2932 /* All the 3 bytes are copied in the local buffer */
2933 if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
2935 #ifdef FRINFC_READONLY_NDEF
2936 (void)memcpy ((void *)psNdefMap->LockTlv.LockTlvBuff,
2937 (void *)lock_mem_buf, sizeof (lock_mem_buf));
2938 #endif /* #ifdef FRINFC_READONLY_NDEF */
2939 /* Calculate the byte address and size of the lock bytes */
2940 result = phFriNfc_Tpz_H_GetLockBytesInfo (psNdefMap, lock_mem_buf);
2941 lock_mem_ndef_index = 0;
2942 expected_seq = MEM_T_TLV;
2949 /* Parse the bytes till TYPE field of MEMORY TLV is found, Once the
2950 TYPE field is found then change the sequence to MEM_L_TLV */
2951 result = phFriNfc_Tpz_H_ParseMemTLVType (psNdefMap, p_recv_buf,
2952 &parse_index, recv_length, &expected_seq);
2958 /* Parse the length field of MEMORY TLV. Length field value of the
2959 MEMORY TLV is always 3 */
2960 if (TOPAZ_MEM_LOCK_TLV_LENGTH != p_recv_buf[parse_index])
2962 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2963 NFCSTATUS_NO_NDEF_SUPPORT);
2967 parse_index = (uint16_t)(parse_index + 1);
2968 expected_seq = MEM_V_TLV;
2976 /* Parse the VALUE field of the MEMORY TLV */
2977 lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
2978 parse_index = (uint16_t)(parse_index + 1);
2979 lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
2981 /* All the 3 bytes are copied in the local buffer */
2982 if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
2984 /* Calculate the byte address and size of the lock bytes */
2985 ndef_tlv_byte_addr = TOPAZ_BYTE_ADR_FROM_SEG (
2986 ps_tpz_info->CurrentSeg , parse_index);
2987 result = phFriNfc_Tpz_H_GetMemBytesInfo (psNdefMap, lock_mem_buf);
2988 lock_mem_ndef_index = 0;
2989 expected_seq = NDEF_T_TLV;
2997 /* Parse the bytes till TYPE field of NDEF TLV is found, Once the
2998 TYPE field is found then change the sequence to NDEF_L_TLV */
2999 result = phFriNfc_Tpz_H_ParseNdefTLVType (psNdefMap, p_recv_buf,
3000 &parse_index, recv_length, &expected_seq);
3007 /* Length field of the NDEF TLV */
3008 if (0 == lock_mem_ndef_index)
3010 /* This is the 1st time, the loop has entered this case,
3011 means that the NDEF byte address has to be updated */
3012 ps_tpz_info->NdefTLVByteAddress = (uint16_t)
3013 TOPAZ_BYTE_ADR_FROM_SEG (ps_tpz_info->CurrentSeg,
3017 if (0 != lock_mem_ndef_index)
3019 /* There is already index has been updated, update remaining
3021 lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
3022 parse_index = (uint16_t)(parse_index + 1);
3023 lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
3025 if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
3027 lock_mem_ndef_index = 0;
3028 ps_tpz_info->ActualNDEFMsgSize = (uint16_t)((lock_mem_buf[1] <<
3029 TOPAZ_BYTE_SHIFT) | lock_mem_buf[2]);
3030 expected_seq = NDEF_V_TLV;
3033 /* Check for remaining size in the card and the actual ndef length */
3034 else if (p_recv_buf[parse_index] <=
3035 (ps_tpz_info->RemainingSize - (parse_index + 1)))
3037 /* This check is added to see that length field in the TLV is
3038 greater than the 1 byte */
3039 if (0xFF == p_recv_buf[parse_index])
3041 lock_mem_buf[lock_mem_ndef_index] =
3042 p_recv_buf[parse_index];
3043 lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
3047 /* Length field of the TLV is ONE byte, so update the
3049 lock_mem_ndef_index = 0;
3050 ps_tpz_info->ActualNDEFMsgSize = (uint16_t)
3051 p_recv_buf[parse_index];
3053 expected_seq = NDEF_V_TLV;
3055 parse_index = (uint16_t)(parse_index + 1);
3059 /* Wrong length, remaining size in the card is lesser than the actual
3060 ndef message length */
3061 lock_mem_ndef_index = 0;
3062 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3063 NFCSTATUS_NO_NDEF_SUPPORT);
3072 }/* end of switch (expected_seq) */
3073 } /* end of if (0 != skip_size) */
3074 } /* while ((parse_index < recv_length) && (NFCSTATUS_SUCCESS != result) &&
3075 (NDEF_V_TLV != expected_seq)) */
3077 ps_tpz_info->ExpectedSeq = (uint8_t)expected_seq;
3079 if (0 == ps_tpz_info->CurrentSeg)
3081 /* First segment has the STATIC lock and reserved bytes, so delete it from
3082 the remaining size */
3083 ps_tpz_info->RemainingSize = (uint16_t)(ps_tpz_info->RemainingSize -
3084 (parse_index + TOPAZ_STATIC_LOCK_RES_BYTES));
3089 ps_tpz_info->RemainingSize = (uint16_t)(ps_tpz_info->RemainingSize -
3093 if ((NDEF_V_TLV == expected_seq) && (NFCSTATUS_SUCCESS == result))
3095 /* NDEF TLV found */
3096 result = phFriNfc_Tpz_H_ActualCardSize (psNdefMap);
3098 if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState) &&
3099 (0 != ps_tpz_info->ActualNDEFMsgSize))
3101 /* Check if the card state is READ ONLY or the actual NDEF size is 0
3102 if actual NDEF size is 0, then card state is INITIALISED
3104 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
3108 if ((NFCSTATUS_SUCCESS == result) && (NDEF_V_TLV != expected_seq))
3110 ps_tpz_info->CurrentSeg = (uint8_t)(ps_tpz_info->CurrentSeg + 1);
3111 if (TOPAZ_TOTAL_SEG_TO_READ == ps_tpz_info->CurrentSeg)
3113 /* Max segment to read reached, so no more read can be done */
3114 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3115 NFCSTATUS_NO_NDEF_SUPPORT);
3119 #ifdef TOPAZ_RAW_SUPPORT
3121 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
3125 psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
3127 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3128 result = phFriNfc_Tpz_H_NxpRead(psNdefMap);
3132 if ((NFCSTATUS_SUCCESS != result) && (NFCSTATUS_PENDING != result))
3134 /* Error scenario */
3135 ps_tpz_info->NdefTLVByteAddress = 0;
3136 ps_tpz_info->ActualNDEFMsgSize = 0;
3139 if (NFCSTATUS_PENDING != result)
3142 if ((0x00 == *ps_tpz_info->CCByteBuf) ||
3143 ((NDEF_T_TLV == expected_seq) &&
3144 (TOPAZ_TOTAL_SEG_TO_READ == ps_tpz_info->CurrentSeg)))
3146 /* This statement is for getting the new
3147 NDEF TLV byte address, because 1st CC byte is corrupted or
3148 no NDEF TLV in the card
3150 If the 1st CC byte (NDEF magic number) in the card is 0, means
3151 that previous write has failed, so to write the exact TLV,
3152 calculate the byte number
3154 The NDEF TLV is not present in the entire card, and the sequence is
3155 NDEF_T_TLV (this means, that lock and memory control TLV is found
3158 uint16_t size_to_skip = 0;
3159 ps_tpz_info->ActualNDEFMsgSize = 0;
3161 if (0 != ndef_tlv_byte_addr)
3163 /* ndef_tlv_byte_addr is updated, only after complete parsing the
3164 memory control TLV so the value shall not be 0 */
3167 /* This loop is added to make sure the lock and reserved bytes are not
3170 size_to_skip = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
3171 ndef_tlv_byte_addr);
3173 ndef_tlv_byte_addr = (uint16_t)(ndef_tlv_byte_addr +
3175 }while (0 != size_to_skip);
3177 /* Update the TLV byte address */
3178 ps_tpz_info->NdefTLVByteAddress = ndef_tlv_byte_addr;
3180 /* Update the remaining size */
3181 ps_tpz_info->RemainingSize = (uint16_t)(psNdefMap->CardMemSize +
3182 TOPAZ_UID_BYTES_LENGTH +
3183 TOPAZ_CC_BYTES_LENGTH);
3185 ps_tpz_info->RemainingSize = (uint16_t)
3186 (ps_tpz_info->RemainingSize -
3187 (ndef_tlv_byte_addr +
3188 TOPAZ_STATIC_LOCK_RES_BYTES));
3189 (void)phFriNfc_Tpz_H_ActualCardSize (psNdefMap);
3191 /* Length byte is subtracted here to get the actual NDEF
3192 read and write size */
3193 ps_tpz_info->NDEFRWSize = (uint16_t)
3194 (ps_tpz_info->NDEFRWSize - 2);
3195 ndef_tlv_byte_addr = 0;
3196 result = NFCSTATUS_SUCCESS;
3206 phFriNfc_Tpz_H_CopyReadDataAndWrite (
3207 phFriNfc_NdefMap_t *psNdefMap)
3209 NFCSTATUS result = NFCSTATUS_SUCCESS;
3210 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
3211 uint8_t write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3212 uint16_t write_index = 0;
3213 uint16_t write_len = 0;
3214 uint16_t byte_addr = 0;
3215 static uint16_t skip_size = 0;
3217 ps_tpz_info = &(psNdefMap->TopazContainer);
3219 write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
3220 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
3222 (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf,
3223 TOPAZ_WRITE_8_DATA_LENGTH);
3225 if (ps_tpz_info->CurrentBlock == TOPAZ_BLK_FROM_BYTE_ADR (
3226 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (psNdefMap, write_len)))
3231 /* Byte Number != 0 menas that the VALUE field of the TLV is in between the
3232 block, so the first few bytes shall be copied and then user data has to
3235 if (0 != ps_tpz_info->ByteNumber)
3237 write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);
3243 write_index = (uint16_t)(write_index + skip_size);
3246 while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) &&
3247 (write_len != psNdefMap->ApduBuffIndex))
3250 byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
3251 ps_tpz_info->ByteNumber);
3252 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
3256 write_buf[write_index] =
3257 psNdefMap->ApduBuffer[psNdefMap->ApduBuffIndex];
3259 write_index = (uint16_t)(write_index + 1);
3260 psNdefMap->ApduBuffIndex = (uint16_t)
3261 (psNdefMap->ApduBuffIndex + 1);
3262 ps_tpz_info->ByteNumber = (uint8_t)
3263 (ps_tpz_info->ByteNumber + 1);
3268 if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
3270 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
3272 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
3276 ps_tpz_info->ByteNumber = (uint8_t)
3277 (ps_tpz_info->ByteNumber + skip_size);
3278 write_index = (uint16_t)(write_index + skip_size);
3284 if (psNdefMap->ApduBuffIndex == write_len)
3286 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
3292 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
3297 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
3301 #ifdef TOPAZ_RAW_SUPPORT
3302 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3304 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3305 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3306 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
3307 sizeof (write_buf));
3315 phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (
3316 phFriNfc_NdefMap_t *psNdefMap)
3318 /* This function is called, only when the LENGTH field has to be updated
3319 with the correct value */
3320 NFCSTATUS result = NFCSTATUS_SUCCESS;
3321 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
3322 uint16_t write_len = 0;
3323 uint16_t write_index = 0;
3324 uint16_t byte_addr = 0;
3325 phFriNfc_Tpz_WrSeq_t write_seq;
3326 /* This variable is kept static because if the size to skip LOCK or RESERVED
3327 bytes extends to next read then it shall be stored and used to skip the next
3330 static uint16_t skip_size = 0;
3331 uint8_t write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3332 uint8_t exit_while = FALSE;
3334 ps_tpz_info = &(psNdefMap->TopazContainer);
3335 write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
3336 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
3338 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
3340 (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf,
3341 TOPAZ_WRITE_8_DATA_LENGTH);
3343 write_seq = (phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq;
3345 if (WR_LEN_1_VALUE == write_seq)
3347 /* First LENGTH field is geting updated, so the skip size
3352 if (0 != ps_tpz_info->ByteNumber)
3354 /* Byte Number is not 0, means that some data shall not be overwriteen till
3355 that position in the block */
3356 write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);
3361 /* This is possible after updating the FIRST length field
3362 skip size is skipped because of the pending LOCK or
3365 write_index = (uint16_t)(write_index + skip_size);
3368 while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) &&
3369 (FALSE == exit_while))
3372 /* Get the exact byte address from the block number and
3374 byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
3375 ps_tpz_info->ByteNumber);
3376 /* Get the skip size */
3377 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
3383 case WR_LEN_1_VALUE:
3385 /* First sequenc is always to update 1st LENGTH field of the TLV */
3386 if (write_len < 0xFF)
3388 /* This means the LENGTH field is only one BYTE */
3389 write_buf[write_index] = (uint8_t)
3390 psNdefMap->ApduBuffIndex;
3396 /* Update the 1st LENGTH field */
3397 write_buf[write_index] = (uint8_t)0xFF;
3402 case WR_LEN_2_VALUE:
3404 /* Update the 2nd LENGTH field */
3405 write_buf[write_index] = (uint8_t)
3406 (psNdefMap->ApduBuffIndex >> BYTE_SIZE);
3410 case WR_LEN_3_VALUE:
3412 /* Update the 3rd LENGTH field */
3413 write_buf[write_index] = (uint8_t)
3414 (psNdefMap->ApduBuffIndex &
3415 TOPAZ_BYTE_LENGTH_MASK);
3427 write_index = (uint16_t)(write_index + 1);
3429 /* As the write is done for 8 bytes, the write index cant
3430 go for more than or equal to 8 bytes, if it reaches 8 bytes
3431 then sequence shall not be incrmented */
3432 (TOPAZ_WRITE_8_DATA_LENGTH != write_index) &&
3433 /* If the last length field byte is updated then the
3434 write sequence shall not be incremented */
3435 (WR_LEN_3_VALUE != write_seq) &&
3436 /* Check added if the write length is less than 0xFF.
3437 If length is less than 0xFF, then write sequence
3438 shall not be incremented */
3442 /* Sequence is incremented to the next level */
3443 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
3445 /* Byte number is incremented */
3446 ps_tpz_info->ByteNumber = (uint8_t)
3447 (ps_tpz_info->ByteNumber + 1);
3452 if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
3454 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
3456 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
3460 ps_tpz_info->ByteNumber = (uint8_t)
3461 (ps_tpz_info->ByteNumber + skip_size);
3462 write_index = (uint16_t)(write_index + skip_size);
3469 ps_tpz_info->WriteSeq = (uint8_t)write_seq;
3471 #ifdef TOPAZ_RAW_SUPPORT
3472 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3474 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3475 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3477 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
3478 sizeof (write_buf));
3486 phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (
3487 phFriNfc_NdefMap_t *psNdefMap)
3489 /* This function is called, only when the LENGTH field has to be updated
3491 NFCSTATUS result = NFCSTATUS_SUCCESS;
3492 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
3493 uint16_t write_len = 0;
3494 uint16_t write_index = 0;
3495 uint16_t prev_apdu_index = 0;
3496 uint16_t byte_addr = 0;
3497 phFriNfc_Tpz_WrSeq_t write_seq;
3498 /* This variable is kept static because if the size to skip LOCK or RESERVED
3499 bytes extends to next read then it shall be stored and used to skip the next
3502 static uint16_t skip_size = 0;
3503 uint8_t write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3505 ps_tpz_info = &(psNdefMap->TopazContainer);
3506 write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
3507 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
3509 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
3511 (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf,
3512 TOPAZ_WRITE_8_DATA_LENGTH);
3514 prev_apdu_index = psNdefMap->ApduBuffIndex;
3515 write_seq = (phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq;
3517 if (WR_LEN_1_0 == write_seq)
3519 /* First LENGTH field is geting updated, so the skip size
3524 if (0 != ps_tpz_info->ByteNumber)
3526 /* Byte Number is not 0, means that some data shall not be overwriteen till
3527 that position in the block */
3528 write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);
3529 ps_tpz_info->ByteNumber = 0;
3534 /* This is possible after updating the FIRST length field
3535 skip size is skipped because of the pending LOCK or
3538 write_index = (uint16_t)(write_index + skip_size);
3541 while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) &&
3542 (write_len != psNdefMap->ApduBuffIndex))
3545 byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
3546 ps_tpz_info->ByteNumber);
3547 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
3555 /* First sequence is always to update 1st LENGTH field
3557 write_buf[write_index] = 0x00;
3558 write_index = (uint16_t)(write_index + 1);
3559 if (write_len < 0xFF)
3561 /* LENGTH field is only 1 byte, so update change the sequence to
3563 write_seq = WR_DATA;
3567 /* Go to the next LENGTH field to update */
3568 write_seq = (phFriNfc_Tpz_WrSeq_t)((TOPAZ_WRITE_8_DATA_LENGTH !=
3570 (write_seq + 1) : write_seq);
3578 /* Update 2nd and 3rd LEGNTH field */
3579 write_buf[write_index] = 0x00;
3580 write_index = (uint16_t)(write_index + 1);
3581 write_seq = (phFriNfc_Tpz_WrSeq_t)((TOPAZ_WRITE_8_DATA_LENGTH !=
3583 (write_seq + 1) : write_seq);
3590 /* Update the buffer by the user data */
3591 write_buf[write_index] =
3592 psNdefMap->ApduBuffer[psNdefMap->ApduBuffIndex];
3594 write_index = (uint16_t)(write_index + 1);
3595 psNdefMap->ApduBuffIndex = (uint16_t)
3596 (psNdefMap->ApduBuffIndex + 1);
3602 ps_tpz_info->ByteNumber = (uint8_t)
3603 (ps_tpz_info->ByteNumber + 1);
3607 /* LOCK and MEMORY bytes are found */
3608 if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
3610 /* skip size has exceeded the block number, so calculate the
3611 remaining skip size */
3612 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
3614 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
3618 /* skip the LOCK and MEMORY bytes size */
3619 ps_tpz_info->ByteNumber = (uint8_t)
3620 (ps_tpz_info->ByteNumber + skip_size);
3621 write_index = (uint16_t)(write_index + skip_size);
3627 if (psNdefMap->ApduBuffIndex == write_len)
3629 /* User data has been completely copied and it is ready to write, so
3630 change the sequence */
3631 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
3633 else if ((WR_DATA == write_seq) && (prev_apdu_index ==
3634 psNdefMap->ApduBuffIndex))
3636 /* The user data has not been written, only the LENGTH field is
3638 ps_tpz_info->WriteSeq = (uint8_t)((write_len < 0xFF) ?
3639 WR_LEN_1_0 : WR_LEN_3_0);
3643 /* Update the sequence in the context */
3644 ps_tpz_info->WriteSeq = (uint8_t)write_seq;
3647 ps_tpz_info->ByteNumber = 0;
3649 #ifdef TOPAZ_RAW_SUPPORT
3650 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3652 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3653 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3655 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
3656 sizeof (write_buf));
3662 phFriNfc_Tpz_H_RdForWrite (
3663 phFriNfc_NdefMap_t *psNdefMap)
3665 NFCSTATUS result = NFCSTATUS_SUCCESS;
3666 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
3667 phFriNfc_Tpz_WrSeq_t write_seq;
3668 uint16_t byte_addr = 0;
3669 uint8_t exit_while = FALSE;
3670 uint16_t skip_size = 0;
3672 ps_tpz_info = &(psNdefMap->TopazContainer);
3673 write_seq = (phFriNfc_Tpz_WrSeq_t)(ps_tpz_info->WriteSeq);
3675 #ifdef TOPAZ_RAW_SUPPORT
3677 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
3681 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
3683 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3685 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF;
3690 case WR_LEN_1_VALUE:
3692 byte_addr = (ps_tpz_info->NdefTLVByteAddress + 1);
3694 /* This loop is to skip the lock amd reserved bytes */
3695 while (FALSE == exit_while)
3697 if (TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO ==
3698 TOPAZ_BLK_FROM_BYTE_ADR (byte_addr))
3700 byte_addr = (uint16_t)(byte_addr +
3701 TOPAZ_STATIC_LOCK_RES_BYTES);
3703 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
3707 byte_addr = (uint16_t)(byte_addr + skip_size);
3721 case WR_LEN_2_VALUE:
3722 case WR_LEN_3_VALUE:
3724 byte_addr = (uint16_t)TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
3725 ps_tpz_info->ByteNumber);
3726 /* This loop is for to skip the lock amd reserved bytes */
3727 while (FALSE == exit_while)
3729 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap,
3733 byte_addr = (uint16_t)(byte_addr + skip_size);
3743 case WR_DATA_READ_REQD:
3745 /* Lock or reserved bytes found bytes */
3746 byte_addr = (uint16_t)TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock,
3747 ps_tpz_info->ByteNumber);
3757 ps_tpz_info->CurrentBlock = (uint8_t)
3758 TOPAZ_BLK_FROM_BYTE_ADR (byte_addr);
3759 ps_tpz_info->ByteNumber = (uint8_t)
3760 TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (byte_addr);
3762 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
3769 phFriNfc_Tpz_H_CompareLockBlocks (
3770 phFriNfc_NdefMap_t *psNdefMap,
3772 uint16_t *p_skip_size)
3774 uint16_t return_addr = 0;
3775 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
3777 ps_locktlv_info = &(psNdefMap->LockTlv);
3779 if (block_no == ps_locktlv_info->BlkNum)
3781 /* ps_tpz_info->ByteNumber = (uint8_t)ps_locktlv_info->ByteNum; */
3782 *p_skip_size = ps_locktlv_info->Size;
3783 return_addr = ps_locktlv_info->ByteAddr;
3791 phFriNfc_Tpz_H_CompareMemBlocks (
3792 phFriNfc_NdefMap_t *psNdefMap,
3794 uint16_t *p_skip_size)
3796 uint16_t return_addr = 0;
3797 phFriNfc_ResMemCntrlTLVCont_t *ps_memtlv_info = NULL;
3799 ps_memtlv_info = &(psNdefMap->MemTlv);
3801 if (block_no == ps_memtlv_info->BlkNum)
3803 /* ps_tpz_info->ByteNumber = (uint8_t)ps_memtlv_info->ByteNum; */
3804 *p_skip_size = ps_memtlv_info->Size;
3805 return_addr = ps_memtlv_info->ByteAddr;
3814 phFriNfc_Tpz_H_CopySendWrData (
3815 phFriNfc_NdefMap_t *psNdefMap)
3817 NFCSTATUS result = NFCSTATUS_SUCCESS;
3818 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
3819 uint8_t write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3821 uint8_t copy_length;
3822 uint16_t skip_size = 0;
3824 ps_tpz_info = &(psNdefMap->TopazContainer);
3825 write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
3826 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
3828 if (0 != phFriNfc_Tpz_H_CompareLockBlocks (psNdefMap,
3829 ps_tpz_info->CurrentBlock, &skip_size))
3831 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
3832 ps_tpz_info->ByteNumber = 0;
3833 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
3835 else if (0 != phFriNfc_Tpz_H_CompareMemBlocks (psNdefMap,
3836 ps_tpz_info->CurrentBlock, &skip_size))
3838 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
3839 ps_tpz_info->ByteNumber = 0;
3840 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
3844 #ifdef TOPAZ_RAW_SUPPORT
3845 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3847 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3848 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3849 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
3851 if ((write_len - psNdefMap->ApduBuffIndex) >= (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH)
3853 copy_length = (uint8_t)TOPAZ_WRITE_8_DATA_LENGTH;
3854 (void)memcpy ((void *)write_buf,
3855 (void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
3858 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
3863 copy_length = (uint8_t)(write_len - psNdefMap->ApduBuffIndex);
3865 (void)memcpy ((void *)write_buf,
3866 (void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex),
3867 TOPAZ_WRITE_8_DATA_LENGTH);
3869 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex +
3872 (void)memset ((void *)(write_buf + copy_length), 0x00,
3873 (TOPAZ_WRITE_8_DATA_LENGTH - copy_length));
3876 #ifdef TOPAZ_RAW_SUPPORT
3877 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3879 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3880 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3882 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf,
3883 sizeof (write_buf));
3893 phFriNfc_Tpz_H_ActualCardSize (
3894 phFriNfc_NdefMap_t *psNdefMap)
3896 NFCSTATUS result = NFCSTATUS_SUCCESS;
3897 phFriNfc_TopazCont_t *ps_tpz_info = NULL;
3898 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
3899 phFriNfc_ResMemCntrlTLVCont_t *ps_memtlv_info = NULL;
3900 uint16_t ndef_value_byte_addr = 0;
3901 uint16_t ndef_read_write_size = 0;
3903 ps_tpz_info = &(psNdefMap->TopazContainer);
3904 if (ps_tpz_info->ActualNDEFMsgSize > ps_tpz_info->RemainingSize)
3906 ps_tpz_info->ActualNDEFMsgSize = 0;
3907 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3908 NFCSTATUS_NO_NDEF_SUPPORT);
3912 ndef_read_write_size = ps_tpz_info->RemainingSize;
3913 ndef_value_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead
3916 ps_locktlv_info = &(psNdefMap->LockTlv);
3917 if (ps_locktlv_info->ByteAddr > ndef_value_byte_addr)
3919 ndef_read_write_size = (ndef_read_write_size -
3920 ps_locktlv_info->Size);
3923 ps_memtlv_info = &(psNdefMap->MemTlv);
3924 if (ps_memtlv_info->ByteAddr > ndef_value_byte_addr)
3926 ndef_read_write_size = (ndef_read_write_size -
3927 ps_memtlv_info->Size);
3930 if (ps_tpz_info->ActualNDEFMsgSize > ndef_read_write_size)
3932 ps_tpz_info->ActualNDEFMsgSize = 0;
3933 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3934 NFCSTATUS_NO_NDEF_SUPPORT);
3938 ps_tpz_info->NDEFRWSize = (uint16_t)
3939 ((ps_tpz_info->ActualNDEFMsgSize < 0xFF) ?
3940 (ndef_read_write_size - 2) :
3941 ndef_read_write_size);
3950 phFriNfc_Tpz_H_ParseLockTLVType (
3951 phFriNfc_NdefMap_t *psNdefMap,
3952 uint8_t *p_parse_data,
3953 uint16_t *p_parse_index,
3954 uint16_t total_len_to_parse,
3955 phFriNfc_Tpz_ParseSeq_t *seq_to_execute)
3957 NFCSTATUS result = NFCSTATUS_SUCCESS;
3958 uint16_t parse_index = *p_parse_index;
3959 phFriNfc_Tpz_ParseSeq_t expected_seq = *seq_to_execute;
3961 PHNFC_UNUSED_VARIABLE(psNdefMap);
3962 PHNFC_UNUSED_VARIABLE(total_len_to_parse);
3964 switch (p_parse_data[parse_index])
3966 case PH_FRINFC_TOPAZ_LOCK_CTRL_T:
3968 expected_seq = LOCK_L_TLV;
3969 parse_index = (parse_index + 1);
3973 case PH_FRINFC_TOPAZ_NULL_T:
3975 expected_seq = LOCK_T_TLV;
3976 parse_index = (parse_index + 1);
3982 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3983 NFCSTATUS_NO_NDEF_SUPPORT);
3989 *seq_to_execute = expected_seq;
3990 *p_parse_index = parse_index;
3996 phFriNfc_Tpz_H_ParseMemTLVType (
3997 phFriNfc_NdefMap_t *psNdefMap,
3998 uint8_t *p_parse_data,
3999 uint16_t *p_parse_index,
4000 uint16_t total_len_to_parse,
4001 phFriNfc_Tpz_ParseSeq_t *seq_to_execute)
4003 NFCSTATUS result = NFCSTATUS_SUCCESS;
4004 uint16_t parse_index = *p_parse_index;
4005 phFriNfc_Tpz_ParseSeq_t expected_seq = *seq_to_execute;
4007 PHNFC_UNUSED_VARIABLE(psNdefMap);
4008 PHNFC_UNUSED_VARIABLE(total_len_to_parse);
4010 switch (p_parse_data[parse_index])
4012 case PH_FRINFC_TOPAZ_LOCK_CTRL_T:
4014 expected_seq = LOCK_L_TLV;
4015 parse_index = (parse_index + 1);
4019 case PH_FRINFC_TOPAZ_NULL_T:
4021 expected_seq = MEM_T_TLV;
4022 parse_index = (parse_index + 1);
4026 case PH_FRINFC_TOPAZ_MEM_CTRL_T:
4028 expected_seq = MEM_L_TLV;
4029 parse_index = (parse_index + 1);
4035 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4036 NFCSTATUS_NO_NDEF_SUPPORT);
4041 *seq_to_execute = expected_seq;
4042 *p_parse_index = parse_index;
4048 phFriNfc_Tpz_H_ParseNdefTLVType (
4049 phFriNfc_NdefMap_t *psNdefMap,
4050 uint8_t *p_parse_data,
4051 uint16_t *p_parse_index,
4052 uint16_t total_len_to_parse,
4053 phFriNfc_Tpz_ParseSeq_t *seq_to_execute)
4055 NFCSTATUS result = NFCSTATUS_SUCCESS;
4056 uint16_t parse_index = *p_parse_index;
4057 phFriNfc_Tpz_ParseSeq_t expected_seq = *seq_to_execute;
4059 PHNFC_UNUSED_VARIABLE(psNdefMap);
4060 PHNFC_UNUSED_VARIABLE(total_len_to_parse);
4062 switch (p_parse_data[parse_index])
4064 case PH_FRINFC_TOPAZ_MEM_CTRL_T:
4066 /* TYPE field of Memory control TLV is found.
4067 This means that more than one memory control
4069 expected_seq = MEM_L_TLV;
4070 parse_index = (parse_index + 1);
4074 case PH_FRINFC_TOPAZ_NULL_T:
4076 /* Skip the NULL TLV */
4077 expected_seq = NDEF_T_TLV;
4078 parse_index = (parse_index + 1);
4082 case PH_FRINFC_TOPAZ_NDEF_T:
4084 /* TYPE field of NDEF TLV found, so next expected
4085 sequence is LENGTH field */
4086 expected_seq = NDEF_L_TLV;
4087 parse_index = (parse_index + 1);
4093 /* Reset the sequence */
4094 expected_seq = LOCK_T_TLV;
4095 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4096 NFCSTATUS_NO_NDEF_SUPPORT);
4101 *seq_to_execute = expected_seq;
4102 *p_parse_index = parse_index;
4108 phFriNfc_Tpz_H_GetSkipSize (
4109 phFriNfc_NdefMap_t *psNdefMap,
4110 uint16_t byte_adr_card)
4112 uint16_t return_size = 0;
4113 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
4114 phFriNfc_ResMemCntrlTLVCont_t *ps_memtlv_info = NULL;
4116 ps_locktlv_info = &(psNdefMap->LockTlv);
4117 ps_memtlv_info = &(psNdefMap->MemTlv);
4119 /* If there are more than one LOCK CONTROL TLV, then
4120 ADD A LOOP HERE OF THE NUMBER OF TLVs FOUND */
4121 if (byte_adr_card == ps_locktlv_info->ByteAddr)
4123 return_size = ps_locktlv_info->Size;
4126 /* If there are more than one MEMORY CONTROL TLV, then
4127 ADD A LOOP HERE OF THE NUMBER OF TLVs FOUND */
4128 if (byte_adr_card == ps_memtlv_info->ByteAddr)
4130 return_size = ps_memtlv_info->Size;
4137 phFriNfc_Tpz_H_GetLockBytesInfo (
4138 phFriNfc_NdefMap_t *psNdefMap,
4139 uint8_t *p_lock_info)
4141 NFCSTATUS result = NFCSTATUS_SUCCESS;
4142 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
4143 uint8_t page_address = 0;
4144 uint8_t bytes_offset = 0;
4145 uint8_t lock_index = 0;
4147 ps_locktlv_info = &(psNdefMap->LockTlv);
4149 page_address = (uint8_t)(p_lock_info[lock_index] >> NIBBLE_SIZE);
4150 bytes_offset = (uint8_t)(p_lock_info[lock_index] & TOPAZ_NIBBLE_MASK);
4152 lock_index = (lock_index + 1);
4153 ps_locktlv_info->Size = (uint16_t)
4154 (((p_lock_info[lock_index] % TOPAZ_BYTE_SIZE_IN_BITS) > 0)?
4155 ((p_lock_info[lock_index] / TOPAZ_BYTE_SIZE_IN_BITS) + 1) :
4156 (p_lock_info[lock_index] / TOPAZ_BYTE_SIZE_IN_BITS));
4158 lock_index = (lock_index + 1);
4159 ps_locktlv_info->BytesPerPage =
4160 (p_lock_info[lock_index] & TOPAZ_NIBBLE_MASK);
4161 ps_locktlv_info->BytesLockedPerLockBit =
4162 (p_lock_info[lock_index] >> NIBBLE_SIZE);
4164 /* Apply the formula to calculate byte address
4165 ByteAddr = PageAddr*2^BytesPerPage + ByteOffset
4167 ps_locktlv_info->ByteAddr = (uint16_t)((page_address
4168 * (1 << ps_locktlv_info->BytesPerPage))
4173 /* Out of bound memory check */
4174 ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) >
4175 (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] *
4176 TOPAZ_BYTES_PER_BLOCK)) ||
4178 /* Check the static lock and reserved areas memory blocks */
4179 ((ps_locktlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) &&
4180 (ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) ||
4181 (((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) >=
4182 TOPAZ_STATIC_LOCK_RES_START) &&
4183 ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) <
4184 TOPAZ_STATIC_LOCK_RES_END))
4187 ps_locktlv_info->ByteAddr = 0;
4188 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4189 NFCSTATUS_NO_NDEF_SUPPORT);
4193 ps_locktlv_info->BlkNum = (ps_locktlv_info->ByteAddr /
4194 TOPAZ_BYTES_PER_BLOCK);
4195 ps_locktlv_info->ByteNum = (ps_locktlv_info->ByteAddr %
4196 TOPAZ_BYTES_PER_BLOCK);
4204 phFriNfc_Tpz_H_GetMemBytesInfo (
4205 phFriNfc_NdefMap_t *psNdefMap,
4206 uint8_t *p_mem_info)
4208 NFCSTATUS result = NFCSTATUS_SUCCESS;
4209 phFriNfc_ResMemCntrlTLVCont_t *ps_memtlv_info = NULL;
4210 phFriNfc_LockCntrlTLVCont_t *ps_locktlv_info = NULL;
4211 uint8_t page_address = 0;
4212 uint8_t bytes_offset = 0;
4213 uint8_t mem_index = 0;
4215 ps_memtlv_info = &(psNdefMap->MemTlv);
4216 ps_locktlv_info = &(psNdefMap->LockTlv);
4217 page_address = (uint8_t)(p_mem_info[mem_index] >> NIBBLE_SIZE);
4218 bytes_offset = (uint8_t)(p_mem_info[mem_index] & TOPAZ_NIBBLE_MASK);
4220 mem_index = (mem_index + 1);
4221 ps_memtlv_info->Size = (uint16_t)p_mem_info[mem_index];
4223 mem_index = (mem_index + 1);
4224 ps_memtlv_info->BytesPerPage =
4225 (p_mem_info[mem_index] & TOPAZ_NIBBLE_MASK);
4227 /* Apply the formula to calculate byte address
4228 ByteAddr = PageAddr * 2^BytesPerPage + ByteOffset
4230 ps_memtlv_info->ByteAddr = (uint16_t)((page_address
4231 * (1 << ps_memtlv_info->BytesPerPage))
4236 /* Check if the lock and memory bytes are overlapped */
4237 ((ps_memtlv_info->ByteAddr >= ps_locktlv_info->ByteAddr) &&
4238 (ps_memtlv_info->ByteAddr <=
4239 (ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1))) ||
4241 (((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) >=
4242 ps_locktlv_info->ByteAddr) &&
4243 ((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) <=
4244 (ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1))) ||
4246 /* Check the static lock and reserved areas memory blocks */
4247 ((ps_memtlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) &&
4248 (ps_memtlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) ||
4249 (((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) >=
4250 TOPAZ_STATIC_LOCK_RES_START) &&
4251 ((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) <
4252 TOPAZ_STATIC_LOCK_RES_END)) ||
4254 /* Check if the memory address is out bound */
4255 ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) >
4256 (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] *
4257 TOPAZ_BYTES_PER_BLOCK))
4260 ps_memtlv_info->ByteAddr = 0;
4261 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4262 NFCSTATUS_NO_NDEF_SUPPORT);
4266 ps_memtlv_info->BlkNum = (ps_memtlv_info->ByteAddr /
4267 TOPAZ_BYTES_PER_BLOCK);
4268 ps_memtlv_info->ByteNum = (ps_memtlv_info->ByteAddr %
4269 TOPAZ_BYTES_PER_BLOCK);
4276 #include <phUnitTestNfc_TopazDynamic_static.c>
4279 #endif /*#if !(defined(PH_FRINFC_MAP_TOPAZ_DISABLED ) || defined (PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED ))*/