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_TopazMap.c
19 * \brief NFC Ndef Mapping For Remote Devices.
23 * $Date: Mon Dec 13 14:14:14 2010 $
32 #include <phFriNfc_NdefMap.h>
33 #include <phFriNfc_TopazMap.h>
34 #include <phFriNfc_MapTools.h>
35 #include <phFriNfc_OvrHal.h>
37 #ifndef PH_FRINFC_MAP_TOPAZ_DISABLED
38 /*! \ingroup grp_file_attributes
41 * File: \ref phFriNfcNdefMap.c
45 #define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.23 $"
46 #define PHFRINFCTOPAZMAP_FILEALIASES "$Aliases: $"
48 /****************** Start of macros ********************/
49 /* Below MACRO is used for the WRITE error scenario,
50 in case PN544 returns error for any WRITE, then
51 read the written block and byte number, to check the data
52 written to the card is correct or not
54 /* #define TOPAZ_RF_ERROR_WORKAROUND */
56 #ifdef FRINFC_READONLY_NDEF
58 #define CC_BLOCK_NUMBER (0x01U)
59 #define LOCK_BLOCK_NUMBER (0x0EU)
61 #define LOCK0_BYTE_NUMBER (0x00U)
62 #define LOCK0_BYTE_VALUE (0xFFU)
64 #define LOCK1_BYTE_NUMBER (0x01U)
65 #define LOCK1_BYTE_VALUE (0x7FU)
67 #define CC_RWA_BYTE_NUMBER (0x03U)
68 #define CC_READ_ONLY_VALUE (0x0FU)
70 #endif /* #ifdef FRINFC_READONLY_NDEF */
72 #ifdef TOPAZ_RF_ERROR_WORKAROUND
74 /* Below MACROs are added for the error returned from HAL, if the
75 below error has occured during the WRITE, then read the error
76 returned blocks to confirm */
77 #define FRINFC_RF_TIMEOUT_89 (0x89U)
78 #define FRINFC_RF_TIMEOUT_90 (0x90U)
80 /* State specific to read after the RF ERROR for the WRITE */
81 #define PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ (0x0FU)
83 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
85 /****************** End of macros ********************/
88 * \name Topaz Mapping - Helper Functions
94 * \brief \copydoc page_ovr Helper function for Topaz. This function shall read 8 bytes
97 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,
102 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
105 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap);
108 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
111 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap);
114 * \brief \copydoc page_ovr Helper function for Topaz. This function depends on
115 * function called by the user
117 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap);
120 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC
123 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap);
126 * \brief \copydoc page_ovr Helper function for Topaz. This function finds
129 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap);
132 * \brief \copydoc page_ovr Helper function for Topaz. This function writes a
135 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,
142 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the
145 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap);
148 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the length field of
151 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap);
154 * \brief \copydoc page_ovr Helper function for Topaz. This function updates length field
155 * of the NDEF TLV after complete write.
157 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t *NdefMap);
160 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the card data
163 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf( phFriNfc_NdefMap_t *NdefMap);
166 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the
169 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData( phFriNfc_NdefMap_t *NdefMap);
172 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the block
173 * number is correct or not
175 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t *NdefMap);
178 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the 0th
179 * byte of block 1 has Zero
181 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t *NdefMap);
184 * \brief \copydoc page_ovr Helper function for Topaz. This function calls the
187 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t *NdefMap,
191 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
192 * the CC byte in check ndef function
194 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t *NdefMap);
197 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
198 * the lock bits and set a card state
200 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t *NdefMap);
203 * \brief \copydoc page_ovr Helper function for Topaz. This function writes CC bytes or
206 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t *NdefMap);
208 #ifdef TOPAZ_RF_ERROR_WORKAROUND
211 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written
216 phFriNfc_Tpz_H_CheckWrittenData (
217 phFriNfc_NdefMap_t *psNdefMap,
218 uint8_t state_rf_error);
220 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
223 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written
224 * CC bytes are correct
226 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t *NdefMap);
228 void phFriNfc_TopazMap_H_Reset(phFriNfc_NdefMap_t *NdefMap)
230 /* Initialising the Topaz structure variable */
231 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_INVALID_OPE;
232 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
233 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
234 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_VAL0;
235 (void)memset(NdefMap->TopazContainer.ReadBuffer, PH_FRINFC_TOPAZ_VAL0,
236 sizeof(NdefMap->TopazContainer.ReadBuffer));
237 NdefMap->TopazContainer.ReadWriteCompleteFlag = PH_FRINFC_TOPAZ_FLAG0;
238 NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_VAL0;
239 (void)memset(NdefMap->TopazContainer.UID, PH_FRINFC_TOPAZ_VAL0,
240 sizeof(NdefMap->TopazContainer.UID));
241 NdefMap->TopazContainer.Cur_RW_Index=0;
242 NdefMap->TopazContainer.ByteRWFrmCard =0;
246 * \brief Check whether a particular Remote Device is NDEF compliant.
248 * The function checks whether the peer device is NDEF compliant.
250 * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t
251 * structure describing the component context.
253 * \retval NFCSTATUS_PENDING The action has been successfully triggered.
254 * \retval Others An error has occurred.
258 NFCSTATUS phFriNfc_TopazMap_ChkNdef( phFriNfc_NdefMap_t *NdefMap)
260 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
261 NFCSTATUS_INVALID_PARAMETER);
262 if ( NdefMap != NULL)
264 /* Update the previous operation */
265 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
266 /* Update the CR index to know from which operation completion
267 routine has to be called */
268 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
269 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
270 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
273 NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_CARD;
275 /* Change the state to Check Ndef Compliant */
276 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID;
277 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
279 #ifdef TOPAZ_RAW_SUPPORT
280 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
281 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID;
283 #ifdef PH_HAL4_ENABLE
284 NdefMap->Cmd.JewelCmd = phHal_eJewel_RID;
286 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid;
288 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
290 Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
291 NdefMap->TopazContainer.ByteNumber);
296 #ifdef FRINFC_READONLY_NDEF
299 phFriNfc_TopazMap_ConvertToReadOnly (
300 phFriNfc_NdefMap_t *NdefMap)
302 NFCSTATUS result = NFCSTATUS_SUCCESS;
304 result = phFriNfc_Tpz_H_WrAByte (NdefMap, CC_BLOCK_NUMBER,
305 CC_RWA_BYTE_NUMBER, CC_READ_ONLY_VALUE);
307 if (NFCSTATUS_PENDING == PHNFCSTATUS(result))
309 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE;
314 #endif /* #ifdef FRINFC_READONLY_NDEF */
317 * \brief Initiates Reading of NDEF information from the Remote Device.
319 * The function initiates the reading of NDEF information from a Remote Device.
320 * It performs a reset of the state and starts the action (state machine).
321 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
322 * has been triggered.
324 NFCSTATUS phFriNfc_TopazMap_RdNdef( phFriNfc_NdefMap_t *NdefMap,
326 uint32_t *PacketDataLength,
329 NFCSTATUS Result = NFCSTATUS_SUCCESS;
331 /* Copy user buffer to the context */
332 NdefMap->ApduBuffer = PacketData;
333 /* Copy user length to the context */
334 NdefMap->ApduBufferSize = *PacketDataLength;
335 /* Update the user memory size to a context variable */
336 NdefMap->NumOfBytesRead = PacketDataLength;
337 /* Number of bytes read from the card is zero.
338 This variable returns the number of bytes read
340 *NdefMap->NumOfBytesRead = PH_FRINFC_TOPAZ_VAL0;
341 /* Index to know the length read */
342 NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;
343 /* Store the offset in the context */
344 NdefMap->Offset = Offset;
345 /* Update the CR index to know from which operation completion
346 routine has to be called */
347 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
349 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation ==
350 PH_FRINFC_NDEFMAP_WRITE_OPE))
352 /* If previous operation is not read then the read shall
354 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
355 /* Initialise current block and byte number */
356 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
357 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
358 /* State has to be changed */
359 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;
360 NdefMap->TopazContainer.ReadWriteCompleteFlag =
361 PH_FRINFC_TOPAZ_FLAG0;
362 /* Topaz command = READALL */
363 #ifdef TOPAZ_RAW_SUPPORT
364 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
365 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
368 #ifdef PH_HAL4_ENABLE
369 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
371 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
374 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
377 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
378 /* Offset = Current, but the read has reached the End of Card */
379 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
380 (NdefMap->TopazContainer.ReadWriteCompleteFlag ==
381 PH_FRINFC_TOPAZ_FLAG1))
383 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
384 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
388 /* if the offset is begin then call READALL else copy the data
389 from the user buffer */
390 Result = ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
391 phFriNfc_Tpz_H_RdBytes(NdefMap,
392 NdefMap->TopazContainer.CurrentBlock,
393 NdefMap->TopazContainer.ByteNumber):
394 phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap));
401 * \brief Initiates Writing of NDEF information to the Remote Device.
403 * The function initiates the writing of NDEF information to a Remote Device.
404 * It performs a reset of the state and starts the action (state machine).
405 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
406 * has been triggered.
408 NFCSTATUS phFriNfc_TopazMap_WrNdef( phFriNfc_NdefMap_t *NdefMap,
410 uint32_t *PacketDataLength,
413 NFCSTATUS Result = NFCSTATUS_SUCCESS;
414 uint8_t TempByteVal = 0;
415 /* Copy user buffer to the context */
416 NdefMap->ApduBuffer = PacketData;
417 /* Copy user length to the context */
418 NdefMap->ApduBufferSize = *PacketDataLength;
419 /* Index to know the length written */
420 NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;
421 /* Update the user memory size to a context variable */
422 NdefMap->WrNdefPacketLength = PacketDataLength;
423 /* Number of bytes written to the card is zero.
424 This variable returns the number of bytes written
426 *NdefMap->WrNdefPacketLength = PH_FRINFC_TOPAZ_VAL0;
427 /* Update the CR index to know from which operation completion
428 routine has to be called */
429 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
430 /* Store the offset in the context */
431 NdefMap->Offset = Offset;
434 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
435 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))
437 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
438 /* Initialise current block and byte number */
439 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
440 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
441 /* State has to be changed */
442 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;
443 /* Topaz command = READALL */
445 #ifdef TOPAZ_RAW_SUPPORT
446 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
447 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
449 #ifdef PH_HAL4_ENABLE
450 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
452 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
454 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
455 NdefMap->TopazContainer.ReadWriteCompleteFlag =
456 PH_FRINFC_TOPAZ_FLAG0;
457 NdefMap->TopazContainer.RemainingSize = NdefMap->CardMemSize;
458 TempByteVal = NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1];
462 /* State has to be changed */
463 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
464 /* copy the user data to write into the card */
465 TempByteVal = NdefMap->ApduBuffer[NdefMap->ApduBuffIndex];
468 /* Update the previous operation to write operation */
469 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
470 if((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
471 (NdefMap->TopazContainer.ReadWriteCompleteFlag ==
472 PH_FRINFC_TOPAZ_FLAG1))
474 /* Offset = Current, but the read has reached the End of Card */
475 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
476 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
480 /* Check the block */
481 phFriNfc_Tpz_H_BlkChk(NdefMap);
482 /* if offset is begin then call READALL else start writing */
483 Result = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
484 phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
485 NdefMap->TopazContainer.ByteNumber):
486 phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock,
487 NdefMap->TopazContainer.ByteNumber,TempByteVal));
495 * \brief Completion Routine, Processing function, needed to avoid long blocking.
496 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
497 * Routine in order to be able to notify the component that an I/O has finished and data are
498 * ready to be processed.
502 void phFriNfc_TopazMap_Process( void *Context,
506 phFriNfc_NdefMap_t *psNdefMap = NULL;
508 #ifdef TOPAZ_RF_ERROR_WORKAROUND
510 static uint8_t rf_error_state = 0;
512 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
513 #ifdef FRINFC_READONLY_NDEF
514 static uint8_t written_lock_byte = 0;
515 #endif /* #ifdef FRINFC_READONLY_NDEF */
517 psNdefMap = (phFriNfc_NdefMap_t *)Context;
519 if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER))
521 switch (psNdefMap->State)
523 #ifdef FRINFC_READONLY_NDEF
524 case PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE:
526 if((CC_READ_ONLY_VALUE == *psNdefMap->SendRecvBuf)
527 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
529 written_lock_byte = 0;
530 #ifdef TOPAZ_RAW_SUPPORT
531 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
533 #ifdef PH_HAL4_ENABLE
534 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
536 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;
537 #endif /* #ifdef PH_HAL4_ENABLE */
538 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
539 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER,
542 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
544 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE;
549 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
550 NFCSTATUS_INVALID_RECEIVE_LENGTH);
555 case PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE:
557 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)
559 Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER,
563 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
565 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE;
571 case PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE:
573 if((LOCK0_BYTE_VALUE == *psNdefMap->SendRecvBuf)
574 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
576 #ifdef TOPAZ_RAW_SUPPORT
577 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
579 #ifdef PH_HAL4_ENABLE
580 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
582 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;
583 #endif /* #ifdef PH_HAL4_ENABLE */
584 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
585 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER,
588 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
590 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE;
595 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
596 NFCSTATUS_INVALID_RECEIVE_LENGTH);
600 case PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE:
602 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)
604 written_lock_byte = (uint8_t)(*psNdefMap->SendRecvBuf | LOCK1_BYTE_VALUE);
605 Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER,
609 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
611 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE;
617 case PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE:
619 if((written_lock_byte == *psNdefMap->SendRecvBuf)
620 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
622 written_lock_byte = 0;
627 written_lock_byte = 0;
628 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
629 NFCSTATUS_INVALID_RECEIVE_LENGTH);
632 #endif /* #ifdef FRINFC_READONLY_NDEF */
633 case PH_FRINFC_TOPAZ_STATE_WRITE:
635 Status = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);
639 case PH_FRINFC_TOPAZ_STATE_READID:
641 Status = phFriNfc_Tpz_H_ProReadID (psNdefMap);
645 case PH_FRINFC_TOPAZ_STATE_READALL:
647 Status = phFriNfc_Tpz_H_ProReadAll (psNdefMap);
651 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
653 Status = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);
657 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
659 Status = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);
663 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
665 Status = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);
669 #ifdef TOPAZ_RF_ERROR_WORKAROUND
671 case PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ:
673 Status = phFriNfc_Tpz_H_CheckWrittenData (psNdefMap,
678 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
682 Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP,
683 NFCSTATUS_INVALID_DEVICE_REQUEST);
690 #ifdef TOPAZ_RF_ERROR_WORKAROUND
692 if ((FRINFC_RF_TIMEOUT_89 == PHNFCSTATUS (Status)) ||
693 (FRINFC_RF_TIMEOUT_90 == PHNFCSTATUS (Status)) ||
694 (NFCSTATUS_RF_TIMEOUT == PHNFCSTATUS (Status)))
696 uint8_t byte_number = 0;
697 uint8_t block_number = 0;
699 rf_error_state = psNdefMap->State;
701 #ifdef TOPAZ_RAW_SUPPORT
703 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
707 #ifdef PH_HAL4_ENABLE
709 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
713 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;
715 #endif /* #ifdef PH_HAL4_ENABLE */
717 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
719 /* Update the state variable to the new work around state*/
720 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ;
722 /* Switch is used to know, if the error occured during WRITE or READ */
723 switch (rf_error_state)
725 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
727 /* Block and byte number is updated for NMN */
728 byte_number = PH_FRINFC_TOPAZ_VAL0;
729 block_number = PH_FRINFC_TOPAZ_VAL1;
733 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
735 /* Get the L field of the TLV block */
736 block_number = (uint8_t)(((psNdefMap->TLVStruct.NdefTLVByte +
737 PH_FRINFC_TOPAZ_VAL1) >
738 PH_FRINFC_TOPAZ_VAL7)?
739 (psNdefMap->TLVStruct.NdefTLVBlock +
740 PH_FRINFC_TOPAZ_VAL1):
741 psNdefMap->TLVStruct.NdefTLVBlock);
743 byte_number = (uint8_t)((psNdefMap->TLVStruct.NdefTLVByte +
744 PH_FRINFC_TOPAZ_VAL1) %
745 PH_FRINFC_TOPAZ_VAL8);
749 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
751 switch (psNdefMap->TopazContainer.InternalState)
753 case PH_FRINFC_TOPAZ_WR_CC_BYTE0:
755 /* Block and byte number is updated for the CC byte 0 */
756 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
757 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL0;
761 case PH_FRINFC_TOPAZ_WR_CC_BYTE1:
763 /* Block and byte number is updated for the CC byte 1 */
764 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
765 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
769 case PH_FRINFC_TOPAZ_WR_CC_BYTE2:
771 /* Block and byte number is updated for the CC byte 2 */
772 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
773 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL2;
777 case PH_FRINFC_TOPAZ_WR_CC_BYTE3:
779 /* Block and byte number is updated for the CC byte 3 */
780 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
781 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL3;
785 case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
787 /* Block and byte number is updated for the Type field of the TLV */
788 block_number = psNdefMap->TLVStruct.NdefTLVBlock;
789 byte_number = (uint8_t)psNdefMap->TLVStruct.NdefTLVByte;
798 } /* switch (psNdefMap->TopazContainer.InternalState) */
802 case PH_FRINFC_TOPAZ_STATE_WRITE:
804 /* Block and byte number is updated for the written error data */
805 block_number = psNdefMap->TopazContainer.CurrentBlock;
806 byte_number = psNdefMap->TopazContainer.ByteNumber;
812 /* Error occured is not during WRITE, so update
813 state variable to the previous state */
814 psNdefMap->State = rf_error_state;
817 } /* switch (rf_error_state) */
819 /* The below check is added, to know if the error is for
820 the WRITE or READ scenario,
821 If the error is for READ, then state variable is not updated
822 If the error is for WRITE, then state variable is updated with
823 PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ value */
824 if (PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ == psNdefMap->State)
826 /* Read the data with the updated block and byte number */
827 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, block_number,
832 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
835 /* Call Completion Routine, if Status != PENDING */
836 if (NFCSTATUS_PENDING != Status)
838 phFriNfc_Tpz_H_Complete(psNdefMap, Status);
843 #ifdef TOPAZ_RF_ERROR_WORKAROUND
847 phFriNfc_Tpz_H_CheckWrittenData (
848 phFriNfc_NdefMap_t *psNdefMap,
849 uint8_t state_rf_error)
851 NFCSTATUS result = NFCSTATUS_SUCCESS;
853 switch (state_rf_error)
855 case PH_FRINFC_TOPAZ_STATE_WRITE:
857 result = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);
861 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
863 result = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);
867 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
869 result = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);
873 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
875 result = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);
889 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
891 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,
895 NFCSTATUS Result = NFCSTATUS_SUCCESS;
896 #ifdef TOPAZ_RAW_SUPPORT
898 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
900 /* set the data for additional data exchange*/
901 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
902 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
903 NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
905 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;
906 NdefMap->MapCompletionInfo.Context = NdefMap;
908 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
910 /* Depending on the jewel command, the send length is decided */
911 #ifdef TOPAZ_RAW_SUPPORT
912 switch(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0])
914 switch(NdefMap->Cmd.JewelCmd)
915 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
918 #ifdef TOPAZ_RAW_SUPPORT
919 case PH_FRINFC_TOPAZ_CMD_READID:
921 #ifdef PH_HAL4_ENABLE
922 case phHal_eJewel_RID:
924 case phHal_eJewelCmdListJewelRid:
926 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
928 #ifdef TOPAZ_RAW_SUPPORT
929 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
930 /*Copy command to Send Buffer*/
931 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID;
934 /*Copy UID of the tag to Send Buffer*/
935 (void)memset(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1]),
937 index = index + 0x06;
939 /* Update the length of the command buffer*/
940 NdefMap->SendLength = index;
942 /* For READ ID and READ ALL, send length is 0 */
943 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
944 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
947 #ifdef TOPAZ_RAW_SUPPORT
948 case PH_FRINFC_TOPAZ_CMD_READALL:
950 #ifdef PH_HAL4_ENABLE
951 case phHal_eJewel_ReadAll:
953 case phHal_eJewelCmdListJewelReadAll:
955 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
957 #ifdef TOPAZ_RAW_SUPPORT
958 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
959 /*Copy command to Send Buffer*/
960 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
963 /*Copy 0x00 to Send Buffer*/
964 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00;
966 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;
969 /*Copy UID of the tag to Send Buffer*/
970 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),
971 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),
972 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
974 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
976 /* Update the length of the command buffer*/
977 NdefMap->SendLength = index;
979 /* For READ ID and READ ALL, send length is 0 */
980 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
981 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
984 #ifdef TOPAZ_RAW_SUPPORT
985 case PH_FRINFC_TOPAZ_CMD_READ:
987 #ifdef PH_HAL4_ENABLE
988 case phHal_eJewel_Read1:
990 case phHal_eJewelCmdListJewelRead1:
993 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
995 #ifdef TOPAZ_RAW_SUPPORT
996 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
997 /*Copy command to Send Buffer*/
998 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READ;
1001 /*Copy Address to Send Buffer*/
1002 /* Calculate send length
1003 7 | 6 5 4 3 | 2 1 0 |
1004 | block no | byte no |
1006 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] =
1007 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1010 /*Copy 0x00 to Send Buffer*/
1011 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;
1014 /*Copy UID of the tag to Send Buffer*/
1015 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),
1016 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),
1017 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1018 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1020 /* Update the length of the command buffer*/
1021 NdefMap->SendLength = index;
1023 /* Calculate send length
1024 7 | 6 5 4 3 | 2 1 0 |
1025 | block no | byte no |
1027 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] =
1028 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1030 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL1;
1031 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1034 #ifdef TOPAZ_RAW_SUPPORT
1036 #ifdef PH_HAL4_ENABLE
1037 case phHal_eJewel_Read:
1038 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = 0x00;
1039 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00;
1040 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 104;
1041 NdefMap->SendLength = 3;
1044 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1047 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1048 NFCSTATUS_INVALID_DEVICE_REQUEST);
1051 if(Result == NFCSTATUS_SUCCESS)
1053 /* Call the Overlapped HAL Transceive function */
1054 Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1055 &NdefMap->MapCompletionInfo,
1056 NdefMap->psRemoteDevInfo,
1058 &NdefMap->psDepAdditionalInfo,
1059 NdefMap->SendRecvBuf,
1060 NdefMap->SendLength,
1061 NdefMap->SendRecvBuf,
1062 NdefMap->SendRecvLength);
1067 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,
1073 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1077 PHNFC_UNUSED_VARIABLE(ByteVal);
1078 /* set the data for additional data exchange*/
1079 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
1080 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
1081 NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
1083 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;
1084 NdefMap->MapCompletionInfo.Context = NdefMap;
1086 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1087 /* Command used to write 1 byte */
1088 #ifdef TOPAZ_RAW_SUPPORT
1089 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1091 #ifdef PH_HAL4_ENABLE
1092 NdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1094 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelWriteErase1;
1096 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1098 #ifdef TOPAZ_RAW_SUPPORT
1099 /*Copy command to Send Buffer*/
1100 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1103 /*Copy Address to Send Buffer*/
1104 /* Calculate send length
1105 7 | 6 5 4 3 | 2 1 0 |
1106 | block no | byte no |
1108 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] =
1109 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1112 /*Copy Data byte to Send Buffer*/
1113 NdefMap->SendRecvBuf[index] = ByteVal;
1116 /*Copy UID of the tag to Send Buffer*/
1117 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),
1118 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),
1119 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1120 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1122 /* Update the length of the command buffer*/
1123 NdefMap->SendLength = index;
1126 /* Depending on the jewel command, the send length is decided */
1127 /* Calculate send length
1128 7 | 6 5 4 3 | 2 1 0 |
1129 | block no | byte no |
1131 NdefMap->SendRecvBuf[index] =
1132 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1135 NdefMap->SendRecvBuf[index] = ByteVal;
1137 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL2;
1139 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1141 /* Call the Overlapped HAL Transceive function */
1142 Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1143 &NdefMap->MapCompletionInfo,
1144 NdefMap->psRemoteDevInfo,
1146 &NdefMap->psDepAdditionalInfo,
1147 NdefMap->SendRecvBuf,
1148 NdefMap->SendLength,
1149 NdefMap->SendRecvBuf,
1150 NdefMap->SendRecvLength);
1155 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap)
1157 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1158 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1160 if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] &
1161 PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) &&
1162 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL6))
1164 /* Copy UID to the context, Used when the READ ALL command is used */
1165 (void)memcpy(NdefMap->TopazContainer.UID,
1166 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
1167 PH_FRINFC_TOPAZ_VAL4);
1169 /* State has to be changed */
1170 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;
1171 /* Topaz command = READALL */
1172 #ifdef TOPAZ_RAW_SUPPORT
1173 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1174 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
1176 #ifdef PH_HAL4_ENABLE
1177 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
1179 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
1181 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1183 /* Read all bytes from the card */
1184 Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
1185 NdefMap->TopazContainer.ByteNumber);
1191 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap)
1193 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1194 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1195 int32_t memcompare = PH_FRINFC_TOPAZ_VAL0;
1197 /* Compare the UID of READ ALL command with the stored UID */
1198 #ifdef PH_HAL4_ENABLE
1199 if ((NdefMap->TopazContainer.UID[0] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2]) &&
1200 (NdefMap->TopazContainer.UID[1] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 1]) &&
1201 (NdefMap->TopazContainer.UID[2] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 2]) &&
1202 (NdefMap->TopazContainer.UID[3] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 3]))
1204 memcompare = PH_FRINFC_TOPAZ_VAL0;
1208 memcompare = PH_FRINFC_TOPAZ_VAL1;
1211 memcompare = memcmp(NdefMap->TopazContainer.UID,
1212 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
1213 PH_FRINFC_TOPAZ_VAL4);
1214 #endif /* #ifdef PH_HAL4_ENABLE */
1216 if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] &
1217 PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) &&
1218 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_READALL_RESP) &&
1219 (memcompare == PH_FRINFC_TOPAZ_VAL0))
1221 /* Copy 96 bytes from the read/write memory space */
1222 (void)memcpy(NdefMap->TopazContainer.ReadBuffer,
1223 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL10],
1224 PH_FRINFC_TOPAZ_TOTAL_RWBYTES);
1226 /* Check the lock bits and set the card state */
1227 phFriNfc_Tpz_H_ChkLockBits(NdefMap);
1229 Result = phFriNfc_Tpz_H_CallNxtOp(NdefMap);
1234 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap)
1236 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1237 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1238 /* Depending on the operation (check, read or write ndef), process the
1240 switch(NdefMap->PrevOperation)
1242 case PH_FRINFC_NDEFMAP_CHECK_OPE:
1243 /* Check the capabilty container values, according
1245 Result = phFriNfc_Tpz_H_ChkCCinChkNdef(NdefMap);
1247 if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INVALID)
1249 /* Check the spec version */
1250 Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap,
1251 NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]);
1252 /* Check the CC header size: Only valid ones are
1253 0x0C for 96 bytes. */
1254 if ((Result == NFCSTATUS_SUCCESS) &&
1255 ( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] <=
1256 PH_FRINFC_TOPAZ_CC_BYTE2_MAX))
1258 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap);
1259 /* As there is possibility of either having or not having TLV in
1260 Topaz, no need to send the Actual status to the context*/
1261 Result = NFCSTATUS_SUCCESS;
1266 Result = NFCSTATUS_SUCCESS;
1267 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
1268 NdefMap->CardMemSize =
1269 NdefMap->TopazContainer.RemainingSize = (uint16_t)
1271 4 is decremented from the max size because of the 4 CC bytes
1272 2 is decremented because of the NDEF TLV T and L byte
1273 to get the actual data size
1275 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4 -
1276 PH_FRINFC_TOPAZ_VAL2);
1280 case PH_FRINFC_NDEFMAP_READ_OPE:
1281 /* Check the capabilty container values, according
1283 Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);
1285 /* If success, find the ndef TLV */
1286 Result = ((Result != NFCSTATUS_SUCCESS)?
1287 (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1288 NFCSTATUS_INVALID_FORMAT)):
1289 phFriNfc_Tpz_H_findNDEFTLV(NdefMap));
1291 if(Result == NFCSTATUS_SUCCESS)
1293 NdefMap->TopazContainer.ByteNumber += PH_FRINFC_TOPAZ_VAL2;
1294 /* If success, copy the read bytes to the user buffer */
1295 Result = phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap);
1299 case PH_FRINFC_NDEFMAP_WRITE_OPE:
1301 if((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE) ||
1302 (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED))
1304 /* Check the capabilty container values, according
1306 Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);
1307 if(Result == NFCSTATUS_SUCCESS)
1309 /* Find the NDEF TLV */
1310 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap);
1313 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;
1317 NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4;
1318 NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1;
1319 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4;
1321 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE0;
1323 /* Write CC bytes */
1324 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1331 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap)
1333 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1334 NFCSTATUS_NO_NDEF_SUPPORT);
1336 if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] ==
1337 PH_FRINFC_TOPAZ_CC_BYTE0)
1339 /* Check the spec version */
1340 Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap,
1341 NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]);
1342 /* Check the CC header size: Only valid ones are
1343 0x0C for 96 bytes. */
1344 Result = ((( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] >
1345 PH_FRINFC_TOPAZ_CC_BYTE2_MAX) || (Result !=
1346 NFCSTATUS_SUCCESS))?
1347 (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1348 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED)):
1351 /* Get the read/write card memory size */
1352 NdefMap->TopazContainer.RemainingSize =
1353 NdefMap->CardMemSize = ((Result == NFCSTATUS_SUCCESS)?
1354 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4):
1355 NdefMap->CardMemSize);
1357 /* if the call is from write ndef then check for read write access */
1358 if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) &&
1359 (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] !=
1360 PH_FRINFC_TOPAZ_CC_BYTE3_RW) && (Result == NFCSTATUS_SUCCESS)))
1362 Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1363 NFCSTATUS_INVALID_FORMAT));
1366 /* if the call is from read ndef then check for read only or read write access */
1367 if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) &&
1368 ((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] !=
1369 PH_FRINFC_TOPAZ_CC_BYTE3_RW) &&
1370 (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] !=
1371 PH_FRINFC_TOPAZ_CC_BYTE3_RO))&& (Result == NFCSTATUS_SUCCESS)))
1373 Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1374 NFCSTATUS_INVALID_FORMAT));
1380 extern NFCSTATUS phFriNfc_Tpz_H_ChkSpcVer( phFriNfc_NdefMap_t *NdefMap,
1383 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1384 uint8_t TagVerNo = VersionNo;
1386 /* To remove "warning (VS C4100) : unreferenced formal parameter" */
1387 PHNFC_UNUSED_VARIABLE(NdefMap);
1389 if ( TagVerNo == 0 )
1391 /*Return Status Error
\93 Invalid Format
\94*/
1392 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
1396 /* calculate the major and minor version number of T3VerNo */
1397 if( (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM ==
1398 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&&
1399 ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM >=
1400 PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo))) ||
1401 (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM ==
1402 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&&
1403 ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM <
1404 PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo) )))
1406 Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
1410 if (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM <
1411 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo) ) ||
1412 ( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM >
1413 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)))
1415 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
1422 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap)
1424 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1425 NFCSTATUS_NO_NDEF_SUPPORT);
1426 uint8_t index = PH_FRINFC_TOPAZ_VAL4;
1428 /* If remaining size is less than 3 then, there cant be any
1429 TLV present in the card */
1430 while((index < PH_FRINFC_TOPAZ_TOTAL_RWBYTES) &&
1431 (NdefMap->TopazContainer.RemainingSize >= PH_FRINFC_TOPAZ_VAL3))
1433 switch(NdefMap->TopazContainer.ReadBuffer[index])
1435 case PH_FRINFC_TOPAZ_NDEF_T:
1436 /* To get the length field of the TLV */
1438 /* Type and length are not data bytes, so to know the exact
1439 remaining size in the card, the below operation is done */
1440 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2;
1441 /* Set the card state depending on the L value */
1442 Result = phFriNfc_MapTool_SetCardState(NdefMap,
1443 (uint32_t)NdefMap->TopazContainer.ReadBuffer[index]);
1444 /* Check the TLV is correct */
1445 if((NdefMap->TopazContainer.ReadBuffer[index] >
1446 NdefMap->TopazContainer.RemainingSize) ||
1447 ((NdefMap->TopazContainer.ReadBuffer[index] ==
1448 PH_FRINFC_TOPAZ_VAL0) && (NdefMap->PrevOperation ==
1449 PH_FRINFC_NDEFMAP_READ_OPE)) || (Result != NFCSTATUS_SUCCESS))
1451 /* L field value cant be greater than the remaining size, so error */
1452 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1453 NFCSTATUS_NO_NDEF_SUPPORT);
1454 /* To break out of the loop */
1455 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1459 /* So remaining size also changes, according to the position of NDEF TLV */
1460 NdefMap->TLVStruct.BytesRemainLinTLV =
1461 NdefMap->TopazContainer.ReadBuffer[index];
1463 /* Get the byte number */
1464 NdefMap->TLVStruct.NdefTLVByte = (uint16_t)((index - PH_FRINFC_TOPAZ_VAL1) %
1465 PH_FRINFC_TOPAZ_VAL8);
1466 /* Get the block number */
1467 NdefMap->TLVStruct.NdefTLVBlock = (uint8_t)(((index - PH_FRINFC_TOPAZ_VAL1) /
1468 PH_FRINFC_TOPAZ_VAL8) +
1469 PH_FRINFC_TOPAZ_VAL1);
1470 /* TLV found flag is set */
1471 NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_TOPAZ_FLAG1;
1472 /* To know the position of V field in the TLV */
1473 NdefMap->TopazContainer.ByteNumber = (uint8_t)(((NdefMap->TLVStruct.NdefTLVBlock - 1) * 8) +
1474 NdefMap->TLVStruct.NdefTLVByte);
1475 /* To break out of the loop */
1476 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1477 Result = NFCSTATUS_SUCCESS;
1481 case PH_FRINFC_TOPAZ_NULL_T:
1482 /* Null TLV, Skip the TLV */
1483 NdefMap->TopazContainer.RemainingSize--;
1487 case PH_FRINFC_TOPAZ_TERM_T:
1488 /* No more TLV present in the card, so error */
1489 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1490 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1491 NFCSTATUS_NO_NDEF_SUPPORT);
1495 /* Go till the length field of the TLV */
1497 /* Type and length is not the data, so to know the exact
1498 remaining size in the card, the below operation is done */
1499 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2;
1500 if(NdefMap->TopazContainer.ReadBuffer[index] >
1501 NdefMap->TopazContainer.RemainingSize)
1503 /* L field value cant be greater than the remaining size, so error */
1504 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1505 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1506 NFCSTATUS_NO_NDEF_SUPPORT);
1510 /* Remaining size of the free space available in the card changes,
1511 according to the position of NDEF TLV */
1512 NdefMap->TopazContainer.RemainingSize =
1513 NdefMap->TopazContainer.RemainingSize -
1514 NdefMap->TopazContainer.ReadBuffer[index];
1516 /* Get the position of the next TLV */
1517 index = (uint8_t)(index +
1518 (NdefMap->TopazContainer.ReadBuffer[index] +
1519 PH_FRINFC_TOPAZ_VAL1));
1525 /* If no Ndef TLV found and operation done is read */
1526 if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) &&
1527 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))
1529 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1530 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
1532 if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) &&
1533 ((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) ||
1534 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_CHECK_OPE)))
1536 NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4;
1537 NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1;
1538 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4;
1539 NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_TOTAL_RWBYTES1;
1544 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf(phFriNfc_NdefMap_t *NdefMap)
1546 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1548 /* Check the the TLV size and the user size */
1549 if(NdefMap->ApduBufferSize >=
1550 NdefMap->TLVStruct.BytesRemainLinTLV)
1552 /* Copy the read bytes to user buffer till the value (V)
1554 (void)memcpy(NdefMap->ApduBuffer,
1555 &(NdefMap->TopazContainer.ReadBuffer[
1556 NdefMap->TopazContainer.ByteNumber]),
1557 NdefMap->TLVStruct.BytesRemainLinTLV);
1559 /* Update the number of read bytes to the user */
1560 *(NdefMap->NumOfBytesRead) =
1561 NdefMap->TLVStruct.BytesRemainLinTLV;
1562 /* There is no byte to read */
1563 NdefMap->TopazContainer.ByteNumber =
1564 PH_FRINFC_TOPAZ_VAL0;
1565 /* No further read is possible */
1566 NdefMap->TopazContainer.ReadWriteCompleteFlag =
1567 PH_FRINFC_TOPAZ_FLAG1;
1568 /* Remaining size in the card can be greater than length field in
1570 NdefMap->TopazContainer.RemainingSize =
1571 NdefMap->TopazContainer.RemainingSize -
1572 NdefMap->TLVStruct.BytesRemainLinTLV;
1573 /* TLV has been completely read, no more bytes to read */
1574 NdefMap->TLVStruct.BytesRemainLinTLV =
1575 PH_FRINFC_TOPAZ_VAL0;
1579 /* Copy read bytes till the user buffer size */
1580 (void)memcpy(NdefMap->ApduBuffer,
1581 &(NdefMap->TopazContainer.ReadBuffer[
1582 NdefMap->TopazContainer.ByteNumber]),
1583 NdefMap->ApduBufferSize);
1585 /* Update the number of read bytes to the user */
1586 *(NdefMap->NumOfBytesRead) =
1587 NdefMap->ApduBufferSize;
1588 /* Get the next byte number to read */
1589 NdefMap->TopazContainer.ByteNumber =
1590 (uint8_t)(NdefMap->TopazContainer.ByteNumber +
1591 NdefMap->ApduBufferSize);
1592 /* Free space left in the card */
1593 NdefMap->TopazContainer.RemainingSize
1594 = NdefMap->TopazContainer.RemainingSize
1595 - (uint16_t)NdefMap->ApduBufferSize;
1596 /* Bytes left in the TLV */
1597 NdefMap->TLVStruct.BytesRemainLinTLV =
1598 NdefMap->TLVStruct.BytesRemainLinTLV -
1599 (uint16_t)NdefMap->ApduBufferSize;
1604 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap)
1606 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1607 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1608 uint8_t BlockNo = PH_FRINFC_TOPAZ_VAL0,
1609 ByteNo = PH_FRINFC_TOPAZ_VAL0;
1611 if((NdefMap->TopazContainer.InternalState ==
1612 PH_FRINFC_TOPAZ_WR_NMN_0) &&
1613 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1614 PH_FRINFC_TOPAZ_VAL0) &&
1615 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1617 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV;
1618 /* Get the L field of the TLV block */
1619 BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) >
1620 PH_FRINFC_TOPAZ_VAL7)?
1621 (NdefMap->TLVStruct.NdefTLVBlock + PH_FRINFC_TOPAZ_VAL1):
1622 NdefMap->TLVStruct.NdefTLVBlock);
1623 /* Get the L byte */
1624 ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) %
1625 PH_FRINFC_TOPAZ_VAL8);
1628 /* Here the NMN is written 0, so internal state is used */
1629 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV_0;
1630 /* Write the length value = 0x00 , Write L field of TLV = 0 inside this*/
1631 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,
1632 PH_FRINFC_TOPAZ_VAL0);
1636 if((NdefMap->TopazContainer.InternalState ==
1637 PH_FRINFC_TOPAZ_WR_NMN_E1) &&
1638 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1639 PH_FRINFC_TOPAZ_CC_BYTE0) &&
1640 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1642 /* Card state is initialised or invalid */
1643 NdefMap->CardState = (uint8_t)((NdefMap->CardState ==
1644 PH_NDEFMAP_CARD_STATE_INITIALIZED)?
1645 PH_NDEFMAP_CARD_STATE_READ_WRITE:
1646 NdefMap->CardState);
1647 /* update the length to the user */
1648 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
1649 Result = NFCSTATUS_SUCCESS;
1655 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap)
1657 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1658 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1659 if((NdefMap->TopazContainer.InternalState ==
1660 PH_FRINFC_TOPAZ_WR_L_TLV_0) &&
1661 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1662 PH_FRINFC_TOPAZ_VAL0) &&
1663 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1665 /* state is writing user data to the card */
1666 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1668 NdefMap->TopazContainer.ByteNumber++;
1669 /* Check the byte number */
1670 phFriNfc_Tpz_H_BlkChk(NdefMap);
1672 /* Write data to the specified location */
1673 /* Write the data to the card from the user buffer */
1674 Result = phFriNfc_Tpz_H_WrAByte( NdefMap,
1675 NdefMap->TopazContainer.CurrentBlock,
1676 NdefMap->TopazContainer.ByteNumber,
1677 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]
1682 if((NdefMap->TopazContainer.InternalState ==
1683 PH_FRINFC_TOPAZ_WR_L_TLV) &&
1684 (((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) &&
1685 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1686 NdefMap->ApduBuffIndex)) ||
1687 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
1688 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1689 (NdefMap->ApduBuffIndex + NdefMap->TLVStruct.BytesRemainLinTLV)))) &&
1690 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1692 /* Update the L value in the context */
1693 NdefMap->TLVStruct.BytesRemainLinTLV =
1694 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
1695 NdefMap->ApduBuffIndex:
1696 (NdefMap->TLVStruct.BytesRemainLinTLV + NdefMap->ApduBuffIndex));
1698 /* Write 0xE1 in block number = 1 and byte number = 0 */
1699 Result = phFriNfc_Tpz_H_WrByte0ValE1(NdefMap);
1705 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData(phFriNfc_NdefMap_t *NdefMap)
1707 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1708 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1709 /* send buffer should be equal to receive buffer */
1710 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1711 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]) &&
1712 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1714 /* Increment the index */
1715 NdefMap->ApduBuffIndex += PH_FRINFC_TOPAZ_VAL1;
1717 /* Remaining space left in the card is less by one */
1718 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL1;
1720 /* Increment the byte number */
1721 NdefMap->TopazContainer.ByteNumber++;
1723 /* Check the block number */
1724 phFriNfc_Tpz_H_BlkChk(NdefMap);
1726 /* check for the user space or the card size */
1727 if((NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex) ||
1728 (NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0))
1730 /* Set write complete, if the end of card is reached */
1731 NdefMap->TopazContainer.ReadWriteCompleteFlag = (uint8_t)
1732 ((NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0)?
1733 PH_FRINFC_TOPAZ_FLAG1:PH_FRINFC_TOPAZ_FLAG0);
1735 Result = phFriNfc_Tpz_H_WrLByte(NdefMap);
1739 /* State is continued to be in write */
1740 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1742 /* Write the byte to the specified location , and Byte to write */
1743 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock,
1744 NdefMap->TopazContainer.ByteNumber,
1745 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]
1752 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t *NdefMap)
1754 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1755 uint8_t BlockNo = PH_FRINFC_TOPAZ_VAL0,
1756 ByteNo = PH_FRINFC_TOPAZ_VAL0;
1757 uint8_t TempByteVal = 0;
1758 BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte +
1759 PH_FRINFC_TOPAZ_VAL1) >
1760 PH_FRINFC_TOPAZ_VAL7)?
1761 (NdefMap->TLVStruct.NdefTLVBlock +
1762 PH_FRINFC_TOPAZ_VAL1):
1763 NdefMap->TLVStruct.NdefTLVBlock);
1765 ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte +
1766 PH_FRINFC_TOPAZ_VAL1) % PH_FRINFC_TOPAZ_VAL8);
1767 /* Update L field */
1768 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV;
1769 /* Internal state for write */
1770 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV;
1771 /* Update the length field depending on the offset */
1772 TempByteVal = (uint8_t)
1773 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
1774 NdefMap->ApduBuffIndex:
1775 (NdefMap->ApduBuffIndex +
1776 NdefMap->TLVStruct.BytesRemainLinTLV));
1777 /* Write the L field */
1778 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, BlockNo, ByteNo,TempByteVal);
1782 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t *NdefMap)
1784 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1786 /* Update L field */
1787 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN;
1788 /* Internal state for writing 0xE1 */
1789 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_E1;
1790 /* Update the length field depending on the offset */
1791 /* Write the L field */
1792 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, PH_FRINFC_TOPAZ_VAL1,
1793 PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_CC_BYTE0);
1797 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t *NdefMap,
1800 /* set the state back to the Reset_Init state*/
1801 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
1803 /* set the completion routine*/
1804 NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex].
1805 CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
1808 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t *NdefMap)
1810 NdefMap->TopazContainer.CurrentBlock =
1811 (uint8_t)((NdefMap->TopazContainer.ByteNumber >
1812 PH_FRINFC_TOPAZ_VAL7)?
1813 (NdefMap->TopazContainer.CurrentBlock +
1814 PH_FRINFC_TOPAZ_VAL1):
1815 NdefMap->TopazContainer.CurrentBlock);
1817 NdefMap->TopazContainer.ByteNumber = (uint8_t)(NdefMap->TopazContainer.ByteNumber %
1818 PH_FRINFC_TOPAZ_VAL8);
1821 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t *NdefMap)
1823 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1824 NFCSTATUS_NO_NDEF_SUPPORT);
1826 if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] ==
1827 PH_FRINFC_TOPAZ_CC_BYTE0)
1829 /* Check the most significant nibble of byte 3 (RWA) = 0 */
1830 Result = (((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] &
1831 PH_FRINFC_TOPAZ_BYTE3_MSB)== PH_FRINFC_TOPAZ_VAL0)?
1835 /* Card size is initialised */
1836 NdefMap->CardMemSize = NdefMap->TopazContainer.RemainingSize =
1837 ((Result == NFCSTATUS_SUCCESS)?
1838 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4):
1839 NdefMap->CardMemSize);
1842 if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY)
1844 NdefMap->CardState = (uint8_t)((Result == NFCSTATUS_SUCCESS)?
1845 PH_NDEFMAP_CARD_STATE_INITIALIZED:
1846 PH_NDEFMAP_CARD_STATE_INVALID);
1852 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t *NdefMap)
1854 /* Set the card state */
1855 NdefMap->CardState = (uint8_t)
1856 (((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_0] ==
1857 PH_FRINFC_TOPAZ_LOCKBIT_BYTE114) &&
1858 ((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] ==
1859 PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_1) ||
1860 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] ==
1861 PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_2)))?
1862 PH_NDEFMAP_CARD_STATE_READ_WRITE:
1863 PH_NDEFMAP_CARD_STATE_READ_ONLY);
1865 /* Set the card state from CC bytes */
1866 if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE)
1868 if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READWRITE)
1870 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
1872 else if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READONLY)
1874 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
1878 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
1883 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t *NdefMap)
1885 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1886 uint8_t ByteNo = PH_FRINFC_TOPAZ_VAL0,
1887 BlockNo = PH_FRINFC_TOPAZ_VAL0;
1888 uint8_t TempByteVal = 0;
1889 switch(NdefMap->TopazContainer.InternalState)
1891 case PH_FRINFC_TOPAZ_WR_CC_BYTE0:
1892 /* To write the CC bytes */
1893 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE0;
1894 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL0;
1895 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1898 case PH_FRINFC_TOPAZ_WR_CC_BYTE1:
1899 /* To write the CC bytes */
1900 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE1;
1901 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
1902 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1905 case PH_FRINFC_TOPAZ_WR_CC_BYTE2:
1906 /* To write the CC bytes */
1907 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE2_MAX;
1908 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL2;
1909 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1912 case PH_FRINFC_TOPAZ_WR_CC_BYTE3:
1913 /* To write the CC bytes */
1914 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE3_RW;
1915 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL3;
1916 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1919 case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
1921 /* To write the NDEF TLV (if not present) */
1922 TempByteVal = PH_FRINFC_TOPAZ_NDEF_T;
1923 ByteNo = (uint8_t)NdefMap->TLVStruct.NdefTLVByte;
1924 BlockNo = NdefMap->TLVStruct.NdefTLVBlock;
1927 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV;
1928 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,TempByteVal);
1932 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t *NdefMap)
1934 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1935 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1936 switch(NdefMap->TopazContainer.InternalState)
1938 case PH_FRINFC_TOPAZ_WR_CC_BYTE0:
1939 /* Process the CC byte */
1940 /* Check the response */
1941 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1942 PH_FRINFC_TOPAZ_CC_BYTE0) &&
1943 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1945 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE1;
1946 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1950 case PH_FRINFC_TOPAZ_WR_CC_BYTE1:
1951 /* Process the CC byte */
1952 /* Check the response */
1953 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1954 PH_FRINFC_TOPAZ_CC_BYTE1) &&
1955 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1957 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE2;
1958 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1962 case PH_FRINFC_TOPAZ_WR_CC_BYTE2:
1963 /* Process the CC byte */
1964 /* Check the response */
1965 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1966 PH_FRINFC_TOPAZ_CC_BYTE2_MAX) &&
1967 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1969 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE3;
1970 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1974 case PH_FRINFC_TOPAZ_WR_CC_BYTE3:
1975 /* Process the CC byte */
1976 /* Check the response */
1977 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1978 PH_FRINFC_TOPAZ_CC_BYTE3_RW) &&
1979 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1981 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;
1982 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1986 case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
1988 /* Check the response */
1989 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1990 PH_FRINFC_TOPAZ_NDEF_T) &&
1991 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1993 /* Increment the Byte Number */
1994 NdefMap->TopazContainer.ByteNumber++;
1995 /* Check the block and byte number */
1996 phFriNfc_Tpz_H_BlkChk(NdefMap);
1997 /* Process the T of NDEF TLV */
1998 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN;
2000 /* Here the NMN is written 0, so internal state is used */
2001 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_0;
2003 /*Inside this call Write NMN (block number 1 and byte number 0) = 0 */
2004 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, PH_FRINFC_TOPAZ_VAL1,
2005 PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_VAL0);
2013 #include <phUnitTestNfc_Topaz_static.c>
2016 #endif /* PH_FRINFC_MAP_TOPAZ_DISABLED */