merge with master
[adaptation/devices/nfc-plugin-nxp.git] / src / phFriNfc_TopazMap.c
1 /*\r
2  * Copyright (C) 2010 NXP Semiconductors\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /*!\r
18 * \file  phFriNfc_TopazMap.c\r
19 * \brief NFC Ndef Mapping For Remote Devices.\r
20 *\r
21 * Project: NFC-FRI\r
22 *\r
23 * $Date: Mon Dec 13 14:14:14 2010 $\r
24 * $Author: ing02260 $\r
25 * $Revision: 1.23 $\r
26 * $Aliases:  $\r
27 *\r
28 */\r
29 \r
30 \r
31 \r
32 #include <phFriNfc_NdefMap.h>\r
33 #include <phFriNfc_TopazMap.h>\r
34 #include <phFriNfc_MapTools.h>\r
35 #include <phFriNfc_OvrHal.h>\r
36 \r
37 #ifndef PH_FRINFC_MAP_TOPAZ_DISABLED\r
38 /*! \ingroup grp_file_attributes\r
39 *  \name NDEF Mapping\r
40 *\r
41 * File: \ref phFriNfcNdefMap.c\r
42 *\r
43 */\r
44 /*@{*/\r
45 #define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.23 $"\r
46 #define PHFRINFCTOPAZMAP_FILEALIASES  "$Aliases:  $"\r
47 /*@}*/\r
48 /****************** Start of macros ********************/\r
49 /* Below MACRO is used for the WRITE error scenario, \r
50     in case PN544 returns error for any WRITE, then \r
51     read the written block and byte number, to check the data \r
52     written to the card is correct or not \r
53 */\r
54 /* #define TOPAZ_RF_ERROR_WORKAROUND */\r
55 \r
56 #ifdef FRINFC_READONLY_NDEF\r
57 \r
58     #define CC_BLOCK_NUMBER                                         (0x01U)\r
59     #define LOCK_BLOCK_NUMBER                                       (0x0EU)\r
60 \r
61     #define LOCK0_BYTE_NUMBER                                       (0x00U)\r
62     #define LOCK0_BYTE_VALUE                                        (0xFFU)\r
63 \r
64     #define LOCK1_BYTE_NUMBER                                       (0x01U)\r
65     #define LOCK1_BYTE_VALUE                                        (0x7FU)\r
66 \r
67     #define CC_RWA_BYTE_NUMBER                                      (0x03U)\r
68     #define CC_READ_ONLY_VALUE                                      (0x0FU)\r
69 \r
70 #endif /* #ifdef FRINFC_READONLY_NDEF */\r
71 \r
72 #ifdef TOPAZ_RF_ERROR_WORKAROUND\r
73 \r
74     /* Below MACROs are added for the error returned from HAL, if the \r
75         below error has occured during the WRITE, then read the error \r
76         returned blocks to confirm */\r
77     #define FRINFC_RF_TIMEOUT_89                                    (0x89U)\r
78     #define FRINFC_RF_TIMEOUT_90                                    (0x90U)\r
79 \r
80     /* State specific to read after the RF ERROR for the WRITE */\r
81     #define PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ                     (0x0FU)\r
82 \r
83 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */\r
84 \r
85 /****************** End of macros ********************/\r
86 \r
87 /*!\r
88 * \name Topaz Mapping - Helper Functions\r
89 *\r
90 */\r
91 /*@{*/\r
92 \r
93 /*!\r
94 * \brief \copydoc page_ovr Helper function for Topaz. This function shall read 8 bytes \r
95 *  from the card.\r
96 */\r
97 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,\r
98                                         uint16_t             BlockNo,\r
99                                         uint16_t             ByteNo);\r
100  \r
101 /*!\r
102 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process \r
103 * read id command\r
104 */\r
105 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap);\r
106 \r
107 /*!\r
108 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process \r
109 * read all command\r
110 */\r
111 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap);\r
112 \r
113 /*!\r
114 * \brief \copydoc page_ovr Helper function for Topaz. This function depends on\r
115 * function called by the user\r
116 */\r
117 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap);\r
118 \r
119 /*!\r
120 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC \r
121 * bytes\r
122 */\r
123 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap);\r
124 \r
125 /*!\r
126 * \brief \copydoc page_ovr Helper function for Topaz. This function finds \r
127 * NDEF TLV\r
128 */\r
129 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap);\r
130 \r
131 /*!\r
132 * \brief \copydoc page_ovr Helper function for Topaz. This function writes a \r
133 * byte into the card\r
134 */\r
135 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,\r
136                                         uint16_t             BlockNo,\r
137                                         uint16_t             ByteNo,\r
138                                         uint8_t              ByteVal\r
139                                         );\r
140 \r
141 /*!\r
142 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the \r
143 * NMN write \r
144 */\r
145 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap);\r
146 \r
147 /*!\r
148 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the length field of\r
149 * the NDEF TLV\r
150 */\r
151 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap);\r
152 \r
153 /*!\r
154 * \brief \copydoc page_ovr Helper function for Topaz. This function updates length field \r
155 * of the NDEF TLV after complete write.\r
156 */\r
157 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t  *NdefMap);\r
158 \r
159 /*!\r
160 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the card data\r
161 *  to the user buffer\r
162 */\r
163 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf( phFriNfc_NdefMap_t  *NdefMap);\r
164 \r
165 /*!\r
166 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the \r
167 * written data\r
168 */\r
169 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData( phFriNfc_NdefMap_t  *NdefMap);\r
170 \r
171 /*!\r
172 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the block \r
173 * number is correct or not\r
174 */\r
175 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t  *NdefMap);\r
176 \r
177 /*!\r
178 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the 0th \r
179 * byte of block 1 has Zero\r
180 */\r
181 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t   *NdefMap);\r
182 \r
183 /*!\r
184 * \brief \copydoc page_ovr Helper function for Topaz. This function calls the \r
185 * completion routine\r
186 */\r
187 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t  *NdefMap,\r
188                                     NFCSTATUS           Status);\r
189 \r
190 /*!\r
191 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks \r
192 * the CC byte in check ndef function\r
193 */\r
194 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t  *NdefMap);\r
195 \r
196 /*!\r
197 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks \r
198 * the lock bits and set a card state\r
199 */\r
200 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t  *NdefMap);\r
201 \r
202 /*!\r
203 * \brief \copydoc page_ovr Helper function for Topaz. This function writes CC bytes or \r
204 * type of the TLV\r
205 */\r
206 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t  *NdefMap);\r
207 \r
208 #ifdef TOPAZ_RF_ERROR_WORKAROUND\r
209 \r
210 /*!\r
211 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written  \r
212 * value after the \r
213 */\r
214 static \r
215 NFCSTATUS \r
216 phFriNfc_Tpz_H_CheckWrittenData (\r
217     phFriNfc_NdefMap_t          *psNdefMap,\r
218     uint8_t                     state_rf_error);\r
219 \r
220 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */\r
221 \r
222 /*!\r
223 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written \r
224 * CC bytes are correct\r
225 */\r
226 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t  *NdefMap);\r
227 /*@}*/\r
228 void phFriNfc_TopazMap_H_Reset(phFriNfc_NdefMap_t        *NdefMap)\r
229 {\r
230     /* Initialising the Topaz structure variable */\r
231     NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_INVALID_OPE;\r
232     NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;\r
233     NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;\r
234     NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_VAL0;\r
235     (void)memset(NdefMap->TopazContainer.ReadBuffer, PH_FRINFC_TOPAZ_VAL0, \r
236                 sizeof(NdefMap->TopazContainer.ReadBuffer));\r
237     NdefMap->TopazContainer.ReadWriteCompleteFlag = PH_FRINFC_TOPAZ_FLAG0;\r
238     NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_VAL0;\r
239     (void)memset(NdefMap->TopazContainer.UID, PH_FRINFC_TOPAZ_VAL0, \r
240                 sizeof(NdefMap->TopazContainer.UID));\r
241     NdefMap->TopazContainer.Cur_RW_Index=0;\r
242     NdefMap->TopazContainer.ByteRWFrmCard =0;\r
243 }\r
244 \r
245 /*!\r
246 * \brief Check whether a particular Remote Device is NDEF compliant.\r
247 *\r
248 * The function checks whether the peer device is NDEF compliant.\r
249 *\r
250 * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t \r
251 *                    structure describing the component context.\r
252 *\r
253 * \retval  NFCSTATUS_PENDING   The action has been successfully triggered.\r
254 * \retval  Others              An error has occurred.\r
255 *\r
256 */\r
257 \r
258 NFCSTATUS phFriNfc_TopazMap_ChkNdef( phFriNfc_NdefMap_t     *NdefMap)\r
259 {\r
260     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, \r
261         NFCSTATUS_INVALID_PARAMETER);\r
262     if ( NdefMap != NULL)\r
263     {\r
264         /* Update the previous operation */\r
265         NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;\r
266         /* Update the CR index to know from which operation completion \r
267         routine has to be called */\r
268         NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;\r
269         NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;\r
270         NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;\r
271 \r
272         /* Set card state */\r
273         NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_CARD;\r
274 \r
275         /* Change the state to Check Ndef Compliant */\r
276         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID;\r
277         NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;\r
278 \r
279 #ifdef TOPAZ_RAW_SUPPORT\r
280         NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;  \r
281         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID;        \r
282 #else        \r
283 #ifdef PH_HAL4_ENABLE\r
284         NdefMap->Cmd.JewelCmd = phHal_eJewel_RID;   \r
285 #else\r
286         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid;\r
287 #endif\r
288 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
289         \r
290         Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,\r
291             NdefMap->TopazContainer.ByteNumber);\r
292     }\r
293     return Result;    \r
294 }\r
295 \r
296 #ifdef FRINFC_READONLY_NDEF\r
297 \r
298 NFCSTATUS \r
299 phFriNfc_TopazMap_ConvertToReadOnly (\r
300     phFriNfc_NdefMap_t          *NdefMap)\r
301 {\r
302     NFCSTATUS               result = NFCSTATUS_SUCCESS;\r
303 \r
304     result = phFriNfc_Tpz_H_WrAByte (NdefMap, CC_BLOCK_NUMBER, \r
305                                     CC_RWA_BYTE_NUMBER, CC_READ_ONLY_VALUE);\r
306 \r
307     if (NFCSTATUS_PENDING == PHNFCSTATUS(result))\r
308     {\r
309         NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE;\r
310     }\r
311     return result;\r
312 }\r
313 \r
314 #endif /* #ifdef FRINFC_READONLY_NDEF */\r
315 \r
316 /*!\r
317 * \brief Initiates Reading of NDEF information from the Remote Device.\r
318 *\r
319 * The function initiates the reading of NDEF information from a Remote Device.\r
320 * It performs a reset of the state and starts the action (state machine).\r
321 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action\r
322 * has been triggered.\r
323 */\r
324 NFCSTATUS phFriNfc_TopazMap_RdNdef( phFriNfc_NdefMap_t                  *NdefMap,\r
325                                         uint8_t                         *PacketData,\r
326                                         uint32_t                        *PacketDataLength,\r
327                                         uint8_t                         Offset)\r
328 {\r
329     NFCSTATUS               Result =    NFCSTATUS_SUCCESS;\r
330 \r
331     /* Copy user buffer to the context */\r
332     NdefMap->ApduBuffer = PacketData;\r
333     /* Copy user length to the context */\r
334     NdefMap->ApduBufferSize = *PacketDataLength;\r
335     /* Update the user memory size to a context variable */\r
336     NdefMap->NumOfBytesRead = PacketDataLength;\r
337     /* Number of bytes read from the card is zero. \r
338     This variable returns the number of bytes read \r
339     from the card. */\r
340     *NdefMap->NumOfBytesRead = PH_FRINFC_TOPAZ_VAL0;\r
341     /* Index to know the length read */\r
342     NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;    \r
343     /* Store the offset in the context */\r
344     NdefMap->Offset = Offset;\r
345     /* Update the CR index to know from which operation completion \r
346     routine has to be called */\r
347     NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF;\r
348 \r
349     if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation == \r
350         PH_FRINFC_NDEFMAP_WRITE_OPE))\r
351     {\r
352         /* If previous operation is not read then the read shall \r
353         start from BEGIN */\r
354         NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;\r
355         /* Initialise current block and byte number */\r
356         NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;\r
357         NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;\r
358         /* State has to be changed */\r
359         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;\r
360         NdefMap->TopazContainer.ReadWriteCompleteFlag = \r
361             PH_FRINFC_TOPAZ_FLAG0;\r
362         /* Topaz command = READALL */\r
363 #ifdef TOPAZ_RAW_SUPPORT\r
364         NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;\r
365         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;\r
366 #else     \r
367 \r
368 #ifdef PH_HAL4_ENABLE\r
369         NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;\r
370 #else\r
371         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;        \r
372 #endif\r
373 \r
374 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
375     }\r
376     \r
377     NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;\r
378     /* Offset = Current, but the read has reached the End of Card */\r
379     if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&\r
380         (NdefMap->TopazContainer.ReadWriteCompleteFlag == \r
381         PH_FRINFC_TOPAZ_FLAG1))\r
382     {\r
383         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, \r
384             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); \r
385     }\r
386     else\r
387     {\r
388         /* if the offset is begin then call READALL else copy the data \r
389         from the user buffer */\r
390         Result = ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?\r
391             phFriNfc_Tpz_H_RdBytes(NdefMap,\r
392             NdefMap->TopazContainer.CurrentBlock,\r
393             NdefMap->TopazContainer.ByteNumber):\r
394         phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap));\r
395     }\r
396 \r
397     return Result;\r
398 }\r
399 \r
400 /*!\r
401 * \brief Initiates Writing of NDEF information to the Remote Device.\r
402 *\r
403 * The function initiates the writing of NDEF information to a Remote Device.\r
404 * It performs a reset of the state and starts the action (state machine).\r
405 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action\r
406 * has been triggered.\r
407 */\r
408 NFCSTATUS phFriNfc_TopazMap_WrNdef( phFriNfc_NdefMap_t     *NdefMap,\r
409                                    uint8_t                 *PacketData,\r
410                                    uint32_t                *PacketDataLength,\r
411                                    uint8_t                 Offset)\r
412 {\r
413     NFCSTATUS                   Result =    NFCSTATUS_SUCCESS;\r
414     uint8_t TempByteVal = 0;\r
415     /* Copy user buffer to the context */\r
416     NdefMap->ApduBuffer = PacketData;\r
417     /* Copy user length to the context */\r
418     NdefMap->ApduBufferSize = *PacketDataLength;\r
419     /* Index to know the length written */\r
420     NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;\r
421     /* Update the user memory size to a context variable */\r
422     NdefMap->WrNdefPacketLength = PacketDataLength;\r
423     /* Number of bytes written to the card is zero. \r
424     This variable returns the number of bytes written \r
425     to the card. */\r
426     *NdefMap->WrNdefPacketLength = PH_FRINFC_TOPAZ_VAL0;\r
427     /* Update the CR index to know from which operation completion \r
428     routine has to be called */\r
429     NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF;\r
430     /* Store the offset in the context */\r
431     NdefMap->Offset = Offset;\r
432 \r
433 \r
434     if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || \r
435         (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))\r
436     {\r
437         NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;\r
438         /* Initialise current block and byte number */\r
439         NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;\r
440         NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;\r
441         /* State has to be changed */\r
442         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;\r
443         /* Topaz command = READALL */\r
444 \r
445 #ifdef TOPAZ_RAW_SUPPORT\r
446         NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;\r
447         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;\r
448 #else\r
449 #ifdef PH_HAL4_ENABLE\r
450         NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;\r
451 #else\r
452         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;\r
453 #endif\r
454 #endif  /* #ifdef TOPAZ_RAW_SUPPORT */      \r
455         NdefMap->TopazContainer.ReadWriteCompleteFlag = \r
456             PH_FRINFC_TOPAZ_FLAG0;\r
457         NdefMap->TopazContainer.RemainingSize = NdefMap->CardMemSize;        \r
458         TempByteVal = NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1];\r
459     }\r
460     else\r
461     {\r
462         /* State has to be changed */\r
463         NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;\r
464         /* copy the user data to write into the card */\r
465         TempByteVal = NdefMap->ApduBuffer[NdefMap->ApduBuffIndex];\r
466     } \r
467 \r
468     /* Update the previous operation to write operation */\r
469     NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;\r
470     if((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&\r
471         (NdefMap->TopazContainer.ReadWriteCompleteFlag == \r
472         PH_FRINFC_TOPAZ_FLAG1))\r
473     {\r
474         /* Offset = Current, but the read has reached the End of Card */\r
475         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, \r
476             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); \r
477     }\r
478     else\r
479     {\r
480         /* Check the block */\r
481         phFriNfc_Tpz_H_BlkChk(NdefMap);\r
482         /* if offset is begin then call READALL else start writing */\r
483         Result = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?\r
484             phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,\r
485             NdefMap->TopazContainer.ByteNumber):\r
486             phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock,\r
487             NdefMap->TopazContainer.ByteNumber,TempByteVal));\r
488     }\r
489 \r
490     return Result;\r
491 }\r
492 \r
493 \r
494 /*!\r
495 * \brief Completion Routine, Processing function, needed to avoid long blocking.\r
496 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion\r
497 *       Routine in order to be able to notify the component that an I/O has finished and data are\r
498 *       ready to be processed.\r
499 *\r
500 */\r
501 \r
502 void phFriNfc_TopazMap_Process( void       *Context,\r
503                                NFCSTATUS   Status)\r
504 {\r
505 \r
506     phFriNfc_NdefMap_t              *psNdefMap = NULL;\r
507 \r
508 #ifdef TOPAZ_RF_ERROR_WORKAROUND\r
509 \r
510     static uint8_t                  rf_error_state = 0;\r
511 \r
512 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */\r
513 #ifdef FRINFC_READONLY_NDEF\r
514     static uint8_t                  written_lock_byte = 0;\r
515 #endif /* #ifdef FRINFC_READONLY_NDEF */\r
516 \r
517     psNdefMap = (phFriNfc_NdefMap_t *)Context;\r
518 \r
519     if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER))\r
520     {\r
521         switch (psNdefMap->State)\r
522         {\r
523 #ifdef FRINFC_READONLY_NDEF\r
524             case PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE:\r
525             {\r
526                 if((CC_READ_ONLY_VALUE == *psNdefMap->SendRecvBuf)  \r
527                     && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))\r
528                 {\r
529                     written_lock_byte = 0;\r
530 #ifdef TOPAZ_RAW_SUPPORT\r
531                     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;\r
532 #else\r
533 #ifdef PH_HAL4_ENABLE\r
534                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;\r
535 #else\r
536                     psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;\r
537 #endif /* #ifdef PH_HAL4_ENABLE */\r
538 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
539                     Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER, \r
540                                                     LOCK0_BYTE_NUMBER);\r
541 \r
542                     if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))\r
543                     {\r
544                         psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE;\r
545                     }\r
546                 }\r
547                 else\r
548                 {\r
549                     Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
550                                         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
551                 }\r
552                 break;\r
553             }\r
554 \r
555             case PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE:\r
556             {\r
557                 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)\r
558                 {\r
559                     Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER, \r
560                                                 LOCK0_BYTE_NUMBER, \r
561                                                 LOCK0_BYTE_VALUE);\r
562 \r
563                     if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))\r
564                     {\r
565                         psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE;\r
566                     }\r
567                 }\r
568                 break;\r
569             }\r
570 \r
571             case PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE:\r
572             {\r
573                 if((LOCK0_BYTE_VALUE == *psNdefMap->SendRecvBuf)  \r
574                     && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))\r
575                 {\r
576 #ifdef TOPAZ_RAW_SUPPORT\r
577                     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;\r
578 #else\r
579 #ifdef PH_HAL4_ENABLE\r
580                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;\r
581 #else\r
582                     psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;\r
583 #endif /* #ifdef PH_HAL4_ENABLE */\r
584 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
585                     Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER, \r
586                                                     LOCK1_BYTE_NUMBER);\r
587 \r
588                     if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))\r
589                     {\r
590                         psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE;\r
591                     }\r
592                 }\r
593                 else\r
594                 {\r
595                     Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
596                                         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
597                 }\r
598             }\r
599 \r
600             case PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE:\r
601             {\r
602                 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)\r
603                 {\r
604                     written_lock_byte = (uint8_t)(*psNdefMap->SendRecvBuf | LOCK1_BYTE_VALUE);\r
605                     Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER, \r
606                                                 LOCK1_BYTE_NUMBER, \r
607                                                 written_lock_byte);\r
608 \r
609                     if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))\r
610                     {\r
611                         psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE;\r
612                     }\r
613                 }\r
614                 break;\r
615             }\r
616 \r
617             case PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE:\r
618             {\r
619                 if((written_lock_byte == *psNdefMap->SendRecvBuf)  \r
620                     && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))\r
621                 {\r
622                     written_lock_byte = 0;\r
623                     /* Do nothing */\r
624                 }\r
625                 else\r
626                 {\r
627                     written_lock_byte = 0;\r
628                     Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
629                                         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
630                 }\r
631             }\r
632 #endif /* #ifdef FRINFC_READONLY_NDEF */\r
633             case PH_FRINFC_TOPAZ_STATE_WRITE:\r
634             {\r
635                 Status = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);\r
636                 break;\r
637             }\r
638 \r
639             case PH_FRINFC_TOPAZ_STATE_READID:\r
640             {\r
641                 Status = phFriNfc_Tpz_H_ProReadID (psNdefMap);\r
642                 break;\r
643             }\r
644 \r
645             case PH_FRINFC_TOPAZ_STATE_READALL:\r
646             {\r
647                 Status = phFriNfc_Tpz_H_ProReadAll (psNdefMap);\r
648                 break;\r
649             }\r
650 \r
651             case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:\r
652             {\r
653                 Status = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);\r
654                 break;\r
655             }\r
656 \r
657             case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:\r
658             {\r
659                 Status = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);\r
660                 break;\r
661             }\r
662 \r
663             case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:\r
664             {\r
665                 Status = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);\r
666                 break;\r
667             }\r
668 \r
669 #ifdef TOPAZ_RF_ERROR_WORKAROUND\r
670 \r
671             case PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ:\r
672             {\r
673                 Status = phFriNfc_Tpz_H_CheckWrittenData (psNdefMap, \r
674                                                         rf_error_state);\r
675                 break;\r
676             }\r
677 \r
678 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */\r
679 \r
680             default:\r
681             {\r
682                 Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP,\r
683                                     NFCSTATUS_INVALID_DEVICE_REQUEST);\r
684                 break;\r
685             }\r
686         }\r
687     }\r
688     else\r
689     {\r
690 #ifdef TOPAZ_RF_ERROR_WORKAROUND\r
691 \r
692         if ((FRINFC_RF_TIMEOUT_89 == PHNFCSTATUS (Status)) || \r
693             (FRINFC_RF_TIMEOUT_90 == PHNFCSTATUS (Status)) || \r
694             (NFCSTATUS_RF_TIMEOUT == PHNFCSTATUS (Status)))\r
695         {\r
696             uint8_t             byte_number = 0;\r
697             uint8_t             block_number = 0;\r
698 \r
699             rf_error_state = psNdefMap->State;\r
700 \r
701 #ifdef TOPAZ_RAW_SUPPORT\r
702 \r
703             *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;\r
704 \r
705 #else\r
706 \r
707 #ifdef PH_HAL4_ENABLE\r
708 \r
709             psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;\r
710 \r
711 #else\r
712 \r
713             psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;\r
714 \r
715 #endif /* #ifdef PH_HAL4_ENABLE */\r
716 \r
717 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
718 \r
719             /* Update the state variable to the new work around state*/\r
720             psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ;\r
721 \r
722             /* Switch is used to know, if the error occured during WRITE or READ */\r
723             switch (rf_error_state)\r
724             {\r
725                 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:\r
726                 {                    \r
727                     /* Block and byte number is updated for NMN */\r
728                     byte_number = PH_FRINFC_TOPAZ_VAL0;\r
729                     block_number = PH_FRINFC_TOPAZ_VAL1;\r
730                     break;\r
731                 }\r
732 \r
733                 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:\r
734                 {\r
735                     /* Get the L field of the TLV block */\r
736                     block_number = (uint8_t)(((psNdefMap->TLVStruct.NdefTLVByte + \r
737                                         PH_FRINFC_TOPAZ_VAL1) > \r
738                                         PH_FRINFC_TOPAZ_VAL7)?\r
739                                         (psNdefMap->TLVStruct.NdefTLVBlock + \r
740                                         PH_FRINFC_TOPAZ_VAL1):\r
741                                         psNdefMap->TLVStruct.NdefTLVBlock);\r
742                     /* Get the L byte */\r
743                     byte_number = (uint8_t)((psNdefMap->TLVStruct.NdefTLVByte + \r
744                                         PH_FRINFC_TOPAZ_VAL1) % \r
745                                         PH_FRINFC_TOPAZ_VAL8);\r
746                     break;\r
747                 }\r
748 \r
749                 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:\r
750                 {\r
751                     switch (psNdefMap->TopazContainer.InternalState)\r
752                     {\r
753                         case PH_FRINFC_TOPAZ_WR_CC_BYTE0:\r
754                         {\r
755                             /* Block and byte number is updated for the CC byte 0 */\r
756                             block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;\r
757                             byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL0;\r
758                             break;\r
759                         }\r
760 \r
761                         case PH_FRINFC_TOPAZ_WR_CC_BYTE1:\r
762                         {\r
763                             /* Block and byte number is updated for the CC byte 1 */\r
764                             block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;\r
765                             byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;\r
766                             break;\r
767                         }\r
768 \r
769                         case PH_FRINFC_TOPAZ_WR_CC_BYTE2:\r
770                         {\r
771                             /* Block and byte number is updated for the CC byte 2 */\r
772                             block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;\r
773                             byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL2;\r
774                             break;\r
775                         }\r
776 \r
777                         case PH_FRINFC_TOPAZ_WR_CC_BYTE3:\r
778                         {\r
779                             /* Block and byte number is updated for the CC byte 3 */\r
780                             block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;\r
781                             byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL3;\r
782                             break;\r
783                         }\r
784 \r
785                         case PH_FRINFC_TOPAZ_WR_T_OF_TLV:\r
786                         {\r
787                             /* Block and byte number is updated for the Type field of the TLV */\r
788                             block_number = psNdefMap->TLVStruct.NdefTLVBlock;\r
789                             byte_number = (uint8_t)psNdefMap->TLVStruct.NdefTLVByte;\r
790                             break;\r
791                         }\r
792 \r
793                         default:\r
794                         {\r
795                             /* Do nothing */\r
796                             break;\r
797                         }\r
798                     } /* switch (psNdefMap->TopazContainer.InternalState) */\r
799                     break;\r
800                 }\r
801 \r
802                 case PH_FRINFC_TOPAZ_STATE_WRITE:                \r
803                 {\r
804                     /* Block and byte number is updated for the written error data */                    \r
805                     block_number = psNdefMap->TopazContainer.CurrentBlock;\r
806                     byte_number = psNdefMap->TopazContainer.ByteNumber;                  \r
807                     break;\r
808                 }\r
809 \r
810                 default:\r
811                 {\r
812                     /* Error occured is not during WRITE, so update \r
813                         state variable to the previous state */\r
814                     psNdefMap->State = rf_error_state;\r
815                     break;\r
816                 }\r
817             } /* switch (rf_error_state) */\r
818 \r
819             /* The below check is added, to know if the error is for \r
820             the WRITE or READ scenario, \r
821             If the error is for READ, then state variable is not updated\r
822             If the error is for WRITE, then state variable is updated with \r
823             PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ value */\r
824             if (PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ == psNdefMap->State)\r
825             {\r
826                 /* Read the data with the updated block and byte number */\r
827                 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, block_number, \r
828                                                 byte_number);\r
829             }\r
830         }\r
831 \r
832 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */\r
833     }\r
834 \r
835     /* Call Completion Routine, if Status != PENDING */\r
836     if (NFCSTATUS_PENDING != Status)\r
837     {\r
838         phFriNfc_Tpz_H_Complete(psNdefMap, Status);\r
839     }\r
840 }\r
841 \r
842 \r
843 #ifdef TOPAZ_RF_ERROR_WORKAROUND\r
844 \r
845 static \r
846 NFCSTATUS \r
847 phFriNfc_Tpz_H_CheckWrittenData (\r
848     phFriNfc_NdefMap_t          *psNdefMap,\r
849     uint8_t                     state_rf_error)\r
850 {\r
851     NFCSTATUS   result = NFCSTATUS_SUCCESS;\r
852 \r
853     switch (state_rf_error)\r
854     {\r
855         case PH_FRINFC_TOPAZ_STATE_WRITE:\r
856         {\r
857             result = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);\r
858             break;\r
859         }\r
860 \r
861         case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:\r
862         {\r
863             result = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);\r
864             break;\r
865         }\r
866 \r
867         case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:\r
868         {\r
869             result = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);\r
870             break;\r
871         }\r
872 \r
873         case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:\r
874         {\r
875             result = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);\r
876             break;\r
877         }\r
878 \r
879         default:\r
880         {\r
881             break;\r
882         }\r
883     }\r
884 \r
885     return result;\r
886 }\r
887 \r
888 \r
889 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */\r
890 \r
891 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,\r
892                                         uint16_t             BlockNo,\r
893                                         uint16_t            ByteNo)\r
894 {\r
895     NFCSTATUS   Result = NFCSTATUS_SUCCESS;\r
896 #ifdef TOPAZ_RAW_SUPPORT\r
897     uint8_t index = 0;\r
898 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
899 \r
900     /* set the data for additional data exchange*/\r
901     NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;\r
902     NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;\r
903     NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;\r
904 \r
905     NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;\r
906     NdefMap->MapCompletionInfo.Context = NdefMap;\r
907 \r
908     *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;\r
909 \r
910     /* Depending on the jewel command, the send length is decided */\r
911 #ifdef TOPAZ_RAW_SUPPORT\r
912     switch(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0])\r
913 #else\r
914     switch(NdefMap->Cmd.JewelCmd)\r
915 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
916     {\r
917 \r
918 #ifdef TOPAZ_RAW_SUPPORT\r
919     case PH_FRINFC_TOPAZ_CMD_READID:\r
920 #else\r
921 #ifdef PH_HAL4_ENABLE\r
922     case phHal_eJewel_RID:\r
923 #else\r
924     case phHal_eJewelCmdListJewelRid:\r
925 #endif\r
926 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
927 \r
928 #ifdef TOPAZ_RAW_SUPPORT\r
929         NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;\r
930         /*Copy command to  Send Buffer*/\r
931         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0]  = PH_FRINFC_TOPAZ_CMD_READID;\r
932         index ++;        \r
933 \r
934         /*Copy UID of the tag to  Send Buffer*/\r
935         (void)memset(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1]),\r
936         0x00,(0x06));\r
937         index = index + 0x06;\r
938 \r
939         /* Update the length of the command buffer*/\r
940         NdefMap->SendLength = index;\r
941 #else\r
942         /* For READ ID and READ ALL, send length is 0 */\r
943         NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;\r
944 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
945         break;\r
946 \r
947 #ifdef TOPAZ_RAW_SUPPORT\r
948     case PH_FRINFC_TOPAZ_CMD_READALL:\r
949 #else\r
950 #ifdef PH_HAL4_ENABLE\r
951     case phHal_eJewel_ReadAll:  \r
952 #else\r
953     case phHal_eJewelCmdListJewelReadAll:\r
954 #endif\r
955 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
956 \r
957 #ifdef TOPAZ_RAW_SUPPORT\r
958         NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;\r
959         /*Copy command to  Send Buffer*/\r
960         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0]  = PH_FRINFC_TOPAZ_CMD_READALL;\r
961         index ++;\r
962 \r
963         /*Copy 0x00 to Send Buffer*/\r
964         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00;\r
965         index ++;\r
966         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;\r
967         index ++;\r
968 \r
969         /*Copy UID of the tag to  Send Buffer*/\r
970         (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),\r
971         &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),\r
972         TOPAZ_UID_LENGTH_FOR_READ_WRITE);\r
973 \r
974         index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);\r
975 \r
976         /* Update the length of the command buffer*/\r
977         NdefMap->SendLength = index;\r
978 #else\r
979        /* For READ ID and READ ALL, send length is 0 */\r
980         NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;\r
981 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
982         break;\r
983 \r
984 #ifdef TOPAZ_RAW_SUPPORT\r
985     case PH_FRINFC_TOPAZ_CMD_READ:\r
986 #else\r
987 #ifdef PH_HAL4_ENABLE\r
988     case phHal_eJewel_Read1:\r
989 #else\r
990     case phHal_eJewelCmdListJewelRead1:\r
991 #endif \r
992 \r
993 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
994 \r
995 #ifdef TOPAZ_RAW_SUPPORT\r
996         NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;\r
997         /*Copy command to  Send Buffer*/\r
998         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0]  = PH_FRINFC_TOPAZ_CMD_READ;\r
999         index ++;\r
1000 \r
1001         /*Copy Address to  Send Buffer*/\r
1002         /* Calculate send length \r
1003         7 | 6   5   4   3 | 2   1   0 | \r
1004         |    block no   |  byte no  | \r
1005         */\r
1006         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = \r
1007                 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + \r
1008                 ByteNo);\r
1009         index ++;\r
1010         /*Copy 0x00 to  Send Buffer*/\r
1011         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;\r
1012         index ++;\r
1013 \r
1014         /*Copy UID of the tag to  Send Buffer*/\r
1015         (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),\r
1016         &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),\r
1017         TOPAZ_UID_LENGTH_FOR_READ_WRITE);\r
1018         index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);\r
1019 \r
1020         /* Update the length of the command buffer*/\r
1021         NdefMap->SendLength = index;\r
1022 #else\r
1023         /* Calculate send length \r
1024         7 | 6   5   4   3 | 2   1   0 | \r
1025         |    block no   |  byte no  | \r
1026         */\r
1027         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = \r
1028                 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + \r
1029                 ByteNo);\r
1030         NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL1;\r
1031 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
1032         \r
1033         break;\r
1034 #ifdef TOPAZ_RAW_SUPPORT\r
1035 #else\r
1036 #ifdef PH_HAL4_ENABLE\r
1037     case phHal_eJewel_Read:\r
1038         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = 0x00;\r
1039         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00;\r
1040         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 104;\r
1041         NdefMap->SendLength = 3;\r
1042     break;\r
1043 #endif\r
1044 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
1045 \r
1046     default:\r
1047         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1048                             NFCSTATUS_INVALID_DEVICE_REQUEST);\r
1049     }\r
1050 \r
1051     if(Result == NFCSTATUS_SUCCESS)\r
1052     {\r
1053         /* Call the Overlapped HAL Transceive function */ \r
1054         Result = phFriNfc_OvrHal_Transceive(    NdefMap->LowerDevice,\r
1055                                                 &NdefMap->MapCompletionInfo,\r
1056                                                 NdefMap->psRemoteDevInfo,\r
1057                                                 NdefMap->Cmd,\r
1058                                                 &NdefMap->psDepAdditionalInfo,\r
1059                                                 NdefMap->SendRecvBuf,\r
1060                                                 NdefMap->SendLength,\r
1061                                                 NdefMap->SendRecvBuf,\r
1062                                                 NdefMap->SendRecvLength);\r
1063     }\r
1064     return Result;\r
1065 }\r
1066 \r
1067 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,\r
1068                                         uint16_t             BlockNo,\r
1069                                         uint16_t             ByteNo,\r
1070                                         uint8_t              ByteVal\r
1071                                         )\r
1072 {\r
1073     NFCSTATUS   Result = NFCSTATUS_SUCCESS;\r
1074     uint8_t     index = 0;\r
1075 \r
1076     \r
1077     PHNFC_UNUSED_VARIABLE(ByteVal);\r
1078     /* set the data for additional data exchange*/\r
1079     NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;\r
1080     NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;\r
1081     NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;\r
1082 \r
1083     NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;\r
1084     NdefMap->MapCompletionInfo.Context = NdefMap;\r
1085 \r
1086     *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;\r
1087     /* Command used to write 1 byte */\r
1088 #ifdef TOPAZ_RAW_SUPPORT\r
1089     NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;\r
1090 #else\r
1091 #ifdef PH_HAL4_ENABLE\r
1092     NdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;\r
1093 #else\r
1094     NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelWriteErase1;\r
1095 #endif\r
1096 #endif /* #ifdef TOPAZ_RAW_SUPPORT */   \r
1097 \r
1098 #ifdef TOPAZ_RAW_SUPPORT\r
1099     /*Copy command to Send Buffer*/\r
1100     NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0]  = PH_FRINFC_TOPAZ_CMD_WRITE_1E;\r
1101     index ++;\r
1102 \r
1103     /*Copy Address to  Send Buffer*/\r
1104     /* Calculate send length \r
1105     7 | 6   5   4   3 | 2   1   0 | \r
1106     |    block no   |  byte no  | \r
1107     */\r
1108     NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = \r
1109             (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + \r
1110             ByteNo);\r
1111     index ++;\r
1112     /*Copy Data byte to Send Buffer*/\r
1113     NdefMap->SendRecvBuf[index] = ByteVal;\r
1114     index ++;\r
1115 \r
1116     /*Copy UID of the tag to  Send Buffer*/\r
1117     (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),\r
1118       &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),\r
1119       TOPAZ_UID_LENGTH_FOR_READ_WRITE);\r
1120     index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);\r
1121 \r
1122     /* Update the length of the command buffer*/\r
1123     NdefMap->SendLength = index;   \r
1124 \r
1125 #else\r
1126     /* Depending on the jewel command, the send length is decided */\r
1127     /* Calculate send length \r
1128     7 | 6   5   4   3 | 2   1   0 | \r
1129     |    block no   |  byte no  | \r
1130     */\r
1131     NdefMap->SendRecvBuf[index] = \r
1132                         (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + \r
1133                         ByteNo);\r
1134     index ++;\r
1135     NdefMap->SendRecvBuf[index] = ByteVal;\r
1136     index ++;\r
1137     NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL2;\r
1138 \r
1139 #endif /* #ifdef TOPAZ_RAW_SUPPORT */\r
1140 \r
1141     /* Call the Overlapped HAL Transceive function */ \r
1142     Result = phFriNfc_OvrHal_Transceive(    NdefMap->LowerDevice,\r
1143                                             &NdefMap->MapCompletionInfo,\r
1144                                             NdefMap->psRemoteDevInfo,\r
1145                                             NdefMap->Cmd,\r
1146                                             &NdefMap->psDepAdditionalInfo,\r
1147                                             NdefMap->SendRecvBuf,\r
1148                                             NdefMap->SendLength,\r
1149                                             NdefMap->SendRecvBuf,\r
1150                                             NdefMap->SendRecvLength);\r
1151 \r
1152     return Result;\r
1153 }\r
1154 \r
1155 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap)\r
1156 {\r
1157     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1158         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
1159     \r
1160     if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] & \r
1161         PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) && \r
1162         (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL6))\r
1163     {\r
1164         /* Copy UID to the context, Used when the READ ALL command is used */\r
1165         (void)memcpy(NdefMap->TopazContainer.UID, \r
1166             &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],\r
1167             PH_FRINFC_TOPAZ_VAL4);\r
1168 \r
1169         /* State has to be changed */\r
1170         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;\r
1171         /* Topaz command = READALL */\r
1172 #ifdef TOPAZ_RAW_SUPPORT\r
1173         NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;\r
1174         NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;\r
1175 #else \r
1176 #ifdef PH_HAL4_ENABLE\r
1177         NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;\r
1178 #else\r
1179         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;\r
1180 #endif\r
1181 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ \r
1182     \r
1183         /* Read all bytes from the card */\r
1184         Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,\r
1185             NdefMap->TopazContainer.ByteNumber);\r
1186     }\r
1187 \r
1188     return Result;\r
1189 }\r
1190 \r
1191 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap)\r
1192 {\r
1193     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1194         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
1195     int32_t     memcompare = PH_FRINFC_TOPAZ_VAL0;\r
1196     \r
1197     /* Compare the UID of READ ALL command with the stored UID */\r
1198 #ifdef PH_HAL4_ENABLE\r
1199     if ((NdefMap->TopazContainer.UID[0] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2]) &&\r
1200         (NdefMap->TopazContainer.UID[1] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 1]) &&\r
1201         (NdefMap->TopazContainer.UID[2] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 2]) &&\r
1202         (NdefMap->TopazContainer.UID[3] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 3]))\r
1203     {\r
1204         memcompare = PH_FRINFC_TOPAZ_VAL0;\r
1205     }\r
1206     else\r
1207     {\r
1208         memcompare = PH_FRINFC_TOPAZ_VAL1;\r
1209     }\r
1210 #else\r
1211     memcompare = memcmp(NdefMap->TopazContainer.UID, \r
1212         &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],\r
1213         PH_FRINFC_TOPAZ_VAL4);  \r
1214 #endif /* #ifdef PH_HAL4_ENABLE */\r
1215 \r
1216     if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] & \r
1217         PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) && \r
1218         (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_READALL_RESP) && \r
1219         (memcompare == PH_FRINFC_TOPAZ_VAL0))\r
1220     {\r
1221         /* Copy 96 bytes from the read/write memory space */\r
1222         (void)memcpy(NdefMap->TopazContainer.ReadBuffer, \r
1223             &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL10],\r
1224             PH_FRINFC_TOPAZ_TOTAL_RWBYTES);\r
1225 \r
1226         /* Check the lock bits and set the card state */\r
1227         phFriNfc_Tpz_H_ChkLockBits(NdefMap);\r
1228 \r
1229         Result = phFriNfc_Tpz_H_CallNxtOp(NdefMap);\r
1230     }\r
1231     return Result;\r
1232 }\r
1233 \r
1234 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap)\r
1235 {\r
1236     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1237         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
1238     /* Depending on the operation (check, read or write ndef), process the  \r
1239     read data */\r
1240     switch(NdefMap->PrevOperation)\r
1241     {\r
1242     case PH_FRINFC_NDEFMAP_CHECK_OPE:\r
1243         /* Check the capabilty container values, according \r
1244         to the spec */\r
1245         Result = phFriNfc_Tpz_H_ChkCCinChkNdef(NdefMap);\r
1246 \r
1247         if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INVALID)\r
1248         {\r
1249             /* Check the spec version */\r
1250             Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap,\r
1251                 NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]);\r
1252             /*  Check the CC header size: Only valid ones are\r
1253             0x0C for 96 bytes. */\r
1254             if ((Result == NFCSTATUS_SUCCESS) && \r
1255                 ( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] <=  \r
1256                 PH_FRINFC_TOPAZ_CC_BYTE2_MAX))\r
1257             {\r
1258                 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap);\r
1259                 /* As there is possibility of either having or not having TLV in \r
1260                 Topaz, no need to send the Actual status to the context*/\r
1261                 Result = NFCSTATUS_SUCCESS;\r
1262             }\r
1263         }\r
1264         else\r
1265         {\r
1266             Result = NFCSTATUS_SUCCESS;\r
1267             NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;\r
1268             NdefMap->CardMemSize = \r
1269             NdefMap->TopazContainer.RemainingSize = (uint16_t)\r
1270                         /* \r
1271                         4 is decremented from the max size because of the 4 CC bytes\r
1272                         2 is decremented because of the NDEF TLV T and L byte \r
1273                         to get the actual data size\r
1274                         */\r
1275                         (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4 - \r
1276                         PH_FRINFC_TOPAZ_VAL2);\r
1277         }\r
1278         break;\r
1279 \r
1280     case PH_FRINFC_NDEFMAP_READ_OPE:\r
1281         /* Check the capabilty container values, according \r
1282         to the spec */\r
1283         Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);\r
1284 \r
1285         /* If success, find the ndef TLV */\r
1286         Result = ((Result != NFCSTATUS_SUCCESS)?\r
1287                 (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1288                 NFCSTATUS_INVALID_FORMAT)):\r
1289                 phFriNfc_Tpz_H_findNDEFTLV(NdefMap));\r
1290 \r
1291         if(Result == NFCSTATUS_SUCCESS)\r
1292         {\r
1293             NdefMap->TopazContainer.ByteNumber += PH_FRINFC_TOPAZ_VAL2;\r
1294             /* If success, copy the read bytes to the user buffer */\r
1295             Result = phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap);\r
1296         }\r
1297         break;\r
1298 \r
1299     case PH_FRINFC_NDEFMAP_WRITE_OPE:\r
1300     default:\r
1301         if((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE) || \r
1302             (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED))\r
1303         {\r
1304             /* Check the capabilty container values, according \r
1305             to the spec */\r
1306             Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);\r
1307             if(Result == NFCSTATUS_SUCCESS)\r
1308             {\r
1309                 /* Find the NDEF TLV */\r
1310                 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap);\r
1311                 \r
1312                 /* Write the TLV */\r
1313                 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;\r
1314             }\r
1315             else\r
1316             {\r
1317                 NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4;\r
1318                 NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1;\r
1319                 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4;\r
1320                 /* Write the TLV */\r
1321                 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE0;\r
1322             }\r
1323             /* Write CC bytes */ \r
1324             Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);\r
1325         }\r
1326         break;\r
1327     }\r
1328     return Result;\r
1329 }\r
1330 \r
1331 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap)\r
1332 {\r
1333     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1334         NFCSTATUS_NO_NDEF_SUPPORT);\r
1335 \r
1336     if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] == \r
1337         PH_FRINFC_TOPAZ_CC_BYTE0)\r
1338     {\r
1339         /* Check the spec version */\r
1340         Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap,\r
1341             NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]);\r
1342         /*  Check the CC header size: Only valid ones are\r
1343         0x0C for 96 bytes. */\r
1344         Result = ((( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] >  \r
1345                     PH_FRINFC_TOPAZ_CC_BYTE2_MAX) || (Result != \r
1346                     NFCSTATUS_SUCCESS))?\r
1347                     (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, \r
1348                     NFCSTATUS_EOF_NDEF_CONTAINER_REACHED)):\r
1349                     Result);\r
1350 \r
1351         /* Get the read/write card memory size */\r
1352         NdefMap->TopazContainer.RemainingSize = \r
1353                 NdefMap->CardMemSize = ((Result == NFCSTATUS_SUCCESS)?\r
1354                 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4):\r
1355                 NdefMap->CardMemSize);\r
1356 \r
1357         /* if the call is from write ndef then check for read write access */\r
1358         if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) && \r
1359             (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] != \r
1360             PH_FRINFC_TOPAZ_CC_BYTE3_RW) && (Result == NFCSTATUS_SUCCESS)))\r
1361         {\r
1362             Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1363                                 NFCSTATUS_INVALID_FORMAT));\r
1364         }\r
1365 \r
1366         /* if the call is from read ndef then check for read only or read write access */\r
1367         if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) && \r
1368             ((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] != \r
1369             PH_FRINFC_TOPAZ_CC_BYTE3_RW) && \r
1370             (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] != \r
1371             PH_FRINFC_TOPAZ_CC_BYTE3_RO))&& (Result == NFCSTATUS_SUCCESS)))\r
1372         {\r
1373             Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1374                                 NFCSTATUS_INVALID_FORMAT));\r
1375         }\r
1376     }\r
1377     return Result;\r
1378 }\r
1379 \r
1380 extern NFCSTATUS phFriNfc_Tpz_H_ChkSpcVer( phFriNfc_NdefMap_t  *NdefMap,\r
1381                                           uint8_t             VersionNo)\r
1382 {\r
1383     NFCSTATUS Result = NFCSTATUS_SUCCESS;\r
1384     uint8_t TagVerNo = VersionNo;\r
1385 \r
1386     /* To remove "warning (VS C4100) : unreferenced formal parameter" */\r
1387     PHNFC_UNUSED_VARIABLE(NdefMap);\r
1388 \r
1389     if ( TagVerNo == 0 )\r
1390     {\r
1391         /*Return Status Error \93 Invalid Format\94*/\r
1392         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);\r
1393     }\r
1394     else\r
1395     {\r
1396         /* calculate the major and minor version number of T3VerNo */\r
1397         if( (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == \r
1398             PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&&\r
1399             ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM >= \r
1400             PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo))) ||\r
1401             (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == \r
1402             PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&&\r
1403             ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM < \r
1404             PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo) )))\r
1405         {\r
1406             Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);\r
1407         }\r
1408         else \r
1409         {\r
1410             if (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM <\r
1411                 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo) ) ||\r
1412                 ( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM > \r
1413                 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)))\r
1414             {\r
1415                 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);\r
1416             }\r
1417         }\r
1418     }\r
1419     return Result;\r
1420 }\r
1421 \r
1422 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap)\r
1423 {\r
1424     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1425         NFCSTATUS_NO_NDEF_SUPPORT);\r
1426     uint8_t     index = PH_FRINFC_TOPAZ_VAL4;\r
1427 \r
1428     /* If remaining size is less than 3 then, there cant be any \r
1429     TLV present in the card */\r
1430     while((index < PH_FRINFC_TOPAZ_TOTAL_RWBYTES) && \r
1431         (NdefMap->TopazContainer.RemainingSize >= PH_FRINFC_TOPAZ_VAL3))\r
1432     {\r
1433         switch(NdefMap->TopazContainer.ReadBuffer[index])\r
1434         {\r
1435         case PH_FRINFC_TOPAZ_NDEF_T:\r
1436             /* To get the length field of the TLV */\r
1437             index++;\r
1438             /* Type and length are not data bytes, so to know the exact\r
1439             remaining size in the card, the below operation is done */\r
1440             NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2;\r
1441             /* Set the card state depending on the L value */\r
1442             Result = phFriNfc_MapTool_SetCardState(NdefMap, \r
1443                 (uint32_t)NdefMap->TopazContainer.ReadBuffer[index]);\r
1444             /* Check the TLV is correct */\r
1445             if((NdefMap->TopazContainer.ReadBuffer[index] > \r
1446                 NdefMap->TopazContainer.RemainingSize) || \r
1447                 ((NdefMap->TopazContainer.ReadBuffer[index] == \r
1448                 PH_FRINFC_TOPAZ_VAL0) && (NdefMap->PrevOperation == \r
1449                 PH_FRINFC_NDEFMAP_READ_OPE)) || (Result != NFCSTATUS_SUCCESS))\r
1450             {\r
1451                 /* L field value cant be greater than the remaining size, so error */\r
1452                 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1453                                     NFCSTATUS_NO_NDEF_SUPPORT);\r
1454                 /* To break out of the loop */\r
1455                 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;\r
1456             }\r
1457             else\r
1458             {\r
1459                 /* So remaining size also changes, according to the position of NDEF TLV  */\r
1460                 NdefMap->TLVStruct.BytesRemainLinTLV = \r
1461                     NdefMap->TopazContainer.ReadBuffer[index];\r
1462 \r
1463                 /* Get the byte number */\r
1464                 NdefMap->TLVStruct.NdefTLVByte = (uint16_t)((index - PH_FRINFC_TOPAZ_VAL1) % \r
1465                                                     PH_FRINFC_TOPAZ_VAL8);\r
1466                 /* Get the block number */\r
1467                 NdefMap->TLVStruct.NdefTLVBlock = (uint8_t)(((index - PH_FRINFC_TOPAZ_VAL1) / \r
1468                                                     PH_FRINFC_TOPAZ_VAL8) + \r
1469                                                     PH_FRINFC_TOPAZ_VAL1);\r
1470                 /* TLV found flag is set */\r
1471                 NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_TOPAZ_FLAG1;\r
1472                 /* To know the position of V field in the TLV */\r
1473                 NdefMap->TopazContainer.ByteNumber = (uint8_t)(((NdefMap->TLVStruct.NdefTLVBlock - 1) * 8) +\r
1474                                                     NdefMap->TLVStruct.NdefTLVByte);\r
1475                 /* To break out of the loop */\r
1476                 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;\r
1477                 Result = NFCSTATUS_SUCCESS;\r
1478             }\r
1479             break;\r
1480 \r
1481         case PH_FRINFC_TOPAZ_NULL_T:\r
1482             /* Null TLV, Skip the TLV */\r
1483             NdefMap->TopazContainer.RemainingSize--;\r
1484             index++;\r
1485             break;\r
1486 \r
1487         case PH_FRINFC_TOPAZ_TERM_T:\r
1488             /* No more TLV present in the card, so error */\r
1489             index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;\r
1490             Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1491                                 NFCSTATUS_NO_NDEF_SUPPORT);\r
1492             break;\r
1493 \r
1494         default:\r
1495             /* Go till the length field of the TLV */\r
1496             index++;\r
1497             /* Type and length is not the data, so to know the exact\r
1498             remaining size in the card, the below operation is done */\r
1499             NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2;\r
1500             if(NdefMap->TopazContainer.ReadBuffer[index] > \r
1501                 NdefMap->TopazContainer.RemainingSize)\r
1502             {\r
1503                 /* L field value cant be greater than the remaining size, so error */\r
1504                 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;\r
1505                 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1506                                     NFCSTATUS_NO_NDEF_SUPPORT);\r
1507             }\r
1508             else\r
1509             {\r
1510                 /* Remaining size of the free space available in the card changes, \r
1511                 according to the position of NDEF TLV */\r
1512                 NdefMap->TopazContainer.RemainingSize = \r
1513                     NdefMap->TopazContainer.RemainingSize -\r
1514                     NdefMap->TopazContainer.ReadBuffer[index];\r
1515 \r
1516                 /* Get the position of the next TLV */\r
1517                 index = (uint8_t)(index + \r
1518                     (NdefMap->TopazContainer.ReadBuffer[index] + \r
1519                      PH_FRINFC_TOPAZ_VAL1));                \r
1520             }\r
1521             break;\r
1522         }\r
1523     }\r
1524 \r
1525     /* If no Ndef TLV found and operation done is read */\r
1526     if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) && \r
1527         (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))\r
1528     {\r
1529         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1530                             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);\r
1531     }\r
1532     if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) && \r
1533         ((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) ||\r
1534         (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_CHECK_OPE)))\r
1535     {\r
1536         NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4; \r
1537         NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1;\r
1538         NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4;\r
1539         NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_TOTAL_RWBYTES1;\r
1540     }\r
1541     return Result;\r
1542 }\r
1543 \r
1544 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf(phFriNfc_NdefMap_t  *NdefMap)\r
1545 {\r
1546     NFCSTATUS   Result = NFCSTATUS_SUCCESS;\r
1547     \r
1548     /* Check the the TLV size and the user size */\r
1549     if(NdefMap->ApduBufferSize >=\r
1550         NdefMap->TLVStruct.BytesRemainLinTLV)\r
1551     {\r
1552         /* Copy the read bytes to user buffer till the value (V) \r
1553         of TLV ends */\r
1554         (void)memcpy(NdefMap->ApduBuffer,\r
1555             &(NdefMap->TopazContainer.ReadBuffer[ \r
1556                 NdefMap->TopazContainer.ByteNumber]),\r
1557                     NdefMap->TLVStruct.BytesRemainLinTLV);\r
1558 \r
1559                 /* Update the number of read bytes to the user */\r
1560                 *(NdefMap->NumOfBytesRead) = \r
1561                     NdefMap->TLVStruct.BytesRemainLinTLV;\r
1562                 /* There is no byte to read */\r
1563                 NdefMap->TopazContainer.ByteNumber = \r
1564                                                     PH_FRINFC_TOPAZ_VAL0;\r
1565                 /* No further read is possible */\r
1566                 NdefMap->TopazContainer.ReadWriteCompleteFlag = \r
1567                                                     PH_FRINFC_TOPAZ_FLAG1;\r
1568                 /* Remaining size in the card can be greater than length field in \r
1569                 the TLV */\r
1570                 NdefMap->TopazContainer.RemainingSize = \r
1571                     NdefMap->TopazContainer.RemainingSize -\r
1572                                         NdefMap->TLVStruct.BytesRemainLinTLV;\r
1573                 /* TLV has been completely read, no more bytes to read */\r
1574                 NdefMap->TLVStruct.BytesRemainLinTLV = \r
1575                                                     PH_FRINFC_TOPAZ_VAL0;\r
1576     }\r
1577     else\r
1578     {\r
1579         /* Copy read bytes till the user buffer size */\r
1580         (void)memcpy(NdefMap->ApduBuffer,\r
1581                     &(NdefMap->TopazContainer.ReadBuffer[ \r
1582                     NdefMap->TopazContainer.ByteNumber]),\r
1583                     NdefMap->ApduBufferSize);\r
1584 \r
1585         /* Update the number of read bytes to the user */\r
1586         *(NdefMap->NumOfBytesRead) = \r
1587             NdefMap->ApduBufferSize;\r
1588         /* Get the next byte number to read */\r
1589         NdefMap->TopazContainer.ByteNumber = \r
1590             (uint8_t)(NdefMap->TopazContainer.ByteNumber +\r
1591                       NdefMap->ApduBufferSize);\r
1592         /* Free space left in the card */\r
1593         NdefMap->TopazContainer.RemainingSize \r
1594             = NdefMap->TopazContainer.RemainingSize \r
1595                   - (uint16_t)NdefMap->ApduBufferSize;\r
1596         /* Bytes left in the TLV */\r
1597         NdefMap->TLVStruct.BytesRemainLinTLV = \r
1598             NdefMap->TLVStruct.BytesRemainLinTLV -\r
1599                    (uint16_t)NdefMap->ApduBufferSize;\r
1600     }\r
1601     return Result;\r
1602 }\r
1603 \r
1604 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap)\r
1605 {\r
1606     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1607         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
1608     uint8_t     BlockNo = PH_FRINFC_TOPAZ_VAL0,\r
1609         ByteNo = PH_FRINFC_TOPAZ_VAL0;\r
1610 \r
1611     if((NdefMap->TopazContainer.InternalState == \r
1612         PH_FRINFC_TOPAZ_WR_NMN_0) && \r
1613         (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1614         PH_FRINFC_TOPAZ_VAL0) && \r
1615         (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1616     {\r
1617         NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV;\r
1618         /* Get the L field of the TLV block */\r
1619         BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) > \r
1620                             PH_FRINFC_TOPAZ_VAL7)?\r
1621                             (NdefMap->TLVStruct.NdefTLVBlock + PH_FRINFC_TOPAZ_VAL1):\r
1622                             NdefMap->TLVStruct.NdefTLVBlock);\r
1623         /* Get the L byte */\r
1624         ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) % \r
1625                                 PH_FRINFC_TOPAZ_VAL8);\r
1626 \r
1627         \r
1628         /* Here the NMN is written 0, so internal state is used */\r
1629         NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV_0;\r
1630         /* Write the length value = 0x00 , Write L field of TLV  = 0  inside this*/\r
1631         Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,\r
1632                                         PH_FRINFC_TOPAZ_VAL0);\r
1633     }\r
1634     else \r
1635     {\r
1636         if((NdefMap->TopazContainer.InternalState == \r
1637             PH_FRINFC_TOPAZ_WR_NMN_E1) && \r
1638             (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1639             PH_FRINFC_TOPAZ_CC_BYTE0) && \r
1640             (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1641         {\r
1642             /* Card state is initialised or invalid */ \r
1643             NdefMap->CardState = (uint8_t)((NdefMap->CardState == \r
1644                                     PH_NDEFMAP_CARD_STATE_INITIALIZED)?\r
1645                                     PH_NDEFMAP_CARD_STATE_READ_WRITE:\r
1646                                     NdefMap->CardState);\r
1647             /* update the length to the user */\r
1648             *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;\r
1649             Result = NFCSTATUS_SUCCESS;\r
1650         }\r
1651     }\r
1652     return Result;\r
1653 }\r
1654 \r
1655 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap)\r
1656 {\r
1657     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1658         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
1659     if((NdefMap->TopazContainer.InternalState == \r
1660         PH_FRINFC_TOPAZ_WR_L_TLV_0) && \r
1661         (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1662         PH_FRINFC_TOPAZ_VAL0) && \r
1663         (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1664     {\r
1665         /* state is writing user data to the card */\r
1666         NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;      \r
1667        \r
1668         NdefMap->TopazContainer.ByteNumber++;\r
1669         /* Check the byte number */\r
1670         phFriNfc_Tpz_H_BlkChk(NdefMap);\r
1671 \r
1672         /* Write data to the specified location */\r
1673         /* Write the data to the card from the user buffer */\r
1674         Result = phFriNfc_Tpz_H_WrAByte( NdefMap, \r
1675                                         NdefMap->TopazContainer.CurrentBlock,\r
1676                                         NdefMap->TopazContainer.ByteNumber,\r
1677                                         NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]\r
1678                                         );\r
1679     }\r
1680     else \r
1681     {\r
1682         if((NdefMap->TopazContainer.InternalState == \r
1683             PH_FRINFC_TOPAZ_WR_L_TLV) && \r
1684             (((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) && \r
1685             (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1686             NdefMap->ApduBuffIndex)) || \r
1687             ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && \r
1688             (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1689             (NdefMap->ApduBuffIndex + NdefMap->TLVStruct.BytesRemainLinTLV)))) && \r
1690             (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1691         {\r
1692             /* Update the L value in the context */\r
1693             NdefMap->TLVStruct.BytesRemainLinTLV = \r
1694                 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?\r
1695                 NdefMap->ApduBuffIndex:\r
1696             (NdefMap->TLVStruct.BytesRemainLinTLV + NdefMap->ApduBuffIndex));\r
1697 \r
1698             /* Write 0xE1 in block number = 1 and byte number = 0 */\r
1699             Result = phFriNfc_Tpz_H_WrByte0ValE1(NdefMap);\r
1700         }\r
1701     }\r
1702     return Result;\r
1703 }\r
1704 \r
1705 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData(phFriNfc_NdefMap_t *NdefMap)\r
1706 {\r
1707     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1708         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
1709     /* send buffer should be equal to receive buffer */\r
1710     if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1711         NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]) && \r
1712         (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1713     {\r
1714         /* Increment the index */\r
1715         NdefMap->ApduBuffIndex += PH_FRINFC_TOPAZ_VAL1;\r
1716 \r
1717         /* Remaining space left in the card is less by one */\r
1718         NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL1;\r
1719 \r
1720         /* Increment the byte number */\r
1721         NdefMap->TopazContainer.ByteNumber++;\r
1722 \r
1723         /* Check the block number */\r
1724         phFriNfc_Tpz_H_BlkChk(NdefMap);\r
1725 \r
1726         /* check for the user space or the card size */\r
1727         if((NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex) || \r
1728             (NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0))\r
1729         {\r
1730             /* Set write complete, if the end of card is reached */\r
1731             NdefMap->TopazContainer.ReadWriteCompleteFlag = (uint8_t)\r
1732                 ((NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0)?\r
1733                 PH_FRINFC_TOPAZ_FLAG1:PH_FRINFC_TOPAZ_FLAG0);\r
1734 \r
1735             Result = phFriNfc_Tpz_H_WrLByte(NdefMap);\r
1736         }\r
1737         else\r
1738         {\r
1739             /* State is continued to be in write */\r
1740             NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;           \r
1741             \r
1742             /* Write the byte to the specified location , and Byte to write */\r
1743             Result = phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock,\r
1744                                             NdefMap->TopazContainer.ByteNumber,\r
1745                                             NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]\r
1746                                             );\r
1747         }\r
1748     }\r
1749     return Result;\r
1750 }\r
1751 \r
1752 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t  *NdefMap)\r
1753 {\r
1754     NFCSTATUS   Result = NFCSTATUS_SUCCESS;\r
1755     uint8_t     BlockNo = PH_FRINFC_TOPAZ_VAL0,\r
1756         ByteNo = PH_FRINFC_TOPAZ_VAL0;\r
1757     uint8_t TempByteVal = 0;\r
1758     BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte + \r
1759                             PH_FRINFC_TOPAZ_VAL1) > \r
1760                             PH_FRINFC_TOPAZ_VAL7)?\r
1761                             (NdefMap->TLVStruct.NdefTLVBlock + \r
1762                             PH_FRINFC_TOPAZ_VAL1):\r
1763     NdefMap->TLVStruct.NdefTLVBlock);\r
1764 \r
1765     ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte + \r
1766                         PH_FRINFC_TOPAZ_VAL1) % PH_FRINFC_TOPAZ_VAL8);\r
1767     /* Update L field */\r
1768     NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV;\r
1769     /* Internal state for write */\r
1770     NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV;\r
1771     /* Update the length field depending on the offset */\r
1772     TempByteVal = (uint8_t)\r
1773                     ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?\r
1774                     NdefMap->ApduBuffIndex:\r
1775                     (NdefMap->ApduBuffIndex + \r
1776                     NdefMap->TLVStruct.BytesRemainLinTLV));\r
1777     /* Write the L field */\r
1778     Result = phFriNfc_Tpz_H_WrAByte(NdefMap, BlockNo, ByteNo,TempByteVal);\r
1779     return Result;\r
1780 }\r
1781 \r
1782 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t   *NdefMap)\r
1783 {\r
1784     NFCSTATUS   Result = NFCSTATUS_SUCCESS;\r
1785 \r
1786     /* Update L field */\r
1787     NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN;\r
1788     /* Internal state for writing 0xE1 */\r
1789     NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_E1;\r
1790     /* Update the length field depending on the offset */                          \r
1791     /* Write the L field */\r
1792     Result = phFriNfc_Tpz_H_WrAByte(NdefMap, PH_FRINFC_TOPAZ_VAL1, \r
1793                                     PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_CC_BYTE0);\r
1794     return Result;\r
1795 }\r
1796 \r
1797 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t  *NdefMap,\r
1798                                     NFCSTATUS           Status)\r
1799 {\r
1800     /* set the state back to the Reset_Init state*/\r
1801     NdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;\r
1802 \r
1803     /* set the completion routine*/\r
1804     NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex].\r
1805         CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);\r
1806 }\r
1807 \r
1808 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t  *NdefMap)\r
1809 {\r
1810     NdefMap->TopazContainer.CurrentBlock = \r
1811                     (uint8_t)((NdefMap->TopazContainer.ByteNumber > \r
1812                     PH_FRINFC_TOPAZ_VAL7)?\r
1813                     (NdefMap->TopazContainer.CurrentBlock + \r
1814                     PH_FRINFC_TOPAZ_VAL1):\r
1815                     NdefMap->TopazContainer.CurrentBlock);\r
1816 \r
1817     NdefMap->TopazContainer.ByteNumber = (uint8_t)(NdefMap->TopazContainer.ByteNumber % \r
1818                                         PH_FRINFC_TOPAZ_VAL8);\r
1819 }\r
1820 \r
1821 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t  *NdefMap)\r
1822 {\r
1823     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1824                                     NFCSTATUS_NO_NDEF_SUPPORT);\r
1825 \r
1826     if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] == \r
1827         PH_FRINFC_TOPAZ_CC_BYTE0)\r
1828     {\r
1829         /* Check the most significant nibble of byte 3 (RWA) = 0 */\r
1830         Result = (((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] & \r
1831                     PH_FRINFC_TOPAZ_BYTE3_MSB)== PH_FRINFC_TOPAZ_VAL0)?\r
1832                     NFCSTATUS_SUCCESS:\r
1833                     Result);\r
1834 \r
1835         /* Card size is initialised */ \r
1836         NdefMap->CardMemSize = NdefMap->TopazContainer.RemainingSize = \r
1837                             ((Result == NFCSTATUS_SUCCESS)?\r
1838                             (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4):\r
1839                             NdefMap->CardMemSize);\r
1840     }\r
1841 \r
1842     if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY)\r
1843     {\r
1844         NdefMap->CardState = (uint8_t)((Result == NFCSTATUS_SUCCESS)?\r
1845                             PH_NDEFMAP_CARD_STATE_INITIALIZED:\r
1846                             PH_NDEFMAP_CARD_STATE_INVALID);\r
1847     }\r
1848 \r
1849     return Result;\r
1850 }\r
1851 \r
1852 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t  *NdefMap)\r
1853 {\r
1854     /* Set the card state */\r
1855     NdefMap->CardState =  (uint8_t)\r
1856         (((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_0] == \r
1857         PH_FRINFC_TOPAZ_LOCKBIT_BYTE114) && \r
1858         ((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] == \r
1859         PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_1) ||\r
1860         (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] == \r
1861         PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_2)))?\r
1862         PH_NDEFMAP_CARD_STATE_READ_WRITE:\r
1863         PH_NDEFMAP_CARD_STATE_READ_ONLY);\r
1864 \r
1865     /* Set the card state from CC bytes */\r
1866     if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE)\r
1867     {\r
1868         if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READWRITE)\r
1869         {\r
1870             NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;\r
1871         }\r
1872         else if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READONLY)\r
1873         {\r
1874             NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;\r
1875         }\r
1876         else \r
1877         {\r
1878             NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;\r
1879         }\r
1880     }\r
1881 }\r
1882 \r
1883 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t  *NdefMap)\r
1884 {\r
1885     NFCSTATUS   Result = NFCSTATUS_SUCCESS;\r
1886     uint8_t     ByteNo = PH_FRINFC_TOPAZ_VAL0,\r
1887         BlockNo = PH_FRINFC_TOPAZ_VAL0;\r
1888     uint8_t TempByteVal = 0;\r
1889     switch(NdefMap->TopazContainer.InternalState)\r
1890     {\r
1891     case PH_FRINFC_TOPAZ_WR_CC_BYTE0:\r
1892         /* To write the CC bytes */\r
1893         TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE0;\r
1894         ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL0;\r
1895         BlockNo = PH_FRINFC_TOPAZ_VAL1;\r
1896         break;\r
1897 \r
1898     case PH_FRINFC_TOPAZ_WR_CC_BYTE1:\r
1899         /* To write the CC bytes */\r
1900         TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE1;\r
1901         ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL1;\r
1902         BlockNo = PH_FRINFC_TOPAZ_VAL1;\r
1903         break;\r
1904 \r
1905     case PH_FRINFC_TOPAZ_WR_CC_BYTE2:\r
1906         /* To write the CC bytes */\r
1907         TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE2_MAX;\r
1908         ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL2;\r
1909         BlockNo = PH_FRINFC_TOPAZ_VAL1;\r
1910         break;\r
1911 \r
1912     case PH_FRINFC_TOPAZ_WR_CC_BYTE3:\r
1913         /* To write the CC bytes */\r
1914         TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE3_RW;\r
1915         ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL3;\r
1916         BlockNo = PH_FRINFC_TOPAZ_VAL1;\r
1917         break;\r
1918 \r
1919     case PH_FRINFC_TOPAZ_WR_T_OF_TLV:\r
1920     default:\r
1921         /* To write the NDEF TLV (if not present) */\r
1922         TempByteVal = PH_FRINFC_TOPAZ_NDEF_T;\r
1923         ByteNo = (uint8_t)NdefMap->TLVStruct.NdefTLVByte;\r
1924         BlockNo = NdefMap->TLVStruct.NdefTLVBlock;\r
1925         break;\r
1926     }\r
1927     NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV;\r
1928     Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,TempByteVal);\r
1929     return Result;\r
1930 }\r
1931 \r
1932 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t  *NdefMap)\r
1933 {\r
1934     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1935         NFCSTATUS_INVALID_RECEIVE_LENGTH);\r
1936     switch(NdefMap->TopazContainer.InternalState)\r
1937     {\r
1938     case PH_FRINFC_TOPAZ_WR_CC_BYTE0:\r
1939         /* Process the CC byte */\r
1940         /* Check the response */\r
1941         if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1942             PH_FRINFC_TOPAZ_CC_BYTE0) && \r
1943             (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1944         {\r
1945             NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE1;\r
1946             Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);\r
1947         }\r
1948         break;\r
1949 \r
1950     case PH_FRINFC_TOPAZ_WR_CC_BYTE1:\r
1951         /* Process the CC byte */\r
1952         /* Check the response */\r
1953         if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1954             PH_FRINFC_TOPAZ_CC_BYTE1) && \r
1955             (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1956         {\r
1957             NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE2;\r
1958             Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);\r
1959         }\r
1960         break;\r
1961 \r
1962     case PH_FRINFC_TOPAZ_WR_CC_BYTE2:\r
1963         /* Process the CC byte */\r
1964         /* Check the response */\r
1965         if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1966             PH_FRINFC_TOPAZ_CC_BYTE2_MAX) && \r
1967             (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1968         {\r
1969             NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE3;\r
1970             Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);\r
1971         }\r
1972         break;\r
1973 \r
1974     case PH_FRINFC_TOPAZ_WR_CC_BYTE3:\r
1975         /* Process the CC byte */\r
1976         /* Check the response */\r
1977         if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1978             PH_FRINFC_TOPAZ_CC_BYTE3_RW) && \r
1979             (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1980         {\r
1981             NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;\r
1982             Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);\r
1983         }\r
1984         break;\r
1985 \r
1986     case PH_FRINFC_TOPAZ_WR_T_OF_TLV:\r
1987     default:\r
1988         /* Check the response */\r
1989         if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == \r
1990             PH_FRINFC_TOPAZ_NDEF_T) && \r
1991             (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))\r
1992         {\r
1993             /* Increment the Byte Number */\r
1994             NdefMap->TopazContainer.ByteNumber++;\r
1995             /* Check the block and byte number */\r
1996             phFriNfc_Tpz_H_BlkChk(NdefMap);\r
1997             /* Process the T of NDEF TLV */\r
1998             NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN;            \r
1999             \r
2000             /* Here the NMN is written 0, so internal state is used */\r
2001             NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_0;\r
2002 \r
2003             /*Inside this call Write NMN (block number 1 and byte number 0) = 0 */\r
2004             Result = phFriNfc_Tpz_H_WrAByte( NdefMap, PH_FRINFC_TOPAZ_VAL1,\r
2005                 PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_VAL0);\r
2006         }\r
2007         break;\r
2008     }\r
2009     return Result;\r
2010 }\r
2011 \r
2012 #ifdef UNIT_TEST\r
2013 #include <phUnitTestNfc_Topaz_static.c>\r
2014 #endif\r
2015 \r
2016 #endif  /* PH_FRINFC_MAP_TOPAZ_DISABLED */\r