1/*
2 * Copyright (C) 2010 NXP Semiconductors
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17/*!
18* \file  phFriNfc_TopazMap.c
19* \brief NFC Ndef Mapping For Remote Devices.
20*
21* Project: NFC-FRI
22*
23* $Date: Mon Dec 13 14:14:14 2010 $
24* $Author: ing02260 $
25* $Revision: 1.23 $
26* $Aliases:  $
27*
28*/
29
30
31
32#include <phFriNfc_NdefMap.h>
33#include <phFriNfc_TopazMap.h>
34#include <phFriNfc_MapTools.h>
35#include <phFriNfc_OvrHal.h>
36
37#ifndef PH_FRINFC_MAP_TOPAZ_DISABLED
38/*! \ingroup grp_file_attributes
39*  \name NDEF Mapping
40*
41* File: \ref phFriNfcNdefMap.c
42*
43*/
44/*@{*/
45#define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.23 $"
46#define PHFRINFCTOPAZMAP_FILEALIASES  "$Aliases:  $"
47/*@}*/
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
53*/
54/* #define TOPAZ_RF_ERROR_WORKAROUND */
55
56#ifdef FRINFC_READONLY_NDEF
57
58    #define CC_BLOCK_NUMBER                                         (0x01U)
59    #define LOCK_BLOCK_NUMBER                                       (0x0EU)
60
61    #define LOCK0_BYTE_NUMBER                                       (0x00U)
62    #define LOCK0_BYTE_VALUE                                        (0xFFU)
63
64    #define LOCK1_BYTE_NUMBER                                       (0x01U)
65    #define LOCK1_BYTE_VALUE                                        (0x7FU)
66
67    #define CC_RWA_BYTE_NUMBER                                      (0x03U)
68    #define CC_READ_ONLY_VALUE                                      (0x0FU)
69
70#endif /* #ifdef FRINFC_READONLY_NDEF */
71
72#ifdef TOPAZ_RF_ERROR_WORKAROUND
73
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)
79
80    /* State specific to read after the RF ERROR for the WRITE */
81    #define PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ                     (0x0FU)
82
83#endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
84
85/****************** End of macros ********************/
86
87/*!
88* \name Topaz Mapping - Helper Functions
89*
90*/
91/*@{*/
92
93/*!
94* \brief \copydoc page_ovr Helper function for Topaz. This function shall read 8 bytes
95*  from the card.
96*/
97static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,
98                                        uint16_t             BlockNo,
99                                        uint16_t             ByteNo);
100
101/*!
102* \brief \copydoc page_ovr Helper function for Topaz. This function shall process
103* read id command
104*/
105static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap);
106
107/*!
108* \brief \copydoc page_ovr Helper function for Topaz. This function shall process
109* read all command
110*/
111static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap);
112
113/*!
114* \brief \copydoc page_ovr Helper function for Topaz. This function depends on
115* function called by the user
116*/
117static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap);
118
119/*!
120* \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC
121* bytes
122*/
123static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap);
124
125/*!
126* \brief \copydoc page_ovr Helper function for Topaz. This function finds
127* NDEF TLV
128*/
129static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap);
130
131/*!
132* \brief \copydoc page_ovr Helper function for Topaz. This function writes a
133* byte into the card
134*/
135static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,
136                                        uint16_t             BlockNo,
137                                        uint16_t             ByteNo,
138                                        uint8_t              ByteVal
139                                        );
140
141/*!
142* \brief \copydoc page_ovr Helper function for Topaz. This function shall process the
143* NMN write
144*/
145static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap);
146
147/*!
148* \brief \copydoc page_ovr Helper function for Topaz. This function writes the length field of
149* the NDEF TLV
150*/
151static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap);
152
153/*!
154* \brief \copydoc page_ovr Helper function for Topaz. This function updates length field
155* of the NDEF TLV after complete write.
156*/
157static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t  *NdefMap);
158
159/*!
160* \brief \copydoc page_ovr Helper function for Topaz. This function copies the card data
161*  to the user buffer
162*/
163static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf( phFriNfc_NdefMap_t  *NdefMap);
164
165/*!
166* \brief \copydoc page_ovr Helper function for Topaz. This function shall process the
167* written data
168*/
169static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData( phFriNfc_NdefMap_t  *NdefMap);
170
171/*!
172* \brief \copydoc page_ovr Helper function for Topaz. This function checks the block
173* number is correct or not
174*/
175static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t  *NdefMap);
176
177/*!
178* \brief \copydoc page_ovr Helper function for Topaz. This function writes the 0th
179* byte of block 1 has Zero
180*/
181static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t   *NdefMap);
182
183/*!
184* \brief \copydoc page_ovr Helper function for Topaz. This function calls the
185* completion routine
186*/
187static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t  *NdefMap,
188                                    NFCSTATUS           Status);
189
190/*!
191* \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
192* the CC byte in check ndef function
193*/
194static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t  *NdefMap);
195
196/*!
197* \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
198* the lock bits and set a card state
199*/
200static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t  *NdefMap);
201
202/*!
203* \brief \copydoc page_ovr Helper function for Topaz. This function writes CC bytes or
204* type of the TLV
205*/
206static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t  *NdefMap);
207
208#ifdef TOPAZ_RF_ERROR_WORKAROUND
209
210/*!
211* \brief \copydoc page_ovr Helper function for Topaz. This function checks the written
212* value after the
213*/
214static
215NFCSTATUS
216phFriNfc_Tpz_H_CheckWrittenData (
217    phFriNfc_NdefMap_t          *psNdefMap,
218    uint8_t                     state_rf_error);
219
220#endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
221
222/*!
223* \brief \copydoc page_ovr Helper function for Topaz. This function checks the written
224* CC bytes are correct
225*/
226static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t  *NdefMap);
227/*@}*/
228void phFriNfc_TopazMap_H_Reset(phFriNfc_NdefMap_t        *NdefMap)
229{
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;
243}
244
245/*!
246* \brief Check whether a particular Remote Device is NDEF compliant.
247*
248* The function checks whether the peer device is NDEF compliant.
249*
250* \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t
251*                    structure describing the component context.
252*
253* \retval  NFCSTATUS_PENDING   The action has been successfully triggered.
254* \retval  Others              An error has occurred.
255*
256*/
257
258NFCSTATUS phFriNfc_TopazMap_ChkNdef( phFriNfc_NdefMap_t     *NdefMap)
259{
260    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
261        NFCSTATUS_INVALID_PARAMETER);
262    if ( NdefMap != NULL)
263    {
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;
271
272        /* Set card state */
273        NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_CARD;
274
275        /* Change the state to Check Ndef Compliant */
276        NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID;
277        NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
278
279#ifdef TOPAZ_RAW_SUPPORT
280        NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
281        NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID;
282#else
283#ifdef PH_HAL4_ENABLE
284        NdefMap->Cmd.JewelCmd = phHal_eJewel_RID;
285#else
286        NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid;
287#endif
288#endif /* #ifdef TOPAZ_RAW_SUPPORT */
289
290        Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
291            NdefMap->TopazContainer.ByteNumber);
292    }
293    return Result;
294}
295
296#ifdef FRINFC_READONLY_NDEF
297
298NFCSTATUS
299phFriNfc_TopazMap_ConvertToReadOnly (
300    phFriNfc_NdefMap_t          *NdefMap)
301{
302    NFCSTATUS               result = NFCSTATUS_SUCCESS;
303
304    result = phFriNfc_Tpz_H_WrAByte (NdefMap, CC_BLOCK_NUMBER,
305                                    CC_RWA_BYTE_NUMBER, CC_READ_ONLY_VALUE);
306
307    if (NFCSTATUS_PENDING == PHNFCSTATUS(result))
308    {
309        NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE;
310    }
311    return result;
312}
313
314#endif /* #ifdef FRINFC_READONLY_NDEF */
315
316/*!
317* \brief Initiates Reading of NDEF information from the Remote Device.
318*
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.
323*/
324NFCSTATUS phFriNfc_TopazMap_RdNdef( phFriNfc_NdefMap_t                  *NdefMap,
325                                        uint8_t                         *PacketData,
326                                        uint32_t                        *PacketDataLength,
327                                        uint8_t                         Offset)
328{
329    NFCSTATUS               Result =    NFCSTATUS_SUCCESS;
330
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
339    from the card. */
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;
348
349    if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation ==
350        PH_FRINFC_NDEFMAP_WRITE_OPE))
351    {
352        /* If previous operation is not read then the read shall
353        start from BEGIN */
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;
366#else
367
368#ifdef PH_HAL4_ENABLE
369        NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
370#else
371        NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
372#endif
373
374#endif /* #ifdef TOPAZ_RAW_SUPPORT */
375    }
376
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))
382    {
383        Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
384            NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
385    }
386    else
387    {
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));
395    }
396
397    return Result;
398}
399
400/*!
401* \brief Initiates Writing of NDEF information to the Remote Device.
402*
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.
407*/
408NFCSTATUS phFriNfc_TopazMap_WrNdef( phFriNfc_NdefMap_t     *NdefMap,
409                                   uint8_t                 *PacketData,
410                                   uint32_t                *PacketDataLength,
411                                   uint8_t                 Offset)
412{
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
425    to the card. */
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;
432
433
434    if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
435        (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))
436    {
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 */
444
445#ifdef TOPAZ_RAW_SUPPORT
446        NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
447        NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
448#else
449#ifdef PH_HAL4_ENABLE
450        NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
451#else
452        NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
453#endif
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];
459    }
460    else
461    {
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];
466    }
467
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))
473    {
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);
477    }
478    else
479    {
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));
488    }
489
490    return Result;
491}
492
493
494/*!
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.
499*
500*/
501
502void phFriNfc_TopazMap_Process( void       *Context,
503                               NFCSTATUS   Status)
504{
505
506    phFriNfc_NdefMap_t              *psNdefMap = NULL;
507
508#ifdef TOPAZ_RF_ERROR_WORKAROUND
509
510    static uint8_t                  rf_error_state = 0;
511
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 */
516
517    psNdefMap = (phFriNfc_NdefMap_t *)Context;
518
519    if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER))
520    {
521        switch (psNdefMap->State)
522        {
523#ifdef FRINFC_READONLY_NDEF
524            case PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE:
525            {
526                if((CC_READ_ONLY_VALUE == *psNdefMap->SendRecvBuf)
527                    && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
528                {
529                    written_lock_byte = 0;
530#ifdef TOPAZ_RAW_SUPPORT
531                    *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
532#else
533#ifdef PH_HAL4_ENABLE
534                    psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
535#else
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,
540                                                    LOCK0_BYTE_NUMBER);
541
542                    if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
543                    {
544                        psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE;
545                    }
546                }
547                else
548                {
549                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
550                                        NFCSTATUS_INVALID_RECEIVE_LENGTH);
551                }
552                break;
553            }
554
555            case PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE:
556            {
557                if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)
558                {
559                    Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER,
560                                                LOCK0_BYTE_NUMBER,
561                                                LOCK0_BYTE_VALUE);
562
563                    if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
564                    {
565                        psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE;
566                    }
567                }
568                break;
569            }
570
571            case PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE:
572            {
573                if((LOCK0_BYTE_VALUE == *psNdefMap->SendRecvBuf)
574                    && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
575                {
576#ifdef TOPAZ_RAW_SUPPORT
577                    *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
578#else
579#ifdef PH_HAL4_ENABLE
580                    psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
581#else
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,
586                                                    LOCK1_BYTE_NUMBER);
587
588                    if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
589                    {
590                        psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE;
591                    }
592                }
593                else
594                {
595                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
596                                        NFCSTATUS_INVALID_RECEIVE_LENGTH);
597                }
598            }
599
600            case PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE:
601            {
602                if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)
603                {
604                    written_lock_byte = (uint8_t)(*psNdefMap->SendRecvBuf | LOCK1_BYTE_VALUE);
605                    Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER,
606                                                LOCK1_BYTE_NUMBER,
607                                                written_lock_byte);
608
609                    if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
610                    {
611                        psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE;
612                    }
613                }
614                break;
615            }
616
617            case PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE:
618            {
619                if((written_lock_byte == *psNdefMap->SendRecvBuf)
620                    && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
621                {
622                    written_lock_byte = 0;
623                    /* Do nothing */
624                }
625                else
626                {
627                    written_lock_byte = 0;
628                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
629                                        NFCSTATUS_INVALID_RECEIVE_LENGTH);
630                }
631            }
632#endif /* #ifdef FRINFC_READONLY_NDEF */
633            case PH_FRINFC_TOPAZ_STATE_WRITE:
634            {
635                Status = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);
636                break;
637            }
638
639            case PH_FRINFC_TOPAZ_STATE_READID:
640            {
641                Status = phFriNfc_Tpz_H_ProReadID (psNdefMap);
642                break;
643            }
644
645            case PH_FRINFC_TOPAZ_STATE_READALL:
646            {
647                Status = phFriNfc_Tpz_H_ProReadAll (psNdefMap);
648                break;
649            }
650
651            case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
652            {
653                Status = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);
654                break;
655            }
656
657            case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
658            {
659                Status = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);
660                break;
661            }
662
663            case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
664            {
665                Status = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);
666                break;
667            }
668
669#ifdef TOPAZ_RF_ERROR_WORKAROUND
670
671            case PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ:
672            {
673                Status = phFriNfc_Tpz_H_CheckWrittenData (psNdefMap,
674                                                        rf_error_state);
675                break;
676            }
677
678#endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
679
680            default:
681            {
682                Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP,
683                                    NFCSTATUS_INVALID_DEVICE_REQUEST);
684                break;
685            }
686        }
687    }
688    else
689    {
690#ifdef TOPAZ_RF_ERROR_WORKAROUND
691
692        if ((FRINFC_RF_TIMEOUT_89 == PHNFCSTATUS (Status)) ||
693            (FRINFC_RF_TIMEOUT_90 == PHNFCSTATUS (Status)) ||
694            (NFCSTATUS_RF_TIMEOUT == PHNFCSTATUS (Status)))
695        {
696            uint8_t             byte_number = 0;
697            uint8_t             block_number = 0;
698
699            rf_error_state = psNdefMap->State;
700
701#ifdef TOPAZ_RAW_SUPPORT
702
703            *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
704
705#else
706
707#ifdef PH_HAL4_ENABLE
708
709            psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
710
711#else
712
713            psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;
714
715#endif /* #ifdef PH_HAL4_ENABLE */
716
717#endif /* #ifdef TOPAZ_RAW_SUPPORT */
718
719            /* Update the state variable to the new work around state*/
720            psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ;
721
722            /* Switch is used to know, if the error occured during WRITE or READ */
723            switch (rf_error_state)
724            {
725                case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
726                {
727                    /* Block and byte number is updated for NMN */
728                    byte_number = PH_FRINFC_TOPAZ_VAL0;
729                    block_number = PH_FRINFC_TOPAZ_VAL1;
730                    break;
731                }
732
733                case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
734                {
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);
742                    /* Get the L byte */
743                    byte_number = (uint8_t)((psNdefMap->TLVStruct.NdefTLVByte +
744                                        PH_FRINFC_TOPAZ_VAL1) %
745                                        PH_FRINFC_TOPAZ_VAL8);
746                    break;
747                }
748
749                case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
750                {
751                    switch (psNdefMap->TopazContainer.InternalState)
752                    {
753                        case PH_FRINFC_TOPAZ_WR_CC_BYTE0:
754                        {
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;
758                            break;
759                        }
760
761                        case PH_FRINFC_TOPAZ_WR_CC_BYTE1:
762                        {
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;
766                            break;
767                        }
768
769                        case PH_FRINFC_TOPAZ_WR_CC_BYTE2:
770                        {
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;
774                            break;
775                        }
776
777                        case PH_FRINFC_TOPAZ_WR_CC_BYTE3:
778                        {
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;
782                            break;
783                        }
784
785                        case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
786                        {
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;
790                            break;
791                        }
792
793                        default:
794                        {
795                            /* Do nothing */
796                            break;
797                        }
798                    } /* switch (psNdefMap->TopazContainer.InternalState) */
799                    break;
800                }
801
802                case PH_FRINFC_TOPAZ_STATE_WRITE:
803                {
804                    /* Block and byte number is updated for the written error data */
805                    block_number = psNdefMap->TopazContainer.CurrentBlock;
806                    byte_number = psNdefMap->TopazContainer.ByteNumber;
807                    break;
808                }
809
810                default:
811                {
812                    /* Error occured is not during WRITE, so update
813                        state variable to the previous state */
814                    psNdefMap->State = rf_error_state;
815                    break;
816                }
817            } /* switch (rf_error_state) */
818
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)
825            {
826                /* Read the data with the updated block and byte number */
827                Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, block_number,
828                                                byte_number);
829            }
830        }
831
832#endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
833    }
834
835    /* Call Completion Routine, if Status != PENDING */
836    if (NFCSTATUS_PENDING != Status)
837    {
838        phFriNfc_Tpz_H_Complete(psNdefMap, Status);
839    }
840}
841
842
843#ifdef TOPAZ_RF_ERROR_WORKAROUND
844
845static
846NFCSTATUS
847phFriNfc_Tpz_H_CheckWrittenData (
848    phFriNfc_NdefMap_t          *psNdefMap,
849    uint8_t                     state_rf_error)
850{
851    NFCSTATUS   result = NFCSTATUS_SUCCESS;
852
853    switch (state_rf_error)
854    {
855        case PH_FRINFC_TOPAZ_STATE_WRITE:
856        {
857            result = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);
858            break;
859        }
860
861        case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
862        {
863            result = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);
864            break;
865        }
866
867        case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
868        {
869            result = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);
870            break;
871        }
872
873        case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
874        {
875            result = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);
876            break;
877        }
878
879        default:
880        {
881            break;
882        }
883    }
884
885    return result;
886}
887
888
889#endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
890
891static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,
892                                        uint16_t             BlockNo,
893                                        uint16_t            ByteNo)
894{
895    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
896#ifdef TOPAZ_RAW_SUPPORT
897    uint8_t index = 0;
898#endif /* #ifdef TOPAZ_RAW_SUPPORT */
899
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;
904
905    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;
906    NdefMap->MapCompletionInfo.Context = NdefMap;
907
908    *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
909
910    /* Depending on the jewel command, the send length is decided */
911#ifdef TOPAZ_RAW_SUPPORT
912    switch(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0])
913#else
914    switch(NdefMap->Cmd.JewelCmd)
915#endif /* #ifdef TOPAZ_RAW_SUPPORT */
916    {
917
918#ifdef TOPAZ_RAW_SUPPORT
919    case PH_FRINFC_TOPAZ_CMD_READID:
920#else
921#ifdef PH_HAL4_ENABLE
922    case phHal_eJewel_RID:
923#else
924    case phHal_eJewelCmdListJewelRid:
925#endif
926#endif /* #ifdef TOPAZ_RAW_SUPPORT */
927
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;
932        index ++;
933
934        /*Copy UID of the tag to  Send Buffer*/
935        (void)memset(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1]),
936        0x00,(0x06));
937        index = index + 0x06;
938
939        /* Update the length of the command buffer*/
940        NdefMap->SendLength = index;
941#else
942        /* For READ ID and READ ALL, send length is 0 */
943        NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
944#endif /* #ifdef TOPAZ_RAW_SUPPORT */
945        break;
946
947#ifdef TOPAZ_RAW_SUPPORT
948    case PH_FRINFC_TOPAZ_CMD_READALL:
949#else
950#ifdef PH_HAL4_ENABLE
951    case phHal_eJewel_ReadAll:
952#else
953    case phHal_eJewelCmdListJewelReadAll:
954#endif
955#endif /* #ifdef TOPAZ_RAW_SUPPORT */
956
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;
961        index ++;
962
963        /*Copy 0x00 to Send Buffer*/
964        NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00;
965        index ++;
966        NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;
967        index ++;
968
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);
973
974        index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
975
976        /* Update the length of the command buffer*/
977        NdefMap->SendLength = index;
978#else
979       /* For READ ID and READ ALL, send length is 0 */
980        NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
981#endif /* #ifdef TOPAZ_RAW_SUPPORT */
982        break;
983
984#ifdef TOPAZ_RAW_SUPPORT
985    case PH_FRINFC_TOPAZ_CMD_READ:
986#else
987#ifdef PH_HAL4_ENABLE
988    case phHal_eJewel_Read1:
989#else
990    case phHal_eJewelCmdListJewelRead1:
991#endif
992
993#endif /* #ifdef TOPAZ_RAW_SUPPORT */
994
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;
999        index ++;
1000
1001        /*Copy Address to  Send Buffer*/
1002        /* Calculate send length
1003        7 | 6   5   4   3 | 2   1   0 |
1004        |    block no   |  byte no  |
1005        */
1006        NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] =
1007                (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1008                ByteNo);
1009        index ++;
1010        /*Copy 0x00 to  Send Buffer*/
1011        NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;
1012        index ++;
1013
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);
1019
1020        /* Update the length of the command buffer*/
1021        NdefMap->SendLength = index;
1022#else
1023        /* Calculate send length
1024        7 | 6   5   4   3 | 2   1   0 |
1025        |    block no   |  byte no  |
1026        */
1027        NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] =
1028                (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1029                ByteNo);
1030        NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL1;
1031#endif /* #ifdef TOPAZ_RAW_SUPPORT */
1032
1033        break;
1034#ifdef TOPAZ_RAW_SUPPORT
1035#else
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;
1042    break;
1043#endif
1044#endif /* #ifdef TOPAZ_RAW_SUPPORT */
1045
1046    default:
1047        Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1048                            NFCSTATUS_INVALID_DEVICE_REQUEST);
1049    }
1050
1051    if(Result == NFCSTATUS_SUCCESS)
1052    {
1053        /* Call the Overlapped HAL Transceive function */
1054        Result = phFriNfc_OvrHal_Transceive(    NdefMap->LowerDevice,
1055                                                &NdefMap->MapCompletionInfo,
1056                                                NdefMap->psRemoteDevInfo,
1057                                                NdefMap->Cmd,
1058                                                &NdefMap->psDepAdditionalInfo,
1059                                                NdefMap->SendRecvBuf,
1060                                                NdefMap->SendLength,
1061                                                NdefMap->SendRecvBuf,
1062                                                NdefMap->SendRecvLength);
1063    }
1064    return Result;
1065}
1066
1067static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,
1068                                        uint16_t             BlockNo,
1069                                        uint16_t             ByteNo,
1070                                        uint8_t              ByteVal
1071                                        )
1072{
1073    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
1074    uint8_t     index = 0;
1075
1076
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;
1082
1083    NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;
1084    NdefMap->MapCompletionInfo.Context = NdefMap;
1085
1086    *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1087    /* Command used to write 1 byte */
1088#ifdef TOPAZ_RAW_SUPPORT
1089    NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1090#else
1091#ifdef PH_HAL4_ENABLE
1092    NdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1093#else
1094    NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelWriteErase1;
1095#endif
1096#endif /* #ifdef TOPAZ_RAW_SUPPORT */
1097
1098#ifdef TOPAZ_RAW_SUPPORT
1099    /*Copy command to Send Buffer*/
1100    NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0]  = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1101    index ++;
1102
1103    /*Copy Address to  Send Buffer*/
1104    /* Calculate send length
1105    7 | 6   5   4   3 | 2   1   0 |
1106    |    block no   |  byte no  |
1107    */
1108    NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] =
1109            (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1110            ByteNo);
1111    index ++;
1112    /*Copy Data byte to Send Buffer*/
1113    NdefMap->SendRecvBuf[index] = ByteVal;
1114    index ++;
1115
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);
1121
1122    /* Update the length of the command buffer*/
1123    NdefMap->SendLength = index;
1124
1125#else
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  |
1130    */
1131    NdefMap->SendRecvBuf[index] =
1132                        (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1133                        ByteNo);
1134    index ++;
1135    NdefMap->SendRecvBuf[index] = ByteVal;
1136    index ++;
1137    NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL2;
1138
1139#endif /* #ifdef TOPAZ_RAW_SUPPORT */
1140
1141    /* Call the Overlapped HAL Transceive function */
1142    Result = phFriNfc_OvrHal_Transceive(    NdefMap->LowerDevice,
1143                                            &NdefMap->MapCompletionInfo,
1144                                            NdefMap->psRemoteDevInfo,
1145                                            NdefMap->Cmd,
1146                                            &NdefMap->psDepAdditionalInfo,
1147                                            NdefMap->SendRecvBuf,
1148                                            NdefMap->SendLength,
1149                                            NdefMap->SendRecvBuf,
1150                                            NdefMap->SendRecvLength);
1151
1152    return Result;
1153}
1154
1155static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap)
1156{
1157    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1158        NFCSTATUS_INVALID_RECEIVE_LENGTH);
1159
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))
1163    {
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);
1168
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;
1175#else
1176#ifdef PH_HAL4_ENABLE
1177        NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
1178#else
1179        NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
1180#endif
1181#endif /* #ifdef TOPAZ_RAW_SUPPORT */
1182
1183        /* Read all bytes from the card */
1184        Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
1185            NdefMap->TopazContainer.ByteNumber);
1186    }
1187
1188    return Result;
1189}
1190
1191static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap)
1192{
1193    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1194        NFCSTATUS_INVALID_RECEIVE_LENGTH);
1195    int32_t     memcompare = PH_FRINFC_TOPAZ_VAL0;
1196
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]))
1203    {
1204        memcompare = PH_FRINFC_TOPAZ_VAL0;
1205    }
1206    else
1207    {
1208        memcompare = PH_FRINFC_TOPAZ_VAL1;
1209    }
1210#else
1211    memcompare = memcmp(NdefMap->TopazContainer.UID,
1212        &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
1213        PH_FRINFC_TOPAZ_VAL4);
1214#endif /* #ifdef PH_HAL4_ENABLE */
1215
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))
1220    {
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);
1225
1226        /* Check the lock bits and set the card state */
1227        phFriNfc_Tpz_H_ChkLockBits(NdefMap);
1228
1229        Result = phFriNfc_Tpz_H_CallNxtOp(NdefMap);
1230    }
1231    return Result;
1232}
1233
1234static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap)
1235{
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
1239    read data */
1240    switch(NdefMap->PrevOperation)
1241    {
1242    case PH_FRINFC_NDEFMAP_CHECK_OPE:
1243        /* Check the capabilty container values, according
1244        to the spec */
1245        Result = phFriNfc_Tpz_H_ChkCCinChkNdef(NdefMap);
1246
1247        if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INVALID)
1248        {
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))
1257            {
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;
1262            }
1263        }
1264        else
1265        {
1266            Result = NFCSTATUS_SUCCESS;
1267            NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
1268            NdefMap->CardMemSize =
1269            NdefMap->TopazContainer.RemainingSize = (uint16_t)
1270                        /*
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
1274                        */
1275                        (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4 -
1276                        PH_FRINFC_TOPAZ_VAL2);
1277        }
1278        break;
1279
1280    case PH_FRINFC_NDEFMAP_READ_OPE:
1281        /* Check the capabilty container values, according
1282        to the spec */
1283        Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);
1284
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));
1290
1291        if(Result == NFCSTATUS_SUCCESS)
1292        {
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);
1296        }
1297        break;
1298
1299    case PH_FRINFC_NDEFMAP_WRITE_OPE:
1300    default:
1301        if((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE) ||
1302            (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED))
1303        {
1304            /* Check the capabilty container values, according
1305            to the spec */
1306            Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);
1307            if(Result == NFCSTATUS_SUCCESS)
1308            {
1309                /* Find the NDEF TLV */
1310                Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap);
1311
1312                /* Write the TLV */
1313                NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;
1314            }
1315            else
1316            {
1317                NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4;
1318                NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1;
1319                NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4;
1320                /* Write the TLV */
1321                NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE0;
1322            }
1323            /* Write CC bytes */
1324            Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1325        }
1326        break;
1327    }
1328    return Result;
1329}
1330
1331static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap)
1332{
1333    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1334        NFCSTATUS_NO_NDEF_SUPPORT);
1335
1336    if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] ==
1337        PH_FRINFC_TOPAZ_CC_BYTE0)
1338    {
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)):
1349                    Result);
1350
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);
1356
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)))
1361        {
1362            Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1363                                NFCSTATUS_INVALID_FORMAT));
1364        }
1365
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)))
1372        {
1373            Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1374                                NFCSTATUS_INVALID_FORMAT));
1375        }
1376    }
1377    return Result;
1378}
1379
1380extern NFCSTATUS phFriNfc_Tpz_H_ChkSpcVer( phFriNfc_NdefMap_t  *NdefMap,
1381                                          uint8_t             VersionNo)
1382{
1383    NFCSTATUS Result = NFCSTATUS_SUCCESS;
1384    uint8_t TagVerNo = VersionNo;
1385
1386    /* To remove "warning (VS C4100) : unreferenced formal parameter" */
1387    PHNFC_UNUSED_VARIABLE(NdefMap);
1388
1389    if ( TagVerNo == 0 )
1390    {
1391        /*Return Status Error  Invalid Format*/
1392        Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
1393    }
1394    else
1395    {
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) )))
1405        {
1406            Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
1407        }
1408        else
1409        {
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)))
1414            {
1415                Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
1416            }
1417        }
1418    }
1419    return Result;
1420}
1421
1422static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap)
1423{
1424    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1425        NFCSTATUS_NO_NDEF_SUPPORT);
1426    uint8_t     index = PH_FRINFC_TOPAZ_VAL4;
1427
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))
1432    {
1433        switch(NdefMap->TopazContainer.ReadBuffer[index])
1434        {
1435        case PH_FRINFC_TOPAZ_NDEF_T:
1436            /* To get the length field of the TLV */
1437            index++;
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))
1450            {
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;
1456            }
1457            else
1458            {
1459                /* So remaining size also changes, according to the position of NDEF TLV  */
1460                NdefMap->TLVStruct.BytesRemainLinTLV =
1461                    NdefMap->TopazContainer.ReadBuffer[index];
1462
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;
1478            }
1479            break;
1480
1481        case PH_FRINFC_TOPAZ_NULL_T:
1482            /* Null TLV, Skip the TLV */
1483            NdefMap->TopazContainer.RemainingSize--;
1484            index++;
1485            break;
1486
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);
1492            break;
1493
1494        default:
1495            /* Go till the length field of the TLV */
1496            index++;
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)
1502            {
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);
1507            }
1508            else
1509            {
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];
1515
1516                /* Get the position of the next TLV */
1517                index = (uint8_t)(index +
1518                    (NdefMap->TopazContainer.ReadBuffer[index] +
1519                     PH_FRINFC_TOPAZ_VAL1));
1520            }
1521            break;
1522        }
1523    }
1524
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))
1528    {
1529        Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1530                            NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
1531    }
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)))
1535    {
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;
1540    }
1541    return Result;
1542}
1543
1544static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf(phFriNfc_NdefMap_t  *NdefMap)
1545{
1546    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
1547
1548    /* Check the the TLV size and the user size */
1549    if(NdefMap->ApduBufferSize >=
1550        NdefMap->TLVStruct.BytesRemainLinTLV)
1551    {
1552        /* Copy the read bytes to user buffer till the value (V)
1553        of TLV ends */
1554        (void)memcpy(NdefMap->ApduBuffer,
1555            &(NdefMap->TopazContainer.ReadBuffer[
1556                NdefMap->TopazContainer.ByteNumber]),
1557                    NdefMap->TLVStruct.BytesRemainLinTLV);
1558
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
1569                the TLV */
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;
1576    }
1577    else
1578    {
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);
1584
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;
1600    }
1601    return Result;
1602}
1603
1604static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap)
1605{
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;
1610
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))
1616    {
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);
1626
1627
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);
1633    }
1634    else
1635    {
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))
1641        {
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;
1650        }
1651    }
1652    return Result;
1653}
1654
1655static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap)
1656{
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))
1664    {
1665        /* state is writing user data to the card */
1666        NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1667
1668        NdefMap->TopazContainer.ByteNumber++;
1669        /* Check the byte number */
1670        phFriNfc_Tpz_H_BlkChk(NdefMap);
1671
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]
1678                                        );
1679    }
1680    else
1681    {
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))
1691        {
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));
1697
1698            /* Write 0xE1 in block number = 1 and byte number = 0 */
1699            Result = phFriNfc_Tpz_H_WrByte0ValE1(NdefMap);
1700        }
1701    }
1702    return Result;
1703}
1704
1705static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData(phFriNfc_NdefMap_t *NdefMap)
1706{
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))
1713    {
1714        /* Increment the index */
1715        NdefMap->ApduBuffIndex += PH_FRINFC_TOPAZ_VAL1;
1716
1717        /* Remaining space left in the card is less by one */
1718        NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL1;
1719
1720        /* Increment the byte number */
1721        NdefMap->TopazContainer.ByteNumber++;
1722
1723        /* Check the block number */
1724        phFriNfc_Tpz_H_BlkChk(NdefMap);
1725
1726        /* check for the user space or the card size */
1727        if((NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex) ||
1728            (NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0))
1729        {
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);
1734
1735            Result = phFriNfc_Tpz_H_WrLByte(NdefMap);
1736        }
1737        else
1738        {
1739            /* State is continued to be in write */
1740            NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1741
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]
1746                                            );
1747        }
1748    }
1749    return Result;
1750}
1751
1752static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t  *NdefMap)
1753{
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);
1764
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);
1779    return Result;
1780}
1781
1782static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t   *NdefMap)
1783{
1784    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
1785
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);
1794    return Result;
1795}
1796
1797static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t  *NdefMap,
1798                                    NFCSTATUS           Status)
1799{
1800    /* set the state back to the Reset_Init state*/
1801    NdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
1802
1803    /* set the completion routine*/
1804    NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex].
1805        CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
1806}
1807
1808static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t  *NdefMap)
1809{
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);
1816
1817    NdefMap->TopazContainer.ByteNumber = (uint8_t)(NdefMap->TopazContainer.ByteNumber %
1818                                        PH_FRINFC_TOPAZ_VAL8);
1819}
1820
1821static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t  *NdefMap)
1822{
1823    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1824                                    NFCSTATUS_NO_NDEF_SUPPORT);
1825
1826    if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] ==
1827        PH_FRINFC_TOPAZ_CC_BYTE0)
1828    {
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)?
1832                    NFCSTATUS_SUCCESS:
1833                    Result);
1834
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);
1840    }
1841
1842    if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY)
1843    {
1844        NdefMap->CardState = (uint8_t)((Result == NFCSTATUS_SUCCESS)?
1845                            PH_NDEFMAP_CARD_STATE_INITIALIZED:
1846                            PH_NDEFMAP_CARD_STATE_INVALID);
1847    }
1848
1849    return Result;
1850}
1851
1852static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t  *NdefMap)
1853{
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);
1864
1865    /* Set the card state from CC bytes */
1866    if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE)
1867    {
1868        if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READWRITE)
1869        {
1870            NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
1871        }
1872        else if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READONLY)
1873        {
1874            NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
1875        }
1876        else
1877        {
1878            NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
1879        }
1880    }
1881}
1882
1883static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t  *NdefMap)
1884{
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)
1890    {
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;
1896        break;
1897
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;
1903        break;
1904
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;
1910        break;
1911
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;
1917        break;
1918
1919    case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
1920    default:
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;
1925        break;
1926    }
1927    NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV;
1928    Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,TempByteVal);
1929    return Result;
1930}
1931
1932static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t  *NdefMap)
1933{
1934    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1935        NFCSTATUS_INVALID_RECEIVE_LENGTH);
1936    switch(NdefMap->TopazContainer.InternalState)
1937    {
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))
1944        {
1945            NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE1;
1946            Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1947        }
1948        break;
1949
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))
1956        {
1957            NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE2;
1958            Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1959        }
1960        break;
1961
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))
1968        {
1969            NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE3;
1970            Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1971        }
1972        break;
1973
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))
1980        {
1981            NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;
1982            Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1983        }
1984        break;
1985
1986    case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
1987    default:
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))
1992        {
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;
1999
2000            /* Here the NMN is written 0, so internal state is used */
2001            NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_0;
2002
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);
2006        }
2007        break;
2008    }
2009    return Result;
2010}
2011
2012#ifdef UNIT_TEST
2013#include <phUnitTestNfc_Topaz_static.c>
2014#endif
2015
2016#endif  /* PH_FRINFC_MAP_TOPAZ_DISABLED */
2017