Initialize Tizen 2.3
[adaptation/devices/nfc-plugin-nxp.git] / src / phFriNfc_TopazDynamicMap.c
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_TopazDynamicMap.c
19 * \brief NFC Ndef Mapping For Remote Devices.
20 *
21 * Project: NFC-FRI
22 *
23 * $Date: Wed Oct 27 10:21:29 2010 $
24 * $Author: ing02260 $
25 * $Revision: 1.41 $
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 #if !(defined(PH_FRINFC_MAP_TOPAZ_DISABLED ) || defined (PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED ))
38
39 /*! \ingroup grp_file_attributes
40 *  \name NDEF Mapping
41 *
42 * File: \ref phFriNfcNdefMap.c
43 *
44 */
45 /*@{*/
46 #define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.41 $"
47 #define PHFRINFCTOPAZMAP_FILEALIASES  "$Aliases:  $"
48 /*@}*/
49 /*!
50 * \name Topaz Mapping - Helper data structures and macros
51 *
52 */
53 /*@{*/
54
55 /********************************** Start of data structures *********************************/
56 #ifdef FRINFC_READONLY_NDEF
57
58     #define DYN_CC_BLOCK_NUMBER                                     (0x01U)
59     #define DYN_STATIC_LOCK_BLOCK_NUM                               (0x0EU)
60
61     #define DYN_STATIC_LOCK0_BYTE_NUM                               (0x00U)
62     #define DYN_STATIC_LOCK0_BYTE_VALUE                             (0xFFU)
63
64     #define DYN_STATIC_LOCK1_BYTE_NUM                               (0x01U)
65     #define DYN_STATIC_LOCK1_BYTE_VALUE                             (0x7FU)
66
67     #define DYN_CC_RWA_BYTE_NUMBER                                  (0x03U)
68     #define DYN_CC_READ_ONLY_VALUE                                  (0x0FU)
69
70 #endif /* #ifdef FRINFC_READONLY_NDEF */
71
72 /*!
73 * \brief \copydoc page_ovr enum for the topaz sequence of execution. 
74 */
75 typedef enum phFriNfc_Tpz_ParseSeq
76 {
77     LOCK_T_TLV, 
78     LOCK_L_TLV, 
79     LOCK_V_TLV,
80     MEM_T_TLV, 
81     MEM_L_TLV,
82     MEM_V_TLV,
83     NDEF_T_TLV, 
84     NDEF_L_TLV, 
85     NDEF_V_TLV
86 }phFriNfc_Tpz_ParseSeq_t;
87
88 typedef enum phFriNfc_Tpz_WrSeq
89 {
90     WR_NDEF_T_TLV, 
91     WR_NMN_0, 
92     WR_LEN_1_0, 
93     WR_LEN_2_0,
94     WR_LEN_3_0,
95     WR_DATA,
96     WR_DATA_READ_REQD, 
97     WR_LEN_1_VALUE, 
98     WR_LEN_2_VALUE,
99     WR_LEN_3_VALUE,     
100     WR_NMN_E1
101 }phFriNfc_Tpz_WrSeq_t;
102
103 #ifdef FRINFC_READONLY_NDEF
104
105 typedef enum phFriNfc_Tpz_RO_Seq
106 {
107     WR_READONLY_CC, 
108     RD_LOCK_BYTES, 
109     WR_LOCK_BYTES, 
110     RD_STATIC_LOCK_BYTE0,
111     WR_STATIC_LOCK_BYTE0,
112     WR_STATIC_LOCK_BYTE1
113 }phFriNfc_Tpz_RO_Seq_t;
114
115 #endif /* #ifdef FRINFC_READONLY_NDEF  */
116
117 /********************************** End of data structures *********************************/
118
119 /********************************** Start of Macros *********************************/
120 /* New state for TOPAZ dynamic  card*/
121 #define PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF            (0x10U)
122
123 #ifdef FRINFC_READONLY_NDEF
124     #define PH_FRINFC_TOPAZ_STATE_READ_ONLY             (0x11U)
125 #endif /* #ifdef FRINFC_READONLY_NDEF */
126
127 #define NIBBLE_SIZE                                     (0x04U)
128 /* Byte shifting for the topaz */
129 #define TOPAZ_BYTE_SHIFT                                (0x08U)
130 /* Lock and memory control TLV length. Always 3 bytes */
131 #define TOPAZ_MEM_LOCK_TLV_LENGTH                       (0x03U)
132 /* UID byte length */
133 #define TOPAZ_UID_BYTES_LENGTH                          (0x08U)
134
135 /* Number os static lock and reserved bytes */
136 #define TOPAZ_STATIC_LOCK_RES_BYTES                     (0x18U)
137 /* Number of static lock and reserved memory. This value is 3 (because 
138     block number D, E and F are lock and reserved blocks */
139 #define TOPAZ_STATIC_LOCK_BLOCK_AREAS                   (0x03U)
140 /* First lock or reserved block in the static area of the card */
141 #define TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO                (0x0DU)
142 /* First lock or reserved byte number in the static area of the card */
143 #define TOPAZ_STATIC_LOCK_RES_START                     (0x68U)
144 /* End lock or reserved byte number in the static area of the card */
145 #define TOPAZ_STATIC_LOCK_RES_END                       (0x78U)
146
147 /* CC byte length */
148 #define TOPAZ_CC_BYTES_LENGTH                           (0x04U)
149
150 /* In TOPAZ card each block has 8 bytes */
151 #define TOPAZ_BYTES_PER_BLOCK                           (0x08U)
152 /* Each byte has 8 bites */
153 #define TOPAZ_BYTE_SIZE_IN_BITS                         (0x08U)
154
155 /* This mask is to get the least significant NIBBLE from a BYTE */
156 #define TOPAZ_NIBBLE_MASK                               (0x0FU)
157 /* This is used to mask the least significant BYTE from a TWO BYTE value */
158 #define TOPAZ_BYTE_LENGTH_MASK                          (0x00FFU)
159
160 /* Total segments in TOPAZ 512 bytes card. Each segment = 128 bytes, 
161 so there are 4 segements in the card */
162 #define TOPAZ_TOTAL_SEG_TO_READ                         (0x04U)
163 /* SPEC version value shall be 0x10 as per the TYPE 1 specification */
164 #define TOPAZ_SPEC_VERSION                              (0x10U)
165
166 /* Response length for READ SEGMENT command is 128 bytes */
167 #define TOPAZ_SEGMENT_READ_LENGTH                       (0x80U)
168 /* Response length for WRITE-1E command is 1 byte */
169 #define TOPAZ_WRITE_1_RESPONSE                          (0x01U)
170 /* Response length for WRITE-8E command is 8 bytes */
171 #define TOPAZ_WRITE_8_RESPONSE                          (0x08U)
172 /* Response length for READ-8 command is 8 bytes */
173 #define TOPAZ_READ_8_RESPONSE                           (0x08U)
174
175 /* Data bytes that can be written for the WRITE-8E command is 8 bytes */
176 #define TOPAZ_WRITE_8_DATA_LENGTH                       (0x08U)
177
178 /* Get the exact byte address of the card from the segment number 
179     and the parse index of each segment */
180 #define TOPAZ_BYTE_ADR_FROM_SEG(seg, parse_index) \
181     (((seg) * TOPAZ_SEGMENT_READ_LENGTH) + (parse_index))
182
183 /* Get the segment number of the card from the byte address */
184 #define TOPAZ_SEG_FROM_BYTE_ADR(byte_addr) \
185     ((byte_addr) / TOPAZ_SEGMENT_READ_LENGTH)
186 /* Get the block number of the card from the byte address */ 
187 #define TOPAZ_BLK_FROM_BYTE_ADR(byte_addr) \
188     ((byte_addr) / TOPAZ_BYTES_PER_BLOCK)
189 /* Get the block offset of a block number of the card from the byte address */ 
190 #define TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR(byte_addr) \
191     ((byte_addr) % TOPAZ_BYTES_PER_BLOCK)
192 /* Get the exact byte address of the card from the block number 
193     and the byte offset of the block number */
194 #define TOPAZ_BYTE_ADR_FROM_BLK(block_no, byte_offset) \
195     (((block_no) * TOPAZ_BYTES_PER_BLOCK) + (byte_offset))
196 /* To increment the block number and if block number overlaps with the 
197     static lock and reserved blocks, then skip the blocks */
198 #define TOPAZ_INCREMENT_SKIP_STATIC_BLOCK(block_no) \
199     ((((block_no) + 1) == TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO) ? \
200     (((block_no) + 1) + TOPAZ_STATIC_LOCK_BLOCK_AREAS) : \
201     ((block_no) + 1))
202
203 #ifdef FRINFC_READONLY_NDEF
204
205 #define TOPAZ_CONVERT_BITS_TO_BYTES(bits_to_bytes) \
206             (((bits_to_bytes % TOPAZ_BYTE_SIZE_IN_BITS) > 0) ? \
207             ((bits_to_bytes / TOPAZ_BYTE_SIZE_IN_BITS) + 1) : \
208             (bits_to_bytes / TOPAZ_BYTE_SIZE_IN_BITS))
209
210 #endif /* #ifdef FRINFC_READONLY_NDEF */
211 /********************************** End of Macros *********************************/
212
213 /*@}*/
214
215
216 /*!
217 * \name Topaz Mapping - Helper Functions
218 *
219 */
220 /*@{*/
221
222 /*!
223 * \brief \copydoc page_ovr Helper function for Topaz. This function shall read defined 
224 * bytes from the card.
225 */
226 static 
227 NFCSTATUS 
228 phFriNfc_Tpz_H_NxpRead (
229     phFriNfc_NdefMap_t          *psNdefMap);
230
231 /*!
232 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process 
233 * received read id command.
234 */
235 static 
236 NFCSTATUS 
237 phFriNfc_Tpz_H_ChkReadID (
238     phFriNfc_NdefMap_t          *psNdefMap);
239
240
241 /*!
242 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process 
243 * read response. 
244 */
245 static 
246 NFCSTATUS 
247 phFriNfc_Tpz_H_ProReadResp (
248     phFriNfc_NdefMap_t  *psNdefMap);
249
250 /*!
251 * \brief \copydoc page_ovr Helper function for Topaz. This function calls the 
252 * completion routine
253 */
254 static 
255 void 
256 phFriNfc_Tpz_H_Complete (
257     phFriNfc_NdefMap_t  *NdefMap,
258     NFCSTATUS           Status);
259
260
261 /*!
262 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks 
263 * the lock bits and set a card state
264 */
265 static 
266 NFCSTATUS 
267 phFriNfc_Tpz_H_ChkLockBits (
268     phFriNfc_NdefMap_t  *psNdefMap);
269
270 /*!
271 * \brief \copydoc page_ovr Helper function for Topaz. This function writes defined 
272 * bytes into the card
273 */
274 static 
275 NFCSTATUS 
276 phFriNfc_Tpz_H_NxpWrite (
277     phFriNfc_NdefMap_t          *psNdefMap, 
278     uint8_t                     *p_write_data, 
279     uint8_t                     wr_data_len);
280
281
282 /*!
283 * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
284 * till the NDEF TLV is found. Also, it returns error if it founds wrong TLVs.
285 */
286 static 
287 NFCSTATUS 
288 phFriNfc_Tpz_H_ParseTLVs (
289     phFriNfc_NdefMap_t          *psNdefMap);
290
291 /*!
292  * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
293  * till the TYPE of the LOCK control TLV is found. 
294  * Also, it returns error if it founds wrong TYPE.
295  */
296 static 
297 NFCSTATUS 
298 phFriNfc_Tpz_H_ParseLockTLVType (
299     phFriNfc_NdefMap_t          *psNdefMap, 
300     uint8_t                     *p_parse_data, 
301     uint16_t                    *p_parse_index, 
302     uint16_t                    total_len_to_parse, 
303     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute);
304
305 /*!
306  * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
307  * till the TYPE of the MEMORY control TLV is found. 
308  * Also, it returns error if it founds wrong TYPE.
309  */
310 static 
311 NFCSTATUS 
312 phFriNfc_Tpz_H_ParseMemTLVType (
313     phFriNfc_NdefMap_t          *psNdefMap, 
314     uint8_t                     *p_parse_data, 
315     uint16_t                    *p_parse_index, 
316     uint16_t                    total_len_to_parse, 
317     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute);
318
319 /*!
320  * \brief \copydoc page_ovr Helper function for Topaz. This function parses the read bytes
321  * till the TYPE of the NDEF control TLV is found. 
322  * Also, it returns error if it founds wrong TYPE.
323  */
324 static 
325 NFCSTATUS 
326 phFriNfc_Tpz_H_ParseNdefTLVType (
327     phFriNfc_NdefMap_t          *psNdefMap, 
328     uint8_t                     *p_parse_data, 
329     uint16_t                    *p_parse_index, 
330     uint16_t                    total_len_to_parse, 
331     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute);
332
333 /*!
334  * \brief \copydoc page_ovr Helper function for Topaz. This function gets the lock bytes 
335  * information.
336  */
337 static 
338 NFCSTATUS 
339 phFriNfc_Tpz_H_GetLockBytesInfo (
340     phFriNfc_NdefMap_t          *psNdefMap, 
341     uint8_t                     *p_lock_info);
342
343 /*!
344  * \brief \copydoc page_ovr Helper function for Topaz. This function gets the reserved bytes 
345  * information.
346  */
347 static 
348 NFCSTATUS 
349 phFriNfc_Tpz_H_GetMemBytesInfo (
350     phFriNfc_NdefMap_t          *psNdefMap, 
351     uint8_t                     *p_mem_info);
352
353 /*!
354  * \brief \copydoc page_ovr Helper function for Topaz. This function copies and checks the CC bytes.  
355  * This function checks for the lock bytes value and card state also.
356  */
357 static 
358 NFCSTATUS 
359 phFriNfc_Tpz_H_CheckCCBytes (
360     phFriNfc_NdefMap_t          *psNdefMap);
361
362 /*!
363  * \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC bytes.  
364  * If .
365  */
366 static 
367 NFCSTATUS 
368 phFriNfc_Tpz_H_CheckCCBytesForWrite (
369     phFriNfc_NdefMap_t          *psNdefMap);
370
371
372 /*!
373  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the read bytes.  
374  * This function also checks for the lock and reserved bytes and skips the bytes before copying it 
375  * in the buffer.
376  */
377 static 
378 NFCSTATUS 
379 phFriNfc_Tpz_H_CopyReadData (
380     phFriNfc_NdefMap_t          *psNdefMap);
381
382 /*!
383  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the stored read bytes.  
384  * This function is used only for the offset " PH_FRINFC_NDEFMAP_SEEK_CUR ".
385  */
386 static 
387 NFCSTATUS 
388 phFriNfc_Tpz_H_RemainingReadDataCopy (
389     phFriNfc_NdefMap_t          *psNdefMap);
390
391 /*!
392  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the exact byte address
393  * of the value field after the NDEF TYPE field
394  */
395 static 
396 uint16_t 
397 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
398     phFriNfc_NdefMap_t          *psNdefMap);
399
400 /*!
401  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the exact byte address
402  * of the value field after the NDEF TYPE field
403  */
404 static 
405 uint16_t 
406 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (
407     phFriNfc_NdefMap_t          *psNdefMap, 
408     uint16_t                     size_to_write);
409
410 /*!
411  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the number of bytes to skip.  
412  * This function checks the input byte address and checks if any lock or reserved bytes matches with the 
413  * given address. if yes, then it will return number od bytes to skip.
414  */
415 static 
416 uint16_t
417 phFriNfc_Tpz_H_GetSkipSize (
418     phFriNfc_NdefMap_t          *psNdefMap, 
419     uint16_t                    byte_adr_card);
420
421 /*!
422  * \brief \copydoc page_ovr Helper function for Topaz. This function gives the actual data that can 
423  * be read and written in the card.  
424  * This function checks for the lock and reserved bytes and subtracts the remaining size to give the 
425  * actual size.
426  */
427 static 
428 NFCSTATUS 
429 phFriNfc_Tpz_H_ActualCardSize (
430     phFriNfc_NdefMap_t          *psNdefMap);
431
432 /*!
433  * \brief \copydoc page_ovr Helper function for Topaz. This function processes the response for
434  * the write data
435  */
436 static 
437 NFCSTATUS 
438 phFriNfc_Tpz_H_ProWrResp (
439     phFriNfc_NdefMap_t          *psNdefMap);
440
441 /*!
442  * \brief \copydoc page_ovr Helper function for Topaz. This function processes the read 8 commands,  
443  * that is required for writing the data
444  */
445 static 
446 NFCSTATUS 
447 phFriNfc_Tpz_H_ProRdForWrResp (
448     phFriNfc_NdefMap_t          *psNdefMap);
449
450 /*!
451  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the user data to the 
452  * write buffer and writes the data to the card. If the lock or memory blocks are in between the 
453  * write data, then read the current block
454  */
455 static 
456 NFCSTATUS 
457 phFriNfc_Tpz_H_CopySendWrData (
458     phFriNfc_NdefMap_t          *psNdefMap);
459
460 /*!
461  * \brief \copydoc page_ovr Helper function for Topaz. This function compares the input block 
462  * number with lock bytes block number and returns the p_skip_size which is the lock bytes 
463  * size
464  */
465 static 
466 uint16_t 
467 phFriNfc_Tpz_H_CompareLockBlocks (
468     phFriNfc_NdefMap_t          *psNdefMap, 
469     uint8_t                     block_no, 
470     uint16_t                    *p_skip_size);
471
472 /*!
473  * \brief \copydoc page_ovr Helper function for Topaz. This function compares the input block 
474  * number with reserved bytes block number and returns the p_skip_size which is the reserved bytes 
475  * size
476  */
477 static 
478 uint16_t 
479 phFriNfc_Tpz_H_CompareMemBlocks (
480     phFriNfc_NdefMap_t          *psNdefMap, 
481     uint8_t                     block_no, 
482     uint16_t                    *p_skip_size);
483
484 /*!
485  * \brief \copydoc page_ovr Helper function for Topaz. This function copies the read data and update 
486  * the user bytes by skipping lock or memory control areas. Also, used while updating the value field
487  * skips the initial bytes and to start at the proper value field byte offset of the block
488  */
489 static 
490 NFCSTATUS 
491 phFriNfc_Tpz_H_CopyReadDataAndWrite (
492     phFriNfc_NdefMap_t          *psNdefMap);
493
494
495 /*!
496  * \brief \copydoc page_ovr Helper function for Topaz. This function reads the required block for writing, 
497  * as some of the bytes shall not be overwritten
498  */
499 static 
500 NFCSTATUS 
501 phFriNfc_Tpz_H_RdForWrite (
502     phFriNfc_NdefMap_t          *psNdefMap);
503
504 /*!
505  * \brief \copydoc page_ovr Helper function for Topaz. This function reads the length block for writing, 
506  * updates the length bytes with 0
507  */
508 static 
509 NFCSTATUS 
510 phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (
511     phFriNfc_NdefMap_t          *psNdefMap);
512
513 /*!
514  * \brief \copydoc page_ovr Helper function for Topaz. This function reads the length block for writing, 
515  * updates the length bytes with exact bytes that was written in the card
516  */
517 static 
518 NFCSTATUS 
519 phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (
520     phFriNfc_NdefMap_t          *psNdefMap);
521
522 /*!
523  * \brief \copydoc page_ovr Helper function for Topaz. This function writes the NDEF TYPE of the 
524  * NDEF TLV to the specific byte address. This function is called only if the previous write is  
525  * failed or there is no NDEF TLV with correct CC bytes
526  */
527 static 
528 NFCSTATUS 
529 phFriNfc_Tpz_H_UpdateNdefTypeField (
530     phFriNfc_NdefMap_t          *psNdefMap);
531
532 #ifdef FRINFC_READONLY_NDEF
533
534 static
535 NFCSTATUS
536 phFriNfc_Tpz_H_ProcessReadOnly (
537     phFriNfc_NdefMap_t          *psNdefMap);
538
539 static 
540 NFCSTATUS
541 phFriNfc_Tpz_H_UpdateAndWriteLockBits (
542     phFriNfc_NdefMap_t          *psNdefMap);
543
544
545 #endif /* #ifdef FRINFC_READONLY_NDEF */
546
547
548 /*!
549 * \brief Check whether a particular Remote Device is NDEF compliant.
550 *
551 * The function checks whether the peer device is NDEF compliant.
552 *
553 * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t 
554 *                    structure describing the component context.
555 *
556 * \retval  NFCSTATUS_PENDING   The action has been successfully triggered.
557 * \retval  Others              An error has occurred.
558 *
559 */
560 NFCSTATUS  phFriNfc_TopazDynamicMap_ChkNdef( phFriNfc_NdefMap_t     *NdefMap)
561 {
562     NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
563         NFCSTATUS_INVALID_PARAMETER);
564     if ( NdefMap != NULL)
565     {
566         /* Update the previous operation */
567         NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
568         /* Update the CR index to know from which operation completion 
569         routine has to be called */
570         NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
571         NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
572         NdefMap->TopazContainer.CurrentSeg = 0;
573         NdefMap->TopazContainer.NdefTLVByteAddress = 0;
574         NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
575
576         NdefMap->TopazContainer.CurrentBlock = 0;
577         NdefMap->TopazContainer.WriteSeq = 0;
578         NdefMap->TopazContainer.ExpectedSeq = 0;
579         
580         (void)memset ((void *)&(NdefMap->LockTlv), 0, 
581                         sizeof (phFriNfc_LockCntrlTLVCont_t));
582
583         (void)memset ((void *)&(NdefMap->MemTlv), 0, 
584                     sizeof (phFriNfc_ResMemCntrlTLVCont_t));
585         
586         /* Set card state */
587         NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_DYNAMIC_CARD;
588
589         /* Change the state to Read */
590         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
591         
592         NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_DYNAMIC_INIT_CHK_NDEF;
593 #ifdef TOPAZ_RAW_SUPPORT
594
595         *NdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
596
597 #else 
598
599 #ifdef PH_HAL4_ENABLE
600         NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;   
601 #else
602         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
603 #endif
604
605 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
606
607         Result = phFriNfc_Tpz_H_NxpRead(NdefMap);
608
609       }
610     return Result;    
611 }
612
613
614 /*!
615 * \brief Initiates Reading of NDEF information from the Remote Device.
616 *
617 * The function initiates the reading of NDEF information from a Remote Device.
618 * It performs a reset of the state and starts the action (state machine).
619 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
620 * has been triggered.
621 */
622
623 NFCSTATUS phFriNfc_TopazDynamicMap_RdNdef( phFriNfc_NdefMap_t           *NdefMap,
624                                         uint8_t                         *PacketData,
625                                         uint32_t                        *PacketDataLength,
626                                         uint8_t                         Offset)
627 {
628     NFCSTATUS               Result =    NFCSTATUS_SUCCESS;
629
630     /* Copy user buffer to the context */
631     NdefMap->ApduBuffer = PacketData;
632     /* Copy user length to the context */
633     NdefMap->ApduBufferSize = *PacketDataLength;
634     /* Update the user memory size to a context variable */
635     NdefMap->NumOfBytesRead = PacketDataLength;
636     /* Number of bytes read from the card is zero. 
637     This variable returns the number of bytes read 
638     from the card. */
639     *NdefMap->NumOfBytesRead = 0;
640     /* Index to know the length read */
641     NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;    
642     /* Store the offset in the context */
643     NdefMap->Offset = Offset;
644     /* Update the CR index to know from which operation completion 
645     routine has to be called */ 
646     NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
647     NdefMap->TopazContainer.SkipLockBlkFlag = 0;
648
649     NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
650     if ((PH_FRINFC_NDEFMAP_SEEK_CUR == Offset) &&
651         (TRUE == NdefMap->TopazContainer.ReadWriteCompleteFlag))
652     {
653         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
654                             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 
655     }
656     else if ((PH_NDEFMAP_CARD_STATE_INITIALIZED == 
657             NdefMap->CardState) || 
658             (0 == NdefMap->TopazContainer.ActualNDEFMsgSize))
659     {
660         /* Length field of NDEF TLV is 0, so read cannot proceed */
661         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
662                             NFCSTATUS_READ_FAILED);
663     }
664     else if ((PH_FRINFC_NDEFMAP_SEEK_BEGIN == Offset) || 
665         (PH_FRINFC_NDEFMAP_READ_OPE != NdefMap->PrevOperation))
666     {
667         /* If previous operation is not read then the read shall 
668         start from BEGIN */
669         NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
670         /* Initialise byte number */
671         NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
672
673         NdefMap->TopazContainer.RemainingReadSize = 0;
674         NdefMap->TopazContainer.ReadBufferSize = 0;
675         NdefMap->TopazContainer.ReadWriteCompleteFlag = FALSE;
676         NdefMap->TopazContainer.CurrentBlock = 0;
677         NdefMap->TopazContainer.WriteSeq = 0;
678
679         NdefMap->TopazContainer.CurrentSeg = (uint8_t)TOPAZ_SEG_FROM_BYTE_ADR (
680                         phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (NdefMap));
681                 
682          /* Change the state to Read ID */
683         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID;
684         /*Change the state to Read ID*/
685         NdefMap->TopazContainer.ReadWriteCompleteFlag = 0;
686 #ifdef TOPAZ_RAW_SUPPORT
687
688         NdefMap->SendRecvBuf[0] = PH_FRINFC_TOPAZ_CMD_READID;
689
690 #else 
691
692 #ifdef PH_HAL4_ENABLE
693         NdefMap->Cmd.JewelCmd = phHal_eJewel_RID;   
694 #else
695         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid;
696 #endif
697
698 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
699         Result =  phFriNfc_Tpz_H_NxpRead(NdefMap);
700
701     }
702     else
703     {
704          /* Change the state to Read */
705           NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
706           Result = phFriNfc_Tpz_H_RemainingReadDataCopy (NdefMap);
707     }
708
709     
710     return Result;
711 }
712
713 #ifdef FRINFC_READONLY_NDEF
714
715 NFCSTATUS
716 phFriNfc_TopazDynamicMap_ConvertToReadOnly (
717     phFriNfc_NdefMap_t     *psNdefMap)
718 {
719     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
720     uint8_t                     cc_read_only_byte = 0x0FU;
721
722     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_READ_ONLY;
723     
724     psNdefMap->TopazContainer.read_only_seq = 0;
725
726
727
728     psNdefMap->TopazContainer.CurrentBlock = 0x01U;
729     psNdefMap->TopazContainer.ByteNumber = 0x03U;
730                     
731 #ifdef TOPAZ_RAW_SUPPORT
732     *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
733 #else 
734     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
735 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
736
737     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &cc_read_only_byte, 
738                                     1);
739         
740     if (NFCSTATUS_PENDING == result)
741     {
742         psNdefMap->TopazContainer.read_only_seq = (uint8_t)WR_READONLY_CC;
743     }
744
745
746     return result;
747 }
748
749 #endif /* #ifdef FRINFC_READONLY_NDEF */
750
751 /*!
752 * \brief Initiates Writing of NDEF information to the Remote Device.
753 *
754 * The function initiates the writing of NDEF information to a Remote Device.
755 * It performs a reset of the state and starts the action (state machine).
756 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
757 * has been triggered.
758 */
759 NFCSTATUS phFriNfc_TopazDynamicMap_WrNdef( phFriNfc_NdefMap_t     *NdefMap,
760                                    uint8_t                 *PacketData,
761                                    uint32_t                *PacketDataLength,
762                                    uint8_t                 Offset)
763 {
764     NFCSTATUS                   Result = NFCSTATUS_SUCCESS;
765
766     /* Copy user buffer to the context */
767     NdefMap->ApduBuffer = PacketData;
768     /* Copy user length to the context */
769     NdefMap->ApduBufferSize = *PacketDataLength;
770     /* Index to know the length written */
771     NdefMap->ApduBuffIndex = 0;
772     /* Update the user memory size to a context variable */
773     NdefMap->WrNdefPacketLength = PacketDataLength;
774     /* Number of bytes written to the card is zero. 
775     This variable returns the number of bytes written 
776     to the card. */
777     *NdefMap->WrNdefPacketLength = 0;
778     /* Update the CR index to know from which operation completion 
779     routine has to be called */
780     NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
781     /* Store the offset in the context */
782     NdefMap->Offset = Offset;
783
784     /* Update the previous operation to write operation */
785     NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
786
787     if (PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState)
788     {
789         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
790                             NFCSTATUS_WRITE_FAILED);
791     }
792     else if ((PH_FRINFC_NDEFMAP_SEEK_CUR == Offset) &&
793         (TRUE == NdefMap->TopazContainer.ReadWriteCompleteFlag))
794     {
795         /* Offset = Current, but the read has reached the End of Card */
796         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
797                             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 
798     }
799     else if (0 == NdefMap->TopazContainer.NdefTLVByteAddress)
800     {
801         /* No NDEF TLV found in the card, so write not possible */
802         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 
803                             NFCSTATUS_NO_NDEF_SUPPORT);
804     }
805     else if ((PH_FRINFC_NDEFMAP_SEEK_BEGIN == Offset) || 
806         (PH_FRINFC_NDEFMAP_WRITE_OPE != NdefMap->PrevOperation))
807     {
808         NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
809         /* Initialise byte number */
810         NdefMap->TopazContainer.Cur_RW_Index = PH_FRINFC_TOPAZ_VAL0;
811         /* State has to be changed */
812         NdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
813         NdefMap->TopazContainer.ReadWriteCompleteFlag = FALSE;
814
815         NdefMap->TopazContainer.CurrentSeg = 0;
816         NdefMap->TopazContainer.CurrentBlock = 1;
817         NdefMap->TopazContainer.WriteSeq = 0;
818
819 #ifdef TOPAZ_RAW_SUPPORT
820
821         *NdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
822
823 #else 
824
825         /* Topaz command = Jewel Nxp Read */
826 #ifdef PH_HAL4_ENABLE
827         NdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
828 #else
829         NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
830 #endif  
831         
832         NdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
833
834 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
835         /* Call read segment */
836         Result = phFriNfc_Tpz_H_NxpRead (NdefMap);
837     }
838     else
839     {
840 #if 0
841         /* This part is to handle the Current offset, 
842         Current offset is not yet validated */
843         Result = phFriNfc_Tpz_H_NxpWrite(NdefMap);
844 #endif /* #if 0 */
845     } 
846     
847     return Result;
848 }
849
850
851 /*!
852 * \brief Completion Routine, Processing function, needed to avoid long blocking.
853 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
854 *       Routine in order to be able to notify the component that an I/O has finished and data are
855 *       ready to be processed.
856 *
857 */
858
859 void phFriNfc_TopazDynamicMap_Process( void       *Context,
860                                NFCSTATUS   Status)
861 {
862
863     phFriNfc_NdefMap_t      *NdefMap; 
864
865     NdefMap = (phFriNfc_NdefMap_t *)Context;
866
867
868     if((NFCSTATUS_SUCCESS & PHNFCSTBLOWER) == (Status & PHNFCSTBLOWER))
869     {
870         switch(NdefMap->State)
871         {
872             case PH_FRINFC_TOPAZ_STATE_READ:
873             {
874                 Status = phFriNfc_Tpz_H_ProReadResp (NdefMap);
875                 break;
876             }
877
878             case PH_FRINFC_TOPAZ_STATE_WRITE:
879             {
880                 Status =  phFriNfc_Tpz_H_ProWrResp (NdefMap);
881                 break;
882             }
883
884             case PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF:
885             {
886                 Status =  phFriNfc_Tpz_H_ProRdForWrResp (NdefMap);
887                 break;
888             }           
889
890             case PH_FRINFC_TOPAZ_STATE_READID:
891             {
892                 Status = phFriNfc_Tpz_H_ChkReadID(NdefMap);
893                 break;
894             }
895
896 #ifdef FRINFC_READONLY_NDEF
897             case PH_FRINFC_TOPAZ_STATE_READ_ONLY:
898             {
899                 Status = phFriNfc_Tpz_H_ProcessReadOnly (NdefMap);
900                 break;
901             }
902 #endif /* #ifdef FRINFC_READONLY_NDEF */
903             
904             default:
905             {
906                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
907                                     NFCSTATUS_INVALID_DEVICE_REQUEST);
908                 break;
909             }
910         }
911     }
912     
913     /* Call for the Completion Routine*/
914     if(Status != NFCSTATUS_PENDING)
915     {
916         phFriNfc_Tpz_H_Complete(NdefMap, Status);
917     }
918 }
919
920 #ifdef FRINFC_READONLY_NDEF
921
922 static 
923 NFCSTATUS
924 phFriNfc_Tpz_H_UpdateAndWriteLockBits (
925     phFriNfc_NdefMap_t          *psNdefMap)
926 {
927     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
928     phFriNfc_TopazCont_t            *ps_tpz_info = NULL;
929     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
930     uint8_t                         remaining_lock_bits = 0;
931     uint8_t                         byte_index = 0;
932     uint8_t                         lock_bytes_value[TOPAZ_BYTES_PER_BLOCK] = {0};
933     uint8_t                         lock_byte_index = 0;
934     uint8_t                         no_of_bits_left_in_block = 0;
935
936     ps_tpz_info = &(psNdefMap->TopazContainer);
937     ps_locktlv_info = &(psNdefMap->LockTlv);
938
939     (void)memcpy ((void *)lock_bytes_value, (void *)psNdefMap->SendRecvBuf, 
940                     TOPAZ_BYTES_PER_BLOCK);
941
942     if (ps_tpz_info->CurrentBlock == ps_locktlv_info->BlkNum)
943     {
944         /* Get the lock bits that has to locked */
945         remaining_lock_bits = ps_locktlv_info->LockTlvBuff[1];
946         byte_index = (uint8_t)ps_locktlv_info->ByteNum;
947     }
948     else
949     {
950         /* This condition applies only for the lock bits not ending with 
951         " ps_locktlv_info->BlkNum ".
952         Calculate the remaining lock bits */
953         remaining_lock_bits = (uint8_t)(ps_locktlv_info->LockTlvBuff[1] - 
954                     ps_tpz_info->lock_bytes_written);
955     }
956
957     no_of_bits_left_in_block = (uint8_t)((TOPAZ_BYTES_PER_BLOCK - byte_index) * 
958                                 TOPAZ_BYTE_SIZE_IN_BITS);
959
960     if (no_of_bits_left_in_block >= remaining_lock_bits)
961     {
962         /* Entire lock bits can be written */
963         uint8_t                 mod_value = 0;
964
965         mod_value = (uint8_t)(remaining_lock_bits % TOPAZ_BYTES_PER_BLOCK);
966
967         if (mod_value)
968         {
969             /* The lock bits ends in between of a byte */
970             /* lock bits to write is greater than 8 bits */
971             if (mod_value > TOPAZ_BYTE_SIZE_IN_BITS)
972             {
973                 while (lock_byte_index < 
974                     (TOPAZ_CONVERT_BITS_TO_BYTES(remaining_lock_bits) - 1))
975                 {
976                     /* Set 1b to all bits left in the block */
977                     lock_bytes_value[byte_index] = 0xFF;
978                     lock_byte_index = (uint8_t)(lock_byte_index + 1);
979                     byte_index = (uint8_t)(byte_index + 1);
980                 }
981                 /* Last byte of the lock bits shall be filled partially,
982                     Set only the remaining lock bits and dont change 
983                     the other bit value */
984                 lock_bytes_value[byte_index] = 0;
985                 lock_bytes_value[byte_index] = (uint8_t)
986                         SET_BITS8 (lock_bytes_value[byte_index], 0, 
987                                     mod_value, 1);
988             }
989             else
990             {
991                 /* lock bits to write is less than 8 bits, so 
992                     there is only one byte to write.
993                     Set only the remaining lock bits and dont change 
994                     the other bit value */
995                 lock_bytes_value[0] = (uint8_t)
996                         SET_BITS8 (lock_bytes_value[0], 0, 
997                                     mod_value, 1);
998             }            
999         } /* if (mod_value) */
1000         else
1001         {
1002             /* The lock bits exactly ends at a byte 
1003             MOD operation is 00, that means entire byte value shall be 0xFF, means
1004             every bit shall be to 1 */
1005
1006             while (lock_byte_index < TOPAZ_CONVERT_BITS_TO_BYTES(remaining_lock_bits))
1007             {
1008                 /* Set 1b to all bits left in the block */
1009                 lock_bytes_value[byte_index] = 0xFF;
1010                 lock_byte_index = (uint8_t)(lock_byte_index + 1);
1011                 byte_index = (uint8_t)(byte_index + 1);
1012             }
1013         } /* else of if (mod_value) */
1014         ps_tpz_info->lock_bytes_written = remaining_lock_bits;
1015     }
1016     else /* if (no_of_bits_left_in_block >= remaining_lock_bits) */
1017     {
1018         /* Partial lock bits can be written. use next read to write 
1019             the remaining lock bits  */
1020         while (lock_byte_index <  (no_of_bits_left_in_block / 
1021                             TOPAZ_BYTES_PER_BLOCK))
1022         {
1023             /* Set 1b to all bits left in the block */
1024             lock_bytes_value[byte_index] = 0xFF;
1025             lock_byte_index = (uint8_t)(lock_byte_index + 1);
1026             byte_index = (uint8_t)(byte_index + 1);
1027         }
1028         ps_tpz_info->lock_bytes_written = (uint8_t)(no_of_bits_left_in_block / 
1029                             TOPAZ_BYTES_PER_BLOCK);
1030     } /* else of if (no_of_bits_left_in_block >= remaining_lock_bits) */
1031
1032 #ifdef TOPAZ_RAW_SUPPORT
1033     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
1034 #else
1035     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
1036 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1037
1038     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, lock_bytes_value, 
1039                                     sizeof (lock_bytes_value));
1040     return result;
1041 }
1042
1043 static
1044 NFCSTATUS
1045 phFriNfc_Tpz_H_ProcessReadOnly (
1046     phFriNfc_NdefMap_t          *psNdefMap)
1047 {
1048     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
1049     phFriNfc_Tpz_RO_Seq_t               e_readonly_seq = RD_LOCK_BYTES;
1050     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
1051     phFriNfc_LockCntrlTLVCont_t         *ps_locktlv_info = NULL;
1052     static uint8_t                      static_lock_bytes[2] = {0};
1053
1054     ps_tpz_info = &(psNdefMap->TopazContainer);
1055     ps_locktlv_info = &(psNdefMap->LockTlv);
1056     e_readonly_seq = (phFriNfc_Tpz_RO_Seq_t)psNdefMap->TopazContainer.read_only_seq;
1057
1058     switch (e_readonly_seq)
1059     {
1060         case WR_READONLY_CC:
1061         {
1062             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1063             {
1064                 psNdefMap->TopazContainer.CurrentBlock = (uint8_t)
1065                                 psNdefMap->LockTlv.BlkNum;
1066
1067                 e_readonly_seq = RD_LOCK_BYTES;
1068 #ifdef TOPAZ_RAW_SUPPORT
1069
1070                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
1071
1072 #else 
1073
1074         /* Topaz command = Jewel Nxp Read */
1075 #ifdef PH_HAL4_ENABLE
1076                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1077 #else
1078                 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1079 #endif  
1080         
1081                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
1082
1083 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1084                 /* Call read segment */
1085                 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1086             }
1087             else
1088             {
1089                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1090                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1091             }
1092             break;
1093         }
1094
1095         case RD_LOCK_BYTES:
1096         {
1097             if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
1098             { 
1099                 result = phFriNfc_Tpz_H_UpdateAndWriteLockBits (psNdefMap);
1100
1101                 if (NFCSTATUS_PENDING == result)
1102                 {
1103                     e_readonly_seq = WR_LOCK_BYTES;
1104                 }
1105             }
1106             else
1107             {
1108                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1109                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1110             }
1111             break;
1112         }
1113
1114         case WR_LOCK_BYTES:
1115         {
1116             if (TOPAZ_WRITE_8_RESPONSE == *psNdefMap->SendRecvLength)
1117             {
1118                 ps_tpz_info->CurrentBlock = (uint8_t)
1119                                         (ps_tpz_info->CurrentBlock + 1); 
1120                 if (ps_locktlv_info->LockTlvBuff[1] - 
1121                     ps_tpz_info->lock_bytes_written)
1122                 {                    
1123 #ifdef TOPAZ_RAW_SUPPORT
1124
1125                     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
1126
1127 #else 
1128
1129                     /* Topaz command = Jewel Nxp Read */
1130 #ifdef PH_HAL4_ENABLE
1131                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1132 #else
1133                     psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1134 #endif  
1135         
1136                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
1137
1138 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1139                     /* Call read segment */
1140                     result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1141                     e_readonly_seq = RD_LOCK_BYTES;
1142                 }
1143                 else
1144                 {
1145                     ps_tpz_info->CurrentBlock = (uint8_t)
1146                                         DYN_STATIC_LOCK_BLOCK_NUM;
1147                     ps_tpz_info->ByteNumber = (uint8_t)
1148                                         DYN_STATIC_LOCK0_BYTE_NUM;
1149 #ifdef TOPAZ_RAW_SUPPORT
1150
1151                     *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_READ8;
1152
1153 #else 
1154
1155                     /* Topaz command = Jewel Nxp Read */
1156 #ifdef PH_HAL4_ENABLE
1157                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1158 #else
1159                     psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1160 #endif  
1161         
1162                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
1163
1164 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1165                     /* Call read segment */
1166                     result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1167                     e_readonly_seq = RD_STATIC_LOCK_BYTE0;
1168
1169                 }                
1170             }
1171             else
1172             {
1173                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1174                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1175             }
1176             break;
1177         }
1178         
1179         case RD_STATIC_LOCK_BYTE0:
1180         {
1181             if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
1182             {
1183                 uint8_t                 lock_byte_value = 0;
1184
1185                 (void)memcpy ((void *)static_lock_bytes, 
1186                             (void *)(psNdefMap->SendRecvBuf + 
1187                                 ps_tpz_info->ByteNumber), 
1188                             sizeof (static_lock_bytes));
1189
1190
1191                 lock_byte_value = (uint8_t)(static_lock_bytes[0] | 
1192                                     DYN_STATIC_LOCK0_BYTE_VALUE);
1193                     
1194 #ifdef TOPAZ_RAW_SUPPORT
1195                     *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1196 #else
1197                     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1198 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1199
1200                 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &lock_byte_value, 
1201                                                     1);
1202
1203                     if (NFCSTATUS_PENDING == result)
1204                     {
1205                     e_readonly_seq = (uint8_t)WR_STATIC_LOCK_BYTE0;
1206                     }
1207                 }                
1208             else
1209             {
1210                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1211                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1212             }
1213             break;
1214         }        
1215
1216         case WR_STATIC_LOCK_BYTE0:
1217         {
1218             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1219             {
1220                 uint8_t                 lock_byte_value = 
1221                                         (static_lock_bytes[1] | 
1222                                         DYN_STATIC_LOCK1_BYTE_VALUE);
1223
1224                 ps_tpz_info->CurrentBlock = (uint8_t)
1225                                     DYN_STATIC_LOCK_BLOCK_NUM;
1226                 ps_tpz_info->ByteNumber = (uint8_t)
1227                                     DYN_STATIC_LOCK1_BYTE_NUM;
1228 #ifdef TOPAZ_RAW_SUPPORT
1229                 *psNdefMap->SendRecvBuf = (uint8_t)PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1230 #else
1231                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1232 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1233
1234                 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, &lock_byte_value, 
1235                                                     1);
1236
1237                 if (NFCSTATUS_PENDING == result)
1238                 {
1239                     e_readonly_seq = (uint8_t)WR_STATIC_LOCK_BYTE1;
1240                 }
1241             }
1242             else
1243             {
1244                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1245                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1246             }
1247             break;
1248         }
1249
1250         case WR_STATIC_LOCK_BYTE1:
1251         {
1252             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1253             {
1254                 /* READ ONLY successful */
1255             }
1256             else
1257             {
1258                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1259                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1260             }
1261             break;
1262         }
1263
1264         default:
1265         {
1266             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1267                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1268             break;
1269         }
1270     }
1271
1272     psNdefMap->TopazContainer.read_only_seq = (uint8_t)e_readonly_seq;
1273     return result;
1274 }
1275
1276 #endif /* #ifdef FRINFC_READONLY_NDEF */
1277
1278 static 
1279 NFCSTATUS 
1280 phFriNfc_Tpz_H_ProWrResp (
1281     phFriNfc_NdefMap_t          *psNdefMap)
1282 {
1283     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
1284     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
1285     phFriNfc_Tpz_WrSeq_t                write_seq;
1286     uint8_t                             write_buf[] = {0x00};
1287     uint8_t                             write_index = 0;
1288     uint16_t                            write_len = 0;
1289     uint16_t                            len_byte_addr = 0;
1290
1291     ps_tpz_info = &(psNdefMap->TopazContainer);
1292     write_seq = (phFriNfc_Tpz_WrSeq_t)(ps_tpz_info->WriteSeq);
1293     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ? 
1294                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
1295
1296     switch (write_seq)
1297     {
1298         case WR_NDEF_T_TLV:
1299         {
1300             /* TYPE field of the NDEF TLV write is complete */
1301             if (TOPAZ_WRITE_8_RESPONSE == *psNdefMap->SendRecvLength)
1302             {
1303                 psNdefMap->State = (uint8_t)
1304                                     PH_FRINFC_TOPAZ_STATE_WRITE;
1305
1306                 /* Now, Write 0 to the magic number byte */
1307                 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_0;
1308                 write_seq = WR_NMN_0;
1309                 ps_tpz_info->CurrentBlock = 1;
1310                 ps_tpz_info->ByteNumber = 0;
1311                         
1312 #ifdef TOPAZ_RAW_SUPPORT
1313                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1314 #else
1315                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1316 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1317                 result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf, 
1318                                                 sizeof (write_buf));
1319             }
1320             else
1321             {
1322                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1323                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1324             }
1325             break;
1326         }
1327
1328         case WR_NMN_0:
1329         {
1330             /* Magic number set to 0 write is complete */
1331             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1332             {
1333                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1334                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1335                 /* Now the sequence = WR_LEN_1_0, so Length block is read, 
1336                     and only length bytes are made 0, before writing data to 0 
1337                 */
1338                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1339             }
1340             else
1341             {
1342                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1343                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1344             }
1345             break;
1346         }
1347
1348         case WR_LEN_1_0:
1349         {
1350             /* Length field is updated with the value 0 */
1351             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1352             {
1353                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1354                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1355             }
1356             else if (write_len >= 0xFF)
1357             {
1358                 ps_tpz_info->ByteNumber = 0;
1359                 
1360                 ps_tpz_info->CurrentBlock = (uint8_t)
1361                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1362                                     ps_tpz_info->CurrentBlock);                
1363
1364                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1365                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1366                 /* Now the sequence = WR_LEN_1_1, so Length block is read, 
1367                     and only length bytes are made 0, before writing data to 0 
1368                 */
1369                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1370             }
1371             else
1372             {
1373                 /* NDEF data length < 0xFF */
1374                 len_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite 
1375                                                 (psNdefMap, write_len);
1376                 ps_tpz_info->CurrentBlock = (uint8_t)
1377                         TOPAZ_BLK_FROM_BYTE_ADR (len_byte_addr);
1378                 ps_tpz_info->ByteNumber = (uint8_t)
1379                         TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (len_byte_addr);
1380
1381                 
1382                 ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
1383                 write_seq = WR_DATA;
1384
1385                 if (0 != ps_tpz_info->ByteNumber)
1386                 {
1387                     /* If data starts in between the block then read 
1388                         the data */
1389                     result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1390                 }
1391                 else
1392                 {
1393                     /* Data starts at the beginning of the block, so start 
1394                         writing the user data */
1395                     result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
1396                 }
1397             }
1398             break;
1399         }
1400
1401         case WR_LEN_2_0:
1402         case WR_LEN_2_VALUE:
1403         {
1404             /* 2nd length field is updated with the value 0 or the correct 
1405                 written value */
1406             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1407             {
1408                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1409                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1410             }
1411             else
1412             {
1413                 ps_tpz_info->ByteNumber = 0;
1414                 ps_tpz_info->CurrentBlock = (uint8_t)
1415                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1416                                     ps_tpz_info->CurrentBlock);
1417                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1418                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1419                 /* If length byte starts in between the block then read 
1420                     the length block */
1421                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1422             }
1423             break;
1424         }
1425
1426         case WR_LEN_3_0:
1427         {
1428             /* 3rd length field is updated with the value 0 */
1429             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1430             {
1431                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1432                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1433             }
1434             else
1435             {
1436                 len_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite 
1437                                                 (psNdefMap, write_len);
1438                 ps_tpz_info->CurrentBlock = (uint8_t)
1439                         TOPAZ_BLK_FROM_BYTE_ADR (len_byte_addr);
1440                 ps_tpz_info->ByteNumber = (uint8_t)
1441                         TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (len_byte_addr);
1442
1443                 ps_tpz_info->WriteSeq = (uint8_t)(write_seq + 1);
1444                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
1445
1446                 if (0 != ps_tpz_info->ByteNumber)
1447                 {
1448                     /* If data starts in between the block then read 
1449                         the data */
1450                     result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1451                 }
1452                 else
1453                 {
1454                     /* Data starts at the beginning of the block, so start 
1455                         writing the user data */
1456                     result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
1457                 }
1458             }
1459             break;
1460         }
1461
1462         case WR_DATA:
1463         {
1464             /* Data is written from the input buffer */
1465             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1466             {
1467                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1468                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1469             }
1470             else if (write_len == psNdefMap->ApduBuffIndex)
1471             {
1472                 /* Data to be written is completely written to the card */
1473                 *psNdefMap->WrNdefPacketLength = psNdefMap->ApduBuffIndex;
1474                 ps_tpz_info->WriteSeq = (uint8_t)WR_LEN_1_VALUE;
1475                 write_seq = WR_LEN_1_VALUE;
1476                 /* To write the first length byte, it has to be read and then 
1477                     the length has to be updated */
1478                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1479             }
1480             else
1481             {
1482                 ps_tpz_info->ByteNumber = 0;
1483                 /* Go to the next block */
1484                 ps_tpz_info->CurrentBlock = (uint8_t)
1485                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1486                                     ps_tpz_info->CurrentBlock);
1487                 /* Copy and write the user data */
1488                 result = phFriNfc_Tpz_H_CopySendWrData (psNdefMap);
1489             }
1490             break;
1491         }
1492
1493         case WR_DATA_READ_REQD: 
1494         {
1495             /* This sequence is executed, if the first read has some 
1496                 lock or reserved blocks bytes and the lock or reserved 
1497                 blocks are extended to the next block  */
1498             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1499             {
1500                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1501                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1502             }
1503             else
1504             {
1505                 ps_tpz_info->ByteNumber = 0;
1506                 /* Go to the next block */
1507                 ps_tpz_info->CurrentBlock = (uint8_t)
1508                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1509                                     ps_tpz_info->CurrentBlock);
1510                 /* Write is complete for one block, now because lock bytes are 
1511                     shifted to next blocks, the next block is read and update 
1512                     the written data by skipping the lock or reserved memory bytes */
1513                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1514             }
1515             break;
1516         }
1517
1518         case WR_LEN_3_VALUE:
1519         {
1520             /* 3rd LENGTH field byte is updated with correct written value */
1521             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1522             {
1523                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1524                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1525             }
1526             else
1527             {
1528 #ifdef TOPAZ_RAW_SUPPORT
1529                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1530 #else
1531                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1532 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1533
1534                 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
1535
1536                 write_buf[write_index] = PH_FRINFC_TOPAZ_CC_BYTE0;
1537                 write_index = (uint8_t)(write_index + 1);
1538
1539                 ps_tpz_info->ByteNumber = 0;
1540                 ps_tpz_info->CurrentBlock = 1;
1541
1542                 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_E1;
1543                 write_seq = WR_NMN_E1;
1544
1545                 /* Length byte write is complete, so now update the magic 
1546                     number byte with value 0xE1 */
1547                 result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf, 
1548                                                 write_index);
1549             }
1550             break;
1551         }
1552
1553         case WR_LEN_1_VALUE:
1554         {
1555             /* 1st LENGTH field byte is updated */
1556             if (TOPAZ_WRITE_8_RESPONSE != *psNdefMap->SendRecvLength)
1557             {
1558                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1559                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1560             }
1561             else if (write_len < 0xFF)
1562             {
1563                 /* Total length to write is less than 0xFF, so LENGTH field has 
1564                     only one byte, then update the magic number byte with 
1565                     value 0xE1 */
1566 #ifdef TOPAZ_RAW_SUPPORT
1567                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1568 #else
1569                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1570 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1571                 psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
1572
1573                 write_buf[write_index] = PH_FRINFC_TOPAZ_CC_BYTE0;
1574                 write_index = (uint8_t)(write_index + 1);
1575
1576                 ps_tpz_info->ByteNumber = 0;
1577                 ps_tpz_info->CurrentBlock = 1;
1578
1579                 ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_E1;
1580                 write_seq = WR_NMN_E1;
1581                 result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf, 
1582                                                 write_index);
1583             }
1584             else
1585             {
1586                 /* 2nd byte of the LENGTH field has to be updated so, 
1587                     read the block, before updating it */
1588                 ps_tpz_info->ByteNumber = 0;
1589                 ps_tpz_info->CurrentBlock = (uint8_t)
1590                                     TOPAZ_INCREMENT_SKIP_STATIC_BLOCK (
1591                                     ps_tpz_info->CurrentBlock);
1592                 ps_tpz_info->WriteSeq = (uint8_t)WR_LEN_2_VALUE;
1593                 write_seq = WR_LEN_2_VALUE;
1594                 result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
1595             }
1596             break;
1597         }
1598
1599         case WR_NMN_E1:
1600         {
1601             /* Magic number is written, so update the actual ndef length.  */
1602             if (TOPAZ_WRITE_1_RESPONSE == *psNdefMap->SendRecvLength)
1603             {
1604                 *psNdefMap->WrNdefPacketLength = (uint32_t)
1605                                                 psNdefMap->ApduBuffIndex;
1606                 ps_tpz_info->ActualNDEFMsgSize = (uint16_t)
1607                                                 psNdefMap->ApduBuffIndex;
1608             }
1609             else
1610             {
1611                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1612                                     NFCSTATUS_INVALID_RECEIVE_LENGTH);
1613             }
1614             break;
1615         }
1616
1617         default:
1618         {
1619             break;
1620         }
1621     }
1622
1623     return result;
1624 }
1625
1626 static 
1627 NFCSTATUS 
1628 phFriNfc_Tpz_H_UpdateNdefTypeField (
1629     phFriNfc_NdefMap_t          *psNdefMap)
1630 {
1631     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
1632     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
1633     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
1634
1635     ps_tpz_info = &(psNdefMap->TopazContainer);
1636
1637     (void)memcpy ((void *)write_buf, (void *)
1638                 psNdefMap->SendRecvBuf, TOPAZ_WRITE_8_DATA_LENGTH);
1639
1640     /* Update the TYPE field of the NDEF TLV */
1641     write_buf[ps_tpz_info->ByteNumber] = PH_FRINFC_TOPAZ_NDEF_T;
1642
1643     psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
1644
1645 #ifdef TOPAZ_RAW_SUPPORT
1646     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
1647 #else
1648     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
1649 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1650     result = phFriNfc_Tpz_H_NxpWrite(psNdefMap, write_buf, 
1651                                     sizeof (write_buf));
1652
1653     return result;
1654 }
1655
1656 static 
1657 NFCSTATUS 
1658 phFriNfc_Tpz_H_ProRdForWrResp (
1659     phFriNfc_NdefMap_t          *psNdefMap)
1660 {
1661     /* This function is used during the write operation */
1662     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
1663     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;    
1664
1665     ps_tpz_info = &(psNdefMap->TopazContainer);    
1666
1667     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1668
1669     if (TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
1670     {        
1671         switch ((phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq)
1672         {
1673             case WR_NDEF_T_TLV:
1674             {
1675                 /* Read bytes are for updating the TYPE field of the NDEF TLV */
1676                 result = phFriNfc_Tpz_H_UpdateNdefTypeField (psNdefMap);
1677                 break;
1678             }
1679
1680             case WR_LEN_1_0:
1681             case WR_LEN_2_0:
1682             case WR_LEN_3_0:
1683             {
1684                 /* Read bytes are for updating the LENGTH field to 0 of the NDEF TLV and 
1685                 also to update the data from the user buffer */
1686                 result = phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (psNdefMap);
1687                 break;
1688             }
1689
1690             case WR_DATA:
1691             case WR_DATA_READ_REQD:
1692             {
1693                 /* Read bytes are for skipping the lock and reserved bytes */
1694                 result = phFriNfc_Tpz_H_CopyReadDataAndWrite (psNdefMap);
1695                 break;
1696             }
1697
1698             case WR_LEN_1_VALUE:
1699             case WR_LEN_2_VALUE:
1700             case WR_LEN_3_VALUE:
1701             {
1702                 /* Read bytes are for updating the LENGTH field to the correct values 
1703                     of the NDEF TLV */
1704                 result = phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (psNdefMap);
1705                 break;
1706             }
1707
1708             default:
1709             {
1710                 /* Code must not come come here */
1711                 break;
1712             }
1713         }
1714     }
1715     else
1716     {
1717         /* Error in the length, wither the HW has sent wrong response length or 
1718             the response length byte is corrupted */
1719         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1720                             NFCSTATUS_INVALID_RECEIVE_LENGTH);
1721     }
1722
1723     
1724     return result;
1725 }
1726
1727 static 
1728 NFCSTATUS 
1729 phFriNfc_Tpz_H_ChkReadID(
1730     phFriNfc_NdefMap_t      *psNdefMap)
1731 {
1732     NFCSTATUS   result = NFCSTATUS_SUCCESS;
1733     int         compare_result = 0;
1734     uint8_t     recv_index = 0;
1735     
1736     
1737     if (PH_FRINFC_TOPAZ_VAL6 == *psNdefMap->SendRecvLength)
1738     {
1739         if (((psNdefMap->SendRecvBuf[recv_index] & 
1740             PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_DYNAMIC_HEADROM0_VAL))
1741         {
1742             /* Copy UID to the context*/
1743             compare_result = phOsalNfc_MemCompare (
1744                                 psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid, 
1745                                 &psNdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
1746                                 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1747             if (0 == compare_result)
1748             {
1749                 /* State has to be changed */
1750                 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_READ;
1751
1752                 /* Topaz command = READSEG */
1753 #ifdef TOPAZ_RAW_SUPPORT
1754
1755                 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
1756
1757 #else
1758
1759 #ifdef PH_HAL4_ENABLE
1760                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read;
1761 #else
1762                 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead;
1763 #endif
1764                 psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
1765
1766 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1767                 /* Read bytes from the card */
1768                 result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
1769             }
1770             else
1771             {
1772                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1773                                     NFCSTATUS_NO_NDEF_SUPPORT);
1774
1775             }
1776         }
1777     }
1778     else
1779     {
1780         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1781                             NFCSTATUS_INVALID_RECEIVE_LENGTH);
1782     }
1783
1784     return result;
1785 }
1786
1787 #define TOPAZ_READ_ID_ZERO_LENGTH                   (0x06U)
1788 static 
1789 NFCSTATUS 
1790 phFriNfc_Tpz_H_NxpRead (
1791     phFriNfc_NdefMap_t          *psNdefMap)
1792 {
1793     NFCSTATUS           result = NFCSTATUS_SUCCESS;
1794     uint8_t             send_index = 0;
1795 #ifdef TOPAZ_RAW_SUPPORT
1796     uint8_t             read_append[] = { 0x00, 0x00, 0x00, 0x00, 
1797                                         0x00, 0x00, 0x00, 0x00};
1798 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1799
1800     /* set the data for additional data exchange*/
1801     psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
1802     psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
1803     psNdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
1804
1805     psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazDynamicMap_Process;
1806     psNdefMap->MapCompletionInfo.Context = psNdefMap;
1807
1808     *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
1809
1810     /* Depending on the jewel command, the send length is decided */
1811 #ifdef TOPAZ_RAW_SUPPORT
1812
1813     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1814     /* " send_index " is incremented because already received buffer is filled with 
1815         TOPAZ command */
1816     send_index = (uint8_t)(send_index + 1);
1817
1818     switch (*psNdefMap->SendRecvBuf)
1819 #else
1820     switch(psNdefMap->Cmd.JewelCmd)
1821 #endif /* #ifdef TOPAZ_RAW_SUPPORT */    
1822     {
1823 #ifdef TOPAZ_RAW_SUPPORT
1824
1825         case PH_FRINFC_TOPAZ_CMD_READID:
1826         {
1827             (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), 
1828                         (void *)read_append, TOPAZ_READ_ID_ZERO_LENGTH);
1829             send_index = (uint8_t)(send_index + TOPAZ_READ_ID_ZERO_LENGTH);
1830             break;
1831         }
1832
1833         case PH_FRINFC_TOPAZ_CMD_READ8:
1834         {
1835             psNdefMap->SendRecvBuf[send_index] = 
1836                                     psNdefMap->TopazContainer.CurrentBlock;
1837             send_index = (uint8_t)(send_index + 1);
1838             break;
1839         }
1840
1841         case PH_FRINFC_TOPAZ_CMD_RSEG:
1842         {
1843             psNdefMap->SendRecvBuf[send_index] = (uint8_t)
1844                                             (psNdefMap->TopazContainer.CurrentSeg
1845                                              << NIBBLE_SIZE);
1846             send_index = (uint8_t)(send_index + 1);
1847             break;
1848         }
1849
1850 #else /* #ifdef TOPAZ_RAW_SUPPORT */
1851
1852 #ifdef PH_HAL4_ENABLE
1853         case phHal_eJewel_RID:
1854         case phHal_eJewel_ReadAll:  
1855 #else
1856         case phHal_eJewelCmdListJewelRid:
1857         case phHal_eJewelCmdListJewelReadAll:
1858 #endif
1859         {
1860             /* For READ ID and READ ALL, send length is 0 */
1861             psNdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
1862             break;
1863         }
1864
1865 #ifdef PH_HAL4_ENABLE
1866         case phHal_eJewel_Read:
1867 #else
1868         case phHal_eJewelCmdListJewelRead:
1869 #endif
1870         {
1871             /* Need to check the User data size request*/
1872
1873             psNdefMap->SendLength = PH_FRINFC_TOPAZ_VAL3;
1874             break;
1875         }
1876
1877         case phHal_eJewel_ReadSeg:
1878         {
1879             psNdefMap->SendRecvBuf[send_index] = (uint8_t)
1880                                             (psNdefMap->TopazContainer.CurrentSeg
1881                                              << NIBBLE_SIZE);
1882             send_index = (uint8_t)(send_index + 1);
1883             psNdefMap->SendLength = send_index;
1884             break;
1885         }
1886
1887         case phHal_eJewel_Read8:
1888         {
1889             psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read4;
1890             psNdefMap->SendRecvBuf[send_index] = psNdefMap->TopazContainer.CurrentBlock;
1891             send_index = (uint8_t)(send_index + 1);
1892             psNdefMap->SendLength = send_index;
1893             break;
1894         }
1895
1896 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1897
1898         default:
1899         {
1900             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1901                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
1902             break;
1903         }
1904     }
1905     if(result == NFCSTATUS_SUCCESS)
1906     {
1907 #ifdef TOPAZ_RAW_SUPPORT
1908
1909         if (PH_FRINFC_TOPAZ_CMD_READID != *psNdefMap->SendRecvBuf)
1910         {
1911             (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), 
1912                             (void *)read_append, sizeof (read_append));
1913             send_index = (uint8_t)(send_index + sizeof (read_append));
1914
1915             (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), 
1916                         (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid, 
1917                         TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1918             send_index = (uint8_t)(send_index + 
1919                         TOPAZ_UID_LENGTH_FOR_READ_WRITE);            
1920         }
1921
1922         psNdefMap->SendLength = send_index;
1923
1924 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1925         /* Call the Overlapped HAL Transceive function */ 
1926         result = phFriNfc_OvrHal_Transceive(    psNdefMap->LowerDevice,
1927                                                 &psNdefMap->MapCompletionInfo,
1928                                                 psNdefMap->psRemoteDevInfo,
1929                                                 psNdefMap->Cmd,
1930                                                 &psNdefMap->psDepAdditionalInfo,
1931                                                 psNdefMap->SendRecvBuf,
1932                                                 psNdefMap->SendLength,
1933                                                 psNdefMap->SendRecvBuf,
1934                                                 psNdefMap->SendRecvLength);
1935     }
1936     return result;
1937 }
1938
1939
1940 static 
1941 NFCSTATUS 
1942 phFriNfc_Tpz_H_NxpWrite(
1943     phFriNfc_NdefMap_t          *psNdefMap, 
1944     uint8_t                     *p_write_data, 
1945     uint8_t                     wr_data_len)
1946 {
1947     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
1948     phFriNfc_TopazCont_t        *ps_tpz_info = NULL;
1949     uint8_t                     send_index = 0;
1950
1951     ps_tpz_info = &(psNdefMap->TopazContainer);        
1952
1953     /* set the data for additional data exchange*/
1954     psNdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
1955     psNdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
1956     psNdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
1957
1958     psNdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazDynamicMap_Process;
1959     psNdefMap->MapCompletionInfo.Context = psNdefMap;
1960
1961     *psNdefMap->SendRecvLength = psNdefMap->TempReceiveLength;
1962
1963 #ifdef TOPAZ_RAW_SUPPORT
1964     /* " send_index " is incremented because already received buffer is filled with 
1965         TOPAZ command */
1966     send_index = (uint8_t)(send_index + 1);
1967     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1968
1969     switch (*psNdefMap->SendRecvBuf)
1970
1971 #else /* #ifdef TOPAZ_RAW_SUPPORT */
1972
1973     switch (psNdefMap->Cmd.JewelCmd)
1974
1975 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1976     {
1977 #ifdef TOPAZ_RAW_SUPPORT
1978
1979         case PH_FRINFC_TOPAZ_CMD_WRITE_1E:
1980         {
1981             psNdefMap->SendRecvBuf[send_index] = (uint8_t)((ps_tpz_info->CurrentBlock 
1982                                                 << (NIBBLE_SIZE - 1)) | 
1983                                                 ps_tpz_info->ByteNumber);
1984             send_index = (uint8_t)(send_index + 1);
1985             break;
1986         }
1987
1988         case PH_FRINFC_TOPAZ_CMD_WRITE_E8:
1989         {
1990             psNdefMap->SendRecvBuf[send_index] = ps_tpz_info->CurrentBlock;
1991             send_index = (uint8_t)(send_index + 1);
1992             break;
1993         }
1994
1995 #else /* #ifdef TOPAZ_RAW_SUPPORT */
1996
1997         case phHal_eJewel_Write1E:
1998         {
1999             psNdefMap->SendRecvBuf[send_index] = (uint8_t)((ps_tpz_info->CurrentBlock 
2000                                                 << (NIBBLE_SIZE - 1)) | 
2001                                                 ps_tpz_info->ByteNumber);
2002             send_index = (uint8_t)(send_index + 1);
2003
2004             
2005             break;
2006         }
2007
2008         case phHal_eJewel_Write8E:
2009         {
2010             psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write4E;
2011             psNdefMap->SendRecvBuf[send_index] = ps_tpz_info->CurrentBlock;
2012             send_index = (uint8_t)(send_index + 1);
2013             break;
2014         }
2015
2016 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2017
2018         default:
2019         {
2020             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2021                                 NFCSTATUS_INVALID_DEVICE_REQUEST); 
2022             break;
2023         }
2024     }
2025   
2026
2027     if (NFCSTATUS_SUCCESS == result)
2028     {
2029         (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), 
2030                     (void *)p_write_data, wr_data_len);
2031
2032         send_index = (uint8_t)(send_index + wr_data_len);
2033
2034 #ifdef TOPAZ_RAW_SUPPORT
2035
2036         (void)memcpy ((void *)(psNdefMap->SendRecvBuf + send_index), 
2037                     (void *)psNdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid, 
2038                     TOPAZ_UID_LENGTH_FOR_READ_WRITE);
2039         send_index = (uint8_t)(send_index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
2040
2041 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2042
2043         psNdefMap->SendLength = send_index;
2044
2045         /* Call the Overlapped HAL Transceive function */ 
2046         result = phFriNfc_OvrHal_Transceive(    psNdefMap->LowerDevice,
2047                                                 &psNdefMap->MapCompletionInfo,
2048                                                 psNdefMap->psRemoteDevInfo,
2049                                                 psNdefMap->Cmd,
2050                                                 &psNdefMap->psDepAdditionalInfo,
2051                                                 psNdefMap->SendRecvBuf,
2052                                                 psNdefMap->SendLength,
2053                                                 psNdefMap->SendRecvBuf,
2054                                                 psNdefMap->SendRecvLength);
2055     }
2056     return result;
2057 }
2058
2059 static 
2060 NFCSTATUS 
2061 phFriNfc_Tpz_H_ProReadResp(
2062     phFriNfc_NdefMap_t          *psNdefMap)
2063 {
2064     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
2065     phFriNfc_TopazCont_t        *ps_tpz_info = NULL;
2066     uint8_t                     write_buffer[] = {0x00};
2067
2068     ps_tpz_info = &(psNdefMap->TopazContainer);
2069
2070     switch (psNdefMap->PrevOperation)
2071     {
2072         case  PH_FRINFC_NDEFMAP_CHECK_OPE:
2073         {
2074             if (PH_FRINFC_TOPAZ_DYNAMIC_READSEG_RESP == 
2075                 *psNdefMap->SendRecvLength)
2076             {
2077                 if (0 == ps_tpz_info->CurrentSeg)
2078                 {
2079                     result = phFriNfc_Tpz_H_CheckCCBytes (psNdefMap);
2080                 }
2081
2082                 if (NFCSTATUS_SUCCESS == result)
2083                 {
2084                     result = phFriNfc_Tpz_H_ParseTLVs (psNdefMap);
2085                 }
2086             }
2087             else
2088             {
2089                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2090                                     NFCSTATUS_INVALID_RECEIVE_LENGTH); 
2091             }
2092             break;
2093         }
2094
2095         case  PH_FRINFC_NDEFMAP_READ_OPE:
2096         {
2097             if (PH_FRINFC_TOPAZ_DYNAMIC_READSEG_RESP == 
2098                 *psNdefMap->SendRecvLength)
2099             {
2100                 /* call the data bytes to internal buffer*/
2101                 result = phFriNfc_Tpz_H_CopyReadData (psNdefMap);
2102             }
2103             else
2104             {
2105                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2106                                     NFCSTATUS_INVALID_RECEIVE_LENGTH); 
2107             }
2108             break;
2109         }
2110
2111         case  PH_FRINFC_NDEFMAP_WRITE_OPE:
2112         {
2113             /* read the bytes for cheking the CC bytes and lock bit status*/
2114             if(TOPAZ_READ_8_RESPONSE == *psNdefMap->SendRecvLength)
2115             {
2116                 (void)memcpy ((void *)ps_tpz_info->CCByteBuf, 
2117                             (void *)(psNdefMap->SendRecvBuf), 
2118                             TOPAZ_CC_BYTES_LENGTH);
2119
2120                 result = phFriNfc_Tpz_H_CheckCCBytesForWrite (psNdefMap);
2121                 if (NFCSTATUS_SUCCESS == result)
2122                 {
2123                     if ((0x00 == *ps_tpz_info->CCByteBuf) || 
2124                         (NDEF_T_TLV == ps_tpz_info->ExpectedSeq))
2125                     {
2126                         /* This statement is for getting the new 
2127                             NDEF TLV byte address, because 1st CC byte is  
2128                             corrupted or no NDEF TLV in the card
2129
2130                             If the 1st CC byte (NDEF magic number) in the  
2131                             card is 0, means that previous write has failed, 
2132                             so to write the exact file 
2133                             OR
2134                             The NDEF TLV is not present in the entire card, and  
2135                             the sequence is NDEF_T_TLV (this means, that lock and  
2136                             memory control TLV is found in the card)                
2137                         */
2138                         psNdefMap->State = (uint8_t)
2139                                         PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF;
2140                         ps_tpz_info->WriteSeq = (uint8_t)WR_NDEF_T_TLV;
2141
2142                         ps_tpz_info->CurrentBlock = (uint8_t)
2143                                     TOPAZ_BLK_FROM_BYTE_ADR (
2144                                         ps_tpz_info->NdefTLVByteAddress);
2145
2146                         ps_tpz_info->ByteNumber = (uint8_t)
2147                                     TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (
2148                                         ps_tpz_info->NdefTLVByteAddress);
2149
2150 #ifdef TOPAZ_RAW_SUPPORT
2151                         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
2152 #else
2153                         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
2154 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2155
2156                         result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
2157                     }
2158                     else
2159                     {
2160                         ps_tpz_info->WriteSeq = (uint8_t)WR_NMN_0;
2161                         ps_tpz_info->CurrentBlock = 1;
2162                         ps_tpz_info->ByteNumber = 0;
2163                         psNdefMap->State = (uint8_t)
2164                                             PH_FRINFC_TOPAZ_STATE_WRITE;
2165 #ifdef TOPAZ_RAW_SUPPORT
2166                         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
2167 #else
2168                         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
2169 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2170
2171                         /* Call read 8 */
2172                         result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buffer, 
2173                                                     sizeof (write_buffer));
2174                     }
2175                     
2176                 }
2177             }
2178             else
2179             {
2180                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2181                                     NFCSTATUS_INVALID_RECEIVE_LENGTH); 
2182             }
2183             break;
2184         }
2185
2186         default:
2187         {
2188             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2189                                 NFCSTATUS_INVALID_DEVICE_REQUEST);
2190             break;
2191         }
2192     }
2193     
2194     return result;
2195 }
2196
2197
2198
2199 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t  *NdefMap,
2200                                     NFCSTATUS           Status)
2201 {
2202     /* set the state back to the Reset_Init state*/
2203     NdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
2204
2205     /* set the completion routine*/
2206     NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex].
2207         CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
2208 }
2209
2210 static 
2211 NFCSTATUS  
2212 phFriNfc_Tpz_H_ChkLockBits(
2213     phFriNfc_NdefMap_t  *psNdefMap)
2214 {
2215     NFCSTATUS           result = NFCSTATUS_SUCCESS;
2216 #ifdef ENABLE_LOCK_BITS_CHECK
2217     uint8_t             *p_recv_buf = psNdefMap->SendRecvBuf;
2218 #endif /* #ifdef ENABLE_LOCK_BITS_CHECK */
2219     psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
2220
2221 #ifdef ENABLE_LOCK_BITS_CHECK
2222
2223     /* Set the card state */
2224     psNdefMap->CardState =  (uint8_t)
2225         (((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_0] == 
2226             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_0) && 
2227             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_1] == 
2228             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_1)) &&
2229             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_2] == 
2230             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2231             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_3] == 
2232             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2233             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_4] == 
2234             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2235             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_5] == 
2236             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) &&
2237             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_6] == 
2238             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7))) &&
2239             ((p_recv_buf[PH_FRINFC_TOPAZ_DYNAMIC_LOCKBIT_BYTENO_7] == 
2240             PH_FRINFC_TOPAZ_DYNAMIC_LOCKBYTE_2TO7)) ?
2241                 PH_NDEFMAP_CARD_STATE_INITIALIZED :
2242                 PH_NDEFMAP_CARD_STATE_READ_ONLY);
2243
2244 #endif /* #ifdef ENABLE_LOCK_BITS_CHECK */
2245
2246     /* Set the card state from CC bytes */
2247     if (PH_NDEFMAP_CARD_STATE_INITIALIZED == psNdefMap->CardState)
2248     {
2249         switch ((psNdefMap->TopazContainer.CCByteBuf[3] & 0xFF))
2250         {
2251             case PH_FRINFC_TOPAZ_CC_READWRITE:
2252             {
2253                 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
2254                 break;
2255             }
2256
2257             case PH_FRINFC_TOPAZ_CC_READONLY:
2258             {
2259                 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
2260                 break;
2261             }
2262
2263             default: 
2264             {
2265                 psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2266                 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2267                                     NFCSTATUS_NO_NDEF_SUPPORT);
2268                 break;
2269             }
2270         }
2271     }
2272     
2273     return result;
2274 }
2275
2276 static 
2277 NFCSTATUS 
2278 phFriNfc_Tpz_H_CheckCCBytes (
2279     phFriNfc_NdefMap_t          *psNdefMap)
2280 {
2281     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
2282     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
2283     uint8_t                         *p_recv_buf = psNdefMap->SendRecvBuf;
2284     uint16_t                        parse_index = 0;
2285
2286     parse_index = (uint16_t)(parse_index + TOPAZ_UID_BYTES_LENGTH);
2287
2288     (void)memcpy ((void *)ps_tpz_info->CCByteBuf, 
2289                 (void *)(p_recv_buf + parse_index), 
2290                 TOPAZ_CC_BYTES_LENGTH);
2291
2292     p_recv_buf = ps_tpz_info->CCByteBuf;
2293     parse_index = 0;
2294
2295 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2296     /* 1st CC byte value = 0 or 0xE1 */
2297     if ((PH_FRINFC_TOPAZ_CC_BYTE0 == p_recv_buf[parse_index])
2298 #ifdef TOPAZ_MAGIC_NO_0_CHK_ENABLE
2299         || (0 == p_recv_buf[parse_index])
2300 #endif /* #if TOPAZ_MAGIC_NO_0_CHK_ENABLE */
2301         )
2302 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2303     {
2304         parse_index = (uint16_t)(parse_index + 1);
2305         /* 2nd CC byte value = 0x10 */
2306         result = phFriNfc_Tpz_H_ChkSpcVer (psNdefMap, p_recv_buf[parse_index]);        
2307     }
2308 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2309     else
2310     {
2311         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2312                             NFCSTATUS_NO_NDEF_SUPPORT);
2313     }
2314 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2315
2316     if (NFCSTATUS_SUCCESS == result)
2317     {
2318         parse_index = (uint16_t)(parse_index + 1);
2319         /* 3rd CC byte value = 0x3F for 512 card */
2320         if (PH_FRINFC_TOPAZ_DYNAMIC_CC_BYTE2_MMSIZE == p_recv_buf[parse_index])
2321         {
2322             /* Card size calculated as ((3rd CC byte * 8) - 4 CC bytes) */
2323             psNdefMap->CardMemSize = (uint16_t)((p_recv_buf[parse_index] * 
2324                                     TOPAZ_BYTES_PER_BLOCK) - 
2325                                     TOPAZ_CC_BYTES_LENGTH);
2326             ps_tpz_info->RemainingSize = (uint16_t)(psNdefMap->CardMemSize + 
2327                                         TOPAZ_UID_BYTES_LENGTH + 
2328                                         TOPAZ_CC_BYTES_LENGTH);
2329             result = phFriNfc_Tpz_H_ChkLockBits (psNdefMap);
2330         }
2331         else
2332         {
2333             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2334                                 NFCSTATUS_NO_NDEF_SUPPORT);
2335         }
2336     }
2337
2338     if (NFCSTATUS_SUCCESS != result)
2339     {
2340         psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2341     }
2342
2343     return result;
2344 }
2345
2346 static 
2347 NFCSTATUS 
2348 phFriNfc_Tpz_H_CheckCCBytesForWrite (
2349     phFriNfc_NdefMap_t          *psNdefMap)
2350 {
2351     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
2352     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
2353     uint8_t                             check_cc_rw[] = {TOPAZ_SPEC_VERSION, 
2354                                         PH_FRINFC_TOPAZ_DYNAMIC_CC_BYTE2_MMSIZE, 
2355                                         PH_FRINFC_TOPAZ_CC_READWRITE};
2356     uint8_t                             check_index = 0;
2357
2358     ps_tpz_info = &(psNdefMap->TopazContainer);
2359
2360 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2361     if (
2362         (PH_FRINFC_TOPAZ_CC_BYTE0 == ps_tpz_info->CCByteBuf[check_index]) 
2363 #if TOPAZ_MAGIC_NO_0_CHK_ENABLE
2364         || (0 == ps_tpz_info->CCByteBuf[check_index])
2365 #endif /* #if TOPAZ_MAGIC_NO_0_CHK_ENABLE */
2366         )
2367 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2368     {
2369         check_index = (uint8_t)(check_index + 1);
2370
2371         if ((check_cc_rw[0] != ps_tpz_info->CCByteBuf[1]) || 
2372             (check_cc_rw[1] != ps_tpz_info->CCByteBuf[2]) || 
2373             (check_cc_rw[2] != ps_tpz_info->CCByteBuf[3]))
2374         {
2375             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2376                                 NFCSTATUS_NO_NDEF_SUPPORT);
2377         }
2378     }
2379 #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE
2380     else
2381     {
2382         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2383                             NFCSTATUS_NO_NDEF_SUPPORT);
2384     }    
2385 #endif /* #ifdef TOPAZ_MAGIC_NO_CHK_ENABLE */
2386     return result;
2387 }
2388
2389 static 
2390 uint16_t 
2391 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
2392     phFriNfc_NdefMap_t          *psNdefMap)
2393 {
2394     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
2395     uint16_t                        skip_size = 0;
2396     uint16_t                        byte_addr = 0;
2397     uint8_t                         exit_index = 0;
2398
2399     byte_addr = ps_tpz_info->NdefTLVByteAddress;
2400
2401     while (exit_index < ((ps_tpz_info->ActualNDEFMsgSize >= 0xFF) ? 3 : 1))
2402     {
2403         byte_addr = (uint16_t)(byte_addr + 1);
2404         if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2405         {
2406             byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2407         }
2408         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2409         
2410         byte_addr = (uint16_t)(byte_addr + skip_size);
2411         exit_index = (uint8_t)(exit_index + 1);
2412     }
2413
2414     byte_addr = (uint16_t)(byte_addr + 1);
2415     if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2416     {
2417         byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2418     }
2419     skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2420     
2421     byte_addr = (uint16_t)(byte_addr + skip_size);
2422
2423     return byte_addr;
2424 }
2425
2426 static 
2427 uint16_t 
2428 phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (
2429     phFriNfc_NdefMap_t          *psNdefMap, 
2430     uint16_t                    size_to_write)
2431 {
2432     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
2433     uint16_t                        skip_size = 0;
2434     uint16_t                        byte_addr = 0;
2435     uint8_t                         exit_index = 0;
2436
2437     byte_addr = ps_tpz_info->NdefTLVByteAddress;
2438
2439     while (exit_index < ((size_to_write >= 0xFF) ? 3 : 1))
2440     {
2441         byte_addr = (uint16_t)(byte_addr + 1);
2442         if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2443         {
2444             byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2445         }
2446         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2447         
2448         byte_addr = (uint16_t)(byte_addr + skip_size);
2449         exit_index = (uint8_t)(exit_index + 1);
2450     }
2451
2452     byte_addr = (uint16_t)(byte_addr + 1);
2453     if (TOPAZ_STATIC_LOCK_RES_START == byte_addr)
2454     {
2455         byte_addr = (uint16_t)(byte_addr + TOPAZ_STATIC_LOCK_RES_BYTES);
2456     }
2457     skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2458     
2459     byte_addr = (uint16_t)(byte_addr + skip_size);
2460
2461     return byte_addr;
2462 }
2463
2464
2465 static 
2466 NFCSTATUS 
2467 phFriNfc_Tpz_H_RemainingReadDataCopy (
2468     phFriNfc_NdefMap_t          *psNdefMap)
2469 {
2470     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
2471     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
2472     uint8_t                         copy_temp_buf[PH_FRINFC_NDEFMAP_TOPAZ_MAX_SIZE];
2473     uint16_t                        copy_length = 0;
2474     uint16_t                        read_copy_length = 0;
2475
2476
2477     if (0 != ps_tpz_info->ReadBufferSize)
2478     {
2479         /* Data is already copied, so give it from the stored buffer */
2480         if ((psNdefMap->ApduBufferSize - psNdefMap->ApduBuffIndex) >= 
2481             ps_tpz_info->ReadBufferSize)
2482         {
2483             read_copy_length = ps_tpz_info->ReadBufferSize;
2484             (void)memcpy ((void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex), 
2485                     (void *)ps_tpz_info->ReadBuffer, ps_tpz_info->ReadBufferSize);
2486         }
2487         else
2488         {
2489             read_copy_length = (uint16_t)(psNdefMap->ApduBufferSize - 
2490                                 psNdefMap->ApduBuffIndex);
2491
2492             copy_length = (uint16_t)(ps_tpz_info->ReadBufferSize - 
2493                             read_copy_length);
2494
2495             /* Copy data to user buffer */
2496             (void)memcpy ((void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex), 
2497                     (void *)ps_tpz_info->ReadBuffer, read_copy_length);
2498
2499             /* Copy data from " ReadBuffer " to temporary buffer */
2500             (void)memcpy ((void *)copy_temp_buf, 
2501                     (void *)(ps_tpz_info->ReadBuffer + read_copy_length), 
2502                     copy_length);
2503
2504             /* Copy data from temporary buffer to " ReadBuffer " */
2505             (void)memcpy ((void *)ps_tpz_info->ReadBuffer, 
2506                     (void *)copy_temp_buf, copy_length);
2507
2508         }
2509
2510         psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + 
2511                                     read_copy_length);
2512         ps_tpz_info->ReadBufferSize = (uint8_t)
2513                             (ps_tpz_info->ReadBufferSize - 
2514                             read_copy_length);
2515         ps_tpz_info->RemainingReadSize = (uint16_t)(
2516                             ps_tpz_info->RemainingReadSize - read_copy_length);
2517     }
2518
2519     if (0 == ps_tpz_info->RemainingReadSize)
2520     {
2521         /* No data to read, so return */
2522         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
2523         ps_tpz_info->ReadBufferSize = 0;
2524         ps_tpz_info->ReadWriteCompleteFlag = TRUE;
2525     }
2526     else if (psNdefMap->ApduBuffIndex == psNdefMap->ApduBufferSize)
2527     {
2528         /* User data length is read completely */
2529         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
2530     }
2531     else
2532     {
2533         /* Stored data is not enough, so continue reading the next segment */
2534         ps_tpz_info->CurrentSeg = (uint8_t)
2535                             (ps_tpz_info->CurrentSeg + 1);
2536 #ifdef TOPAZ_RAW_SUPPORT
2537
2538         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
2539
2540 #else 
2541
2542         psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
2543
2544 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2545         result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
2546     }
2547
2548     return result;
2549 }
2550
2551 static 
2552 NFCSTATUS 
2553 phFriNfc_Tpz_H_CopyReadData (
2554     phFriNfc_NdefMap_t          *psNdefMap)
2555 {
2556     NFCSTATUS                       result = NFCSTATUS_SUCCESS;    
2557     phFriNfc_TopazCont_t            *ps_tpz_info = &(psNdefMap->TopazContainer);
2558     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
2559     phFriNfc_ResMemCntrlTLVCont_t   *ps_memtlv_info = NULL;
2560     uint16_t                        copy_index = 0;
2561     uint16_t                        copy_length = 0;
2562     uint16_t                        recv_length = 0;
2563     static uint16_t                 skip_size = 0;
2564     /* byte address read */
2565     uint16_t                        copy_till_address = 0;
2566     uint16_t                        exact_copy_length = 0;
2567     uint16_t                        actual_ndef_length = 0;
2568     
2569
2570     recv_length = *(psNdefMap->SendRecvLength);
2571     
2572     actual_ndef_length = ps_tpz_info->ActualNDEFMsgSize;
2573     if (PH_FRINFC_NDEFMAP_SEEK_CUR == psNdefMap->Offset)
2574     {
2575         actual_ndef_length = (uint16_t)(
2576                             ps_tpz_info->RemainingReadSize + 
2577                             psNdefMap->ApduBuffIndex);
2578     }
2579     
2580     exact_copy_length = (uint16_t)((psNdefMap->ApduBufferSize > 
2581                             actual_ndef_length) ? actual_ndef_length : 
2582                             psNdefMap->ApduBufferSize);
2583
2584     if (0 == ps_tpz_info->CurrentSeg)
2585     {
2586         /* Skip copying the UID bytes, CC bytes, and lock and reserved memory bytes 
2587              */
2588         recv_length = (*(psNdefMap->SendRecvLength) - TOPAZ_STATIC_LOCK_RES_BYTES);
2589     }
2590
2591     if (TOPAZ_SEG_FROM_BYTE_ADR (
2592         phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (psNdefMap)) == 
2593         ps_tpz_info->CurrentSeg)
2594     {
2595         copy_index = (uint16_t)(copy_index + (
2596                     phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead (
2597                         psNdefMap) % TOPAZ_SEGMENT_READ_LENGTH));
2598         skip_size = 0;
2599     }
2600
2601     if (0 != skip_size)
2602     {
2603         copy_index = (copy_index + skip_size);
2604         skip_size = 0;
2605     }
2606     
2607     while (copy_index < recv_length)
2608     {
2609         copy_length = (uint16_t)(recv_length - copy_index);
2610         copy_till_address = 0;
2611         /* IF MORE THAN ONE TLV EXISTS THEN ADD A WHILE LOOP HERE, AND PLACE THE 
2612             IF STATEMENT INSIDE THE WHILE LOOP. ALSO,
2613             ps_locktlv_info = &(psNdefMap->LockTlv) change this to 
2614             ps_locktlv_info = &(psNdefMap->LockTlv[index])
2615             */
2616         ps_locktlv_info = &(psNdefMap->LockTlv);
2617         if (
2618             /* Check the lock bytes belong to this segment */
2619             (ps_tpz_info->CurrentSeg == 
2620             (ps_locktlv_info->ByteAddr / TOPAZ_SEGMENT_READ_LENGTH)) && 
2621             /* Now to check if the copy_index has surpassed the lock byte address */
2622             (TOPAZ_BYTE_ADR_FROM_SEG(ps_tpz_info->CurrentSeg, copy_index) 
2623             <= ps_locktlv_info->ByteAddr)
2624             )
2625         {
2626             if ((ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_START) || 
2627                 (ps_locktlv_info->ByteAddr >= (TOPAZ_STATIC_LOCK_RES_END + 8)))
2628             {
2629                 copy_till_address = ps_locktlv_info->ByteAddr;
2630             }
2631             skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, 
2632                                                         ps_locktlv_info->ByteAddr);
2633         }
2634
2635         /* IF MORE THAN ONE TLV EXISTS THEN ADD A WHILE LOOP HERE, AND PLACE THE 
2636             IF STATEMENT INSIDE THE WHILE LOOP. ALSO,
2637             ps_memtlv_info = &(psNdefMap->MemTlv) change this to 
2638             ps_memtlv_info = &(psNdefMap->MemTlv[index])
2639             */
2640         ps_memtlv_info = &(psNdefMap->MemTlv);
2641         if (
2642             /* Check the reserved bytes belong to this segment */
2643             (ps_tpz_info->CurrentSeg == 
2644             (ps_memtlv_info->ByteAddr / TOPAZ_SEGMENT_READ_LENGTH)) && 
2645             /* Now to check if the copy_index has surpassed the reserved byte address */
2646             (TOPAZ_BYTE_ADR_FROM_SEG(ps_tpz_info->CurrentSeg, copy_index) 
2647             <= ps_memtlv_info->ByteAddr)
2648             )
2649         {
2650             if ((ps_memtlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_START) ||  
2651                 (ps_memtlv_info->ByteAddr >= (TOPAZ_STATIC_LOCK_RES_END + 8)))
2652             {
2653                 copy_till_address = (uint16_t)
2654                             (((ps_memtlv_info->ByteAddr < copy_till_address) || 
2655                                 (0 == copy_till_address))?  
2656                             ps_memtlv_info->ByteAddr : copy_till_address);
2657             }
2658
2659             if (copy_till_address == ps_memtlv_info->ByteAddr)
2660             {
2661                 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, 
2662                                                             ps_memtlv_info->ByteAddr);
2663             }
2664         }
2665
2666
2667         copy_length = (uint16_t) ((copy_till_address == 0) ? copy_length : 
2668                     ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) - 
2669                     copy_index));
2670
2671         /* After lock bytes, there are immediate reserved bytes, so " copy_length " 
2672             can be 0 */
2673         if (0 != copy_length)
2674         {
2675             /* If complete user buffer is not filled and the 
2676                 read data is greater than the user data buffer, then get the 
2677                 remaining size that should be copied. 
2678                 The below " if " statement is used for the above scenario */
2679             if ((copy_length > (uint16_t)
2680                 (exact_copy_length - psNdefMap->ApduBuffIndex)) && 
2681                 (exact_copy_length != psNdefMap->ApduBuffIndex))
2682             {            
2683                 copy_length = (uint16_t)(exact_copy_length - 
2684                                         psNdefMap->ApduBuffIndex);
2685             }
2686
2687             if (exact_copy_length != psNdefMap->ApduBuffIndex)
2688             {
2689                 (void)memcpy ((void *)(psNdefMap->ApduBuffer + 
2690                         psNdefMap->ApduBuffIndex), 
2691                         (void *)(psNdefMap->SendRecvBuf + copy_index), 
2692                         copy_length);
2693 #if 0
2694                 if (((copy_till_address == 0) ? copy_length : 
2695                     ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) - 
2696                     copy_index)) > (uint16_t)
2697                     (exact_copy_length - psNdefMap->ApduBuffIndex))
2698                 {                
2699                     /* Copy remaining buffer in the static memory */
2700                     (void)memcpy ((void *)(ps_tpz_info->ReadBuffer + 
2701                             ps_tpz_info->ReadBufferSize), 
2702                             (void *)(psNdefMap->SendRecvBuf + copy_index), 
2703                             (((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) - 
2704                             copy_index) - copy_length));
2705
2706                     ps_tpz_info->ReadBufferSize = (uint16_t)(((copy_till_address % 
2707                                                     TOPAZ_SEGMENT_READ_LENGTH) - 
2708                                                     copy_index) - copy_length);
2709
2710                     /* Copy the data in the user buffer */
2711                     copy_index = (uint16_t)(copy_index + 
2712                                 ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) - 
2713                                 copy_index));
2714                 }
2715                 else
2716 #endif /* #if 0 */
2717                 {
2718                     /* Copy the data in the user buffer */
2719                     copy_index = (uint16_t)(copy_index + copy_length);
2720                 }
2721
2722                 psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + 
2723                                             copy_length);
2724
2725
2726             }
2727             else
2728             {
2729                 copy_length = (uint16_t) ((copy_till_address == 0) ? copy_length : 
2730                             ((copy_till_address % TOPAZ_SEGMENT_READ_LENGTH) - 
2731                             copy_index));
2732
2733                 /* Actual NDEF message size is greater than the last index copied in 
2734                     the user buffer */
2735                 if (actual_ndef_length > (psNdefMap->ApduBuffIndex + 
2736                     ps_tpz_info->ReadBufferSize))
2737                 {
2738                     /* The statement is correct, check the remaining length */
2739                     copy_length = ((copy_length > (actual_ndef_length - 
2740                                 psNdefMap->ApduBuffIndex)) ? 
2741                                 (actual_ndef_length - 
2742                                 psNdefMap->ApduBuffIndex) : 
2743                                 copy_length);
2744
2745                     /* Copy remaining buffer in the static memory */
2746                     (void)memcpy ((void *)(ps_tpz_info->ReadBuffer + 
2747                                 ps_tpz_info->ReadBufferSize), 
2748                                 (void *)(psNdefMap->SendRecvBuf + copy_index), 
2749                                 copy_length);
2750
2751                     ps_tpz_info->ReadBufferSize = (uint8_t)(
2752                                                     ps_tpz_info->ReadBufferSize + 
2753                                                     copy_length);
2754                 }
2755
2756                 /* Copy the data in the user buffer */
2757                 copy_index = (uint16_t)(copy_index + copy_length); 
2758             }
2759         }
2760
2761         if (copy_index != copy_till_address)
2762         {
2763             skip_size = 0;
2764         }
2765
2766         if ((copy_index + skip_size) <= recv_length)
2767         {
2768             copy_index = (uint16_t)(copy_index + skip_size);
2769             skip_size = 0;
2770         }
2771         else
2772         {
2773             skip_size = (uint16_t)((skip_size > 0) ? 
2774                                     (recv_length - copy_index) : 0);
2775             copy_index = (uint16_t)recv_length;
2776         }                        
2777     }
2778
2779     if (exact_copy_length != psNdefMap->ApduBuffIndex)
2780     {
2781         ps_tpz_info->CurrentSeg = (uint8_t)
2782                             (ps_tpz_info->CurrentSeg + 1);
2783 #ifdef TOPAZ_RAW_SUPPORT
2784
2785         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
2786
2787 #else 
2788
2789         psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
2790
2791 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
2792         result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
2793     }
2794     else
2795     {
2796         *psNdefMap->NumOfBytesRead = psNdefMap->ApduBuffIndex;
2797         if (psNdefMap->ApduBuffIndex == actual_ndef_length)
2798         {
2799             ps_tpz_info->ReadBufferSize = 0;
2800             ps_tpz_info->ReadWriteCompleteFlag = TRUE;
2801         }
2802         else
2803         {
2804             ps_tpz_info->RemainingReadSize = (actual_ndef_length - 
2805                                         psNdefMap->ApduBuffIndex);
2806         }
2807     }
2808     return result;
2809 }
2810
2811
2812 static 
2813 NFCSTATUS 
2814 phFriNfc_Tpz_H_ParseTLVs (
2815     phFriNfc_NdefMap_t          *psNdefMap)
2816 {
2817     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
2818     phFriNfc_TopazCont_t        *ps_tpz_info = &(psNdefMap->TopazContainer);
2819     uint8_t                     *p_recv_buf = NULL;
2820     uint16_t                    recv_length = 0;
2821     uint16_t                    parse_index = 0;
2822     phFriNfc_Tpz_ParseSeq_t     expected_seq = (phFriNfc_Tpz_ParseSeq_t)
2823                                 ps_tpz_info->ExpectedSeq;
2824     uint16_t                    byte_addr = 0;
2825     /* This variable is kept static because if the size to skip LOCK or RESERVED 
2826     bytes extends to next read then it shall be stored and used to skip the next 
2827     read the bytes
2828     */
2829     static uint16_t             skip_size = 0;
2830     /* This variable is kept static because if the bytes extends from the read segment, 
2831         then the index shall be stored
2832     This is to store index copied from the 
2833     1. lock memory VALUE field bytes in the LOCK and MEMORY CONTROL TLV. 
2834     2. Also, LENGTH field of the NDEF TLV */
2835     static uint8_t              lock_mem_ndef_index = 0;
2836     /* This variable is kept static because if the bytes extends from the read segment, 
2837         then it has to stored
2838     This is to store the 
2839     1. lock memory VALUE field bytes in the LOCK and MEMORY CONTROL TLV. 
2840     2. Also, LENGTH field of the NDEF TLV */
2841     static uint8_t              lock_mem_buf[TOPAZ_MEM_LOCK_TLV_LENGTH] = {0};
2842     /* This is used in case if there is no MAGIC NUMBER found 
2843                         OR 
2844         TYPE field is not found after reading entire card */
2845     static uint16_t             ndef_tlv_byte_addr = 0;
2846
2847     p_recv_buf = psNdefMap->SendRecvBuf;
2848     recv_length = *psNdefMap->SendRecvLength;
2849
2850     if (0 == ps_tpz_info->CurrentSeg)
2851     {
2852         /* First read, so reset all the static variables */
2853         lock_mem_ndef_index = 0;
2854         skip_size = 0;
2855         ndef_tlv_byte_addr = 0;
2856
2857         /* Skip copying the UID bytes and CC bytes, which is first 12 bytes */
2858         parse_index = (uint16_t)(TOPAZ_UID_BYTES_LENGTH + 
2859                                 TOPAZ_CC_BYTES_LENGTH);
2860         /* Delete the lock and reserved memory bytes 
2861             (which are the last 24 bytes in the card) */
2862         recv_length = (uint16_t)(*(psNdefMap->SendRecvLength) - 
2863                                 TOPAZ_STATIC_LOCK_RES_BYTES);        
2864     }
2865
2866     while ((parse_index < recv_length) && (NFCSTATUS_SUCCESS == result) && 
2867         (NDEF_V_TLV != expected_seq))
2868     {
2869         if (0 == skip_size)
2870         {
2871             /* Macro used to get the exact byte address of the card. 
2872                 This is done by using the current segment and the parse index */
2873             byte_addr = TOPAZ_BYTE_ADR_FROM_SEG (ps_tpz_info->CurrentSeg, parse_index);
2874             /* Skip size is to skip the lock or memory reserved bytes  */
2875             skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
2876         }
2877
2878         if (0 != skip_size)
2879         {
2880             if ((recv_length - parse_index) >= skip_size)
2881             {
2882                 parse_index = (uint16_t)(parse_index + skip_size);
2883                 skip_size = 0;
2884             }
2885             else
2886             {
2887                 parse_index = (uint16_t)(parse_index + (recv_length - 
2888                                 parse_index));
2889                 skip_size = (uint16_t)(skip_size - (recv_length - 
2890                                 parse_index));
2891             }
2892         }
2893         else 
2894         {
2895             switch (expected_seq)
2896             {
2897                 case LOCK_T_TLV:
2898                 {
2899                     /* Parse the bytes till TYPE field of LOCK TLV is found, Once the 
2900                         TYPE field is found then change the sequence to LOCK_L_TLV */
2901                     result = phFriNfc_Tpz_H_ParseLockTLVType (psNdefMap, p_recv_buf, 
2902                                             &parse_index, recv_length, &expected_seq);
2903                     
2904                     break;
2905                 }
2906
2907                 case LOCK_L_TLV:
2908                 {
2909                     /* Parse the length field of LOCK TLV. Length field value of the 
2910                         LOCK TLV is always 3 */
2911                     if (TOPAZ_MEM_LOCK_TLV_LENGTH != p_recv_buf[parse_index])
2912                     {
2913                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2914                                             NFCSTATUS_NO_NDEF_SUPPORT);
2915                     }
2916                     else
2917                     {
2918                         parse_index = (uint16_t)(parse_index + 1);
2919                         expected_seq = LOCK_V_TLV;
2920                     }
2921                     break;
2922                 }
2923
2924                 case LOCK_V_TLV:
2925                 {
2926                     /* Parse the VALUE field of the LOCK TLV */
2927                     lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
2928                     parse_index = (uint16_t)(parse_index + 1);
2929                     lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
2930                     
2931
2932                     /* All the 3 bytes are copied in the local buffer */
2933                     if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
2934                     {
2935 #ifdef FRINFC_READONLY_NDEF
2936                         (void)memcpy ((void *)psNdefMap->LockTlv.LockTlvBuff, 
2937                                 (void *)lock_mem_buf, sizeof (lock_mem_buf));
2938 #endif /* #ifdef FRINFC_READONLY_NDEF */
2939                         /* Calculate the byte address and size of the lock bytes */
2940                         result = phFriNfc_Tpz_H_GetLockBytesInfo (psNdefMap, lock_mem_buf);
2941                         lock_mem_ndef_index = 0;
2942                         expected_seq = MEM_T_TLV;                    
2943                     }
2944                     break;
2945                 }
2946
2947                 case MEM_T_TLV:
2948                 {
2949                     /* Parse the bytes till TYPE field of MEMORY TLV is found, Once the 
2950                         TYPE field is found then change the sequence to MEM_L_TLV */
2951                     result = phFriNfc_Tpz_H_ParseMemTLVType (psNdefMap, p_recv_buf, 
2952                                             &parse_index, recv_length, &expected_seq);                    
2953                     break;
2954                 }
2955
2956                 case MEM_L_TLV:
2957                 {
2958                     /* Parse the length field of MEMORY TLV. Length field value of the 
2959                         MEMORY TLV is always 3 */
2960                     if (TOPAZ_MEM_LOCK_TLV_LENGTH != p_recv_buf[parse_index])
2961                     {
2962                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2963                                             NFCSTATUS_NO_NDEF_SUPPORT);
2964                     }
2965                     else
2966                     {
2967                         parse_index = (uint16_t)(parse_index + 1);
2968                         expected_seq = MEM_V_TLV;
2969                     }
2970
2971                     break;
2972                 }
2973
2974                 case MEM_V_TLV:
2975                 {
2976                     /* Parse the VALUE field of the MEMORY TLV */
2977                     lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
2978                     parse_index = (uint16_t)(parse_index + 1);
2979                     lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
2980
2981                     /* All the 3 bytes are copied in the local buffer */
2982                     if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
2983                     {
2984                         /* Calculate the byte address and size of the lock bytes */
2985                         ndef_tlv_byte_addr = TOPAZ_BYTE_ADR_FROM_SEG (
2986                                             ps_tpz_info->CurrentSeg , parse_index);
2987                         result = phFriNfc_Tpz_H_GetMemBytesInfo (psNdefMap, lock_mem_buf);
2988                         lock_mem_ndef_index = 0;
2989                         expected_seq = NDEF_T_TLV;
2990                     }
2991
2992                     break;
2993                 }
2994
2995                 case NDEF_T_TLV:
2996                 {
2997                     /* Parse the bytes till TYPE field of NDEF TLV is found, Once the 
2998                         TYPE field is found then change the sequence to NDEF_L_TLV */
2999                     result = phFriNfc_Tpz_H_ParseNdefTLVType (psNdefMap, p_recv_buf, 
3000                                             &parse_index, recv_length, &expected_seq);
3001                     
3002                     break;
3003                 }
3004
3005                 case NDEF_L_TLV:
3006                 {
3007                     /* Length field of the NDEF TLV */
3008                     if (0 == lock_mem_ndef_index)
3009                     {
3010                         /* This is the 1st time, the loop has entered this case, 
3011                             means that the NDEF byte address has to be updated */
3012                         ps_tpz_info->NdefTLVByteAddress = (uint16_t)
3013                                 TOPAZ_BYTE_ADR_FROM_SEG (ps_tpz_info->CurrentSeg, 
3014                                 (parse_index - 1));
3015                     }
3016
3017                     if (0 != lock_mem_ndef_index)
3018                     {
3019                         /* There is already index has been updated, update remaining 
3020                             buffer */
3021                         lock_mem_buf[lock_mem_ndef_index] = p_recv_buf[parse_index];
3022                         parse_index = (uint16_t)(parse_index + 1);
3023                         lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
3024
3025                         if (TOPAZ_MEM_LOCK_TLV_LENGTH == lock_mem_ndef_index)
3026                         {
3027                             lock_mem_ndef_index = 0;
3028                             ps_tpz_info->ActualNDEFMsgSize = (uint16_t)((lock_mem_buf[1] << 
3029                                         TOPAZ_BYTE_SHIFT) | lock_mem_buf[2]);
3030                             expected_seq = NDEF_V_TLV;
3031                         }
3032                     }
3033                     /* Check for remaining size in the card and the actual ndef length */
3034                     else if (p_recv_buf[parse_index] <= 
3035                             (ps_tpz_info->RemainingSize - (parse_index + 1)))
3036                     {
3037                         /* This check is added to see that length field in the TLV is 
3038                             greater than the 1 byte */
3039                         if (0xFF == p_recv_buf[parse_index])
3040                         {
3041                             lock_mem_buf[lock_mem_ndef_index] = 
3042                                                     p_recv_buf[parse_index];
3043                             lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1);
3044                         }
3045                         else
3046                         {
3047                             /* Length field of the TLV is ONE byte, so update the 
3048                             actual ndef size */
3049                             lock_mem_ndef_index = 0;
3050                             ps_tpz_info->ActualNDEFMsgSize = (uint16_t)
3051                                                         p_recv_buf[parse_index];
3052                             
3053                             expected_seq = NDEF_V_TLV;
3054                         }
3055                         parse_index = (uint16_t)(parse_index + 1);
3056                     }
3057                     else
3058                     {
3059                         /* Wrong length, remaining size in the card is lesser than the actual 
3060                             ndef message length */
3061                         lock_mem_ndef_index = 0;
3062                         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3063                                             NFCSTATUS_NO_NDEF_SUPPORT);
3064                     }
3065                     break;
3066                 }
3067
3068                 default:
3069                 {
3070                     break;
3071                 }
3072             }/* end of switch (expected_seq) */
3073         } /* end of if (0 != skip_size) */
3074     } /* while ((parse_index < recv_length) && (NFCSTATUS_SUCCESS != result) && 
3075         (NDEF_V_TLV != expected_seq)) */
3076
3077     ps_tpz_info->ExpectedSeq = (uint8_t)expected_seq;
3078
3079     if (0 == ps_tpz_info->CurrentSeg)
3080     {
3081         /* First segment has the STATIC lock and reserved bytes, so delete it from 
3082             the remaining size */
3083         ps_tpz_info->RemainingSize = (uint16_t)(ps_tpz_info->RemainingSize - 
3084                                     (parse_index + TOPAZ_STATIC_LOCK_RES_BYTES));
3085
3086     }
3087     else
3088     {
3089         ps_tpz_info->RemainingSize = (uint16_t)(ps_tpz_info->RemainingSize - 
3090                                     parse_index);
3091     }
3092
3093     if ((NDEF_V_TLV == expected_seq) && (NFCSTATUS_SUCCESS == result))
3094     {
3095         /* NDEF TLV found */
3096         result = phFriNfc_Tpz_H_ActualCardSize (psNdefMap);
3097
3098         if ((PH_NDEFMAP_CARD_STATE_READ_ONLY != psNdefMap->CardState) && 
3099             (0 != ps_tpz_info->ActualNDEFMsgSize))
3100         {
3101             /* Check if the card state is READ ONLY or the actual NDEF size is 0 
3102                 if actual NDEF size is 0, then card state is INITIALISED
3103             */
3104             psNdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
3105         }
3106     }
3107
3108     if ((NFCSTATUS_SUCCESS == result) && (NDEF_V_TLV != expected_seq))
3109     {
3110         ps_tpz_info->CurrentSeg = (uint8_t)(ps_tpz_info->CurrentSeg + 1);
3111         if (TOPAZ_TOTAL_SEG_TO_READ == ps_tpz_info->CurrentSeg)
3112         {
3113             /* Max segment to read reached, so no more read can be done */
3114             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3115                                 NFCSTATUS_NO_NDEF_SUPPORT);
3116         }
3117         else
3118         {
3119 #ifdef TOPAZ_RAW_SUPPORT
3120
3121             *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_RSEG;
3122
3123 #else 
3124
3125             psNdefMap->Cmd.JewelCmd = phHal_eJewel_ReadSeg;
3126
3127 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 
3128             result = phFriNfc_Tpz_H_NxpRead(psNdefMap);
3129         }
3130     }
3131
3132     if ((NFCSTATUS_SUCCESS != result) && (NFCSTATUS_PENDING != result))
3133     {
3134         /* Error scenario */
3135         ps_tpz_info->NdefTLVByteAddress = 0;
3136         ps_tpz_info->ActualNDEFMsgSize = 0;
3137     }
3138     
3139     if (NFCSTATUS_PENDING != result)
3140     {
3141         /* Exit scenario */
3142         if ((0x00 == *ps_tpz_info->CCByteBuf) || 
3143             ((NDEF_T_TLV == expected_seq) && 
3144             (TOPAZ_TOTAL_SEG_TO_READ == ps_tpz_info->CurrentSeg)))
3145         {
3146             /* This statement is for getting the new 
3147                 NDEF TLV byte address, because 1st CC byte is corrupted or 
3148                 no NDEF TLV in the card
3149
3150                 If the 1st CC byte (NDEF magic number) in the card is 0, means 
3151                 that previous write has failed, so to write the exact TLV, 
3152                 calculate the byte number
3153                                             OR
3154                 The NDEF TLV is not present in the entire card, and the sequence is 
3155                 NDEF_T_TLV (this means, that lock and memory control TLV is found 
3156                 in the card)                
3157                 */
3158             uint16_t             size_to_skip = 0;
3159             ps_tpz_info->ActualNDEFMsgSize = 0;
3160             
3161             if (0 != ndef_tlv_byte_addr)
3162             {
3163                 /* ndef_tlv_byte_addr is updated, only after complete parsing the 
3164                     memory control TLV so the value shall not be 0 */
3165                 do 
3166                 {
3167                     /* This loop is added to make sure the lock and reserved bytes are not 
3168                     overwritten */
3169                     size_to_skip = 0;
3170                     size_to_skip = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, 
3171                                                             ndef_tlv_byte_addr);
3172
3173                     ndef_tlv_byte_addr = (uint16_t)(ndef_tlv_byte_addr + 
3174                                             size_to_skip);
3175                 }while (0 != size_to_skip);
3176
3177                 /* Update the TLV byte address */
3178                 ps_tpz_info->NdefTLVByteAddress = ndef_tlv_byte_addr;
3179
3180                 /* Update the remaining size */
3181                 ps_tpz_info->RemainingSize = (uint16_t)(psNdefMap->CardMemSize + 
3182                                         TOPAZ_UID_BYTES_LENGTH + 
3183                                         TOPAZ_CC_BYTES_LENGTH);
3184
3185                 ps_tpz_info->RemainingSize = (uint16_t)
3186                                             (ps_tpz_info->RemainingSize - 
3187                                             (ndef_tlv_byte_addr + 
3188                                             TOPAZ_STATIC_LOCK_RES_BYTES));
3189                 (void)phFriNfc_Tpz_H_ActualCardSize (psNdefMap);
3190
3191                 /* Length byte is subtracted here to get the actual NDEF 
3192                     read and write size */
3193                 ps_tpz_info->NDEFRWSize = (uint16_t)
3194                                         (ps_tpz_info->NDEFRWSize - 2);
3195                 ndef_tlv_byte_addr = 0;
3196                 result = NFCSTATUS_SUCCESS;
3197             }
3198         }
3199     }
3200
3201     return result;
3202 }
3203
3204 static 
3205 NFCSTATUS 
3206 phFriNfc_Tpz_H_CopyReadDataAndWrite (
3207     phFriNfc_NdefMap_t          *psNdefMap)
3208 {
3209     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
3210     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
3211     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3212     uint16_t                            write_index = 0;
3213     uint16_t                            write_len = 0;
3214     uint16_t                            byte_addr = 0;
3215     static uint16_t                     skip_size = 0;
3216
3217     ps_tpz_info = &(psNdefMap->TopazContainer);
3218
3219     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ?
3220                         psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
3221
3222     (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf, 
3223                     TOPAZ_WRITE_8_DATA_LENGTH);
3224
3225     if (ps_tpz_info->CurrentBlock == TOPAZ_BLK_FROM_BYTE_ADR (
3226         phFriNfc_Tpz_H_GetNDEFValueFieldAddrForWrite (psNdefMap, write_len)))
3227     {
3228         skip_size = 0;
3229     }
3230
3231     /* Byte Number != 0 menas that the VALUE field of the TLV is in between the 
3232         block, so the first few bytes shall be copied and then user data has to 
3233         be copied
3234         */
3235     if (0 != ps_tpz_info->ByteNumber)
3236     {
3237         write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);
3238     }
3239     
3240
3241     if (0 != skip_size)
3242     {
3243         write_index = (uint16_t)(write_index + skip_size);        
3244     }
3245
3246     while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) && 
3247         (write_len != psNdefMap->ApduBuffIndex))
3248     {
3249         skip_size = 0;
3250         byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock, 
3251                                             ps_tpz_info->ByteNumber);
3252         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
3253
3254         if (0 == skip_size)
3255         {
3256             write_buf[write_index] = 
3257                         psNdefMap->ApduBuffer[psNdefMap->ApduBuffIndex];
3258
3259             write_index = (uint16_t)(write_index + 1);
3260             psNdefMap->ApduBuffIndex = (uint16_t)
3261                                         (psNdefMap->ApduBuffIndex + 1);
3262             ps_tpz_info->ByteNumber = (uint8_t)
3263                                         (ps_tpz_info->ByteNumber + 1);
3264         }
3265         else
3266         {
3267             
3268             if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
3269             {
3270                 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
3271                             - write_index));
3272                 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
3273             }
3274             else
3275             {
3276                 ps_tpz_info->ByteNumber = (uint8_t)
3277                             (ps_tpz_info->ByteNumber + skip_size);
3278                 write_index = (uint16_t)(write_index + skip_size);
3279                 skip_size = 0;
3280             }            
3281         }
3282     }
3283
3284     if (psNdefMap->ApduBuffIndex == write_len)
3285     {
3286         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
3287     }
3288     else
3289     {
3290         if (0 != skip_size)
3291         {
3292             ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
3293             
3294         }
3295         else
3296         {
3297             ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
3298         }
3299     }
3300
3301 #ifdef TOPAZ_RAW_SUPPORT
3302     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3303 #else
3304     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3305 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3306     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf, 
3307                                             sizeof (write_buf));
3308
3309     return result;
3310
3311 }
3312
3313 static 
3314 NFCSTATUS 
3315 phFriNfc_Tpz_H_UpdateLenFieldValuesAfterRead (
3316     phFriNfc_NdefMap_t          *psNdefMap)
3317 {
3318     /* This function is called, only when the LENGTH field has to be updated 
3319         with the correct value */
3320     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
3321     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
3322     uint16_t                            write_len = 0;
3323     uint16_t                            write_index = 0;    
3324     uint16_t                            byte_addr = 0;
3325     phFriNfc_Tpz_WrSeq_t                write_seq;
3326     /* This variable is kept static because if the size to skip LOCK or RESERVED 
3327     bytes extends to next read then it shall be stored and used to skip the next 
3328     read the bytes
3329     */
3330     static uint16_t                     skip_size = 0;
3331     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3332     uint8_t                             exit_while = FALSE;
3333
3334     ps_tpz_info = &(psNdefMap->TopazContainer);
3335     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ? 
3336                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
3337    
3338     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
3339
3340     (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf, 
3341                     TOPAZ_WRITE_8_DATA_LENGTH);
3342
3343     write_seq = (phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq;
3344
3345     if (WR_LEN_1_VALUE == write_seq)
3346     {
3347         /* First LENGTH field is geting updated, so the skip size 
3348             reset is done */
3349         skip_size = 0;
3350     }
3351
3352     if (0 != ps_tpz_info->ByteNumber)
3353     {
3354         /* Byte Number is not 0, means that some data shall not be overwriteen till 
3355             that position in the block */
3356         write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber); 
3357     }
3358
3359     if (0 != skip_size)
3360     {
3361         /* This is possible after updating the FIRST length field 
3362             skip size is skipped because of the pending LOCK or 
3363             RESERVED bytes
3364         */
3365         write_index = (uint16_t)(write_index + skip_size);        
3366     }
3367
3368     while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) && 
3369         (FALSE == exit_while))
3370     {
3371         skip_size = 0;
3372         /* Get the exact byte address from the block number and 
3373             byte number */
3374         byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock, 
3375                                             ps_tpz_info->ByteNumber);
3376         /* Get the skip size */
3377         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
3378
3379         if (0 == skip_size)
3380         {
3381             switch (write_seq)
3382             {
3383                 case WR_LEN_1_VALUE:
3384                 {
3385                     /* First sequenc is always to update 1st LENGTH field of the TLV */
3386                     if (write_len < 0xFF)
3387                     {
3388                         /* This means the LENGTH field is only one BYTE */
3389                         write_buf[write_index] = (uint8_t)
3390                                         psNdefMap->ApduBuffIndex;
3391                         /* Exit the loop */
3392                         exit_while = TRUE;
3393                     }
3394                     else
3395                     {
3396                         /* Update the 1st LENGTH field */
3397                         write_buf[write_index] = (uint8_t)0xFF;                        
3398                     }
3399                     break;
3400                 }
3401
3402                 case WR_LEN_2_VALUE:
3403                 {
3404                     /* Update the 2nd LENGTH field */
3405                     write_buf[write_index] = (uint8_t)
3406                                 (psNdefMap->ApduBuffIndex >> BYTE_SIZE);
3407                     break;
3408                 }
3409
3410                 case WR_LEN_3_VALUE:
3411                 {
3412                     /* Update the 3rd LENGTH field */
3413                     write_buf[write_index] = (uint8_t)
3414                                 (psNdefMap->ApduBuffIndex & 
3415                                 TOPAZ_BYTE_LENGTH_MASK);
3416                     /* Exit the loop */
3417                     exit_while = TRUE;
3418                     break;
3419                 }                
3420
3421                 default:
3422                 {
3423                     /* Invalid case */
3424                     break;
3425                 }
3426             }
3427             write_index = (uint16_t)(write_index + 1);
3428             if (
3429                 /* As the write is done for 8 bytes, the write index cant 
3430                     go for more than or equal to 8 bytes, if it reaches 8 bytes 
3431                     then sequence shall not be incrmented */
3432                 (TOPAZ_WRITE_8_DATA_LENGTH != write_index) && 
3433                 /* If the last length field byte is updated then the 
3434                     write sequence shall not be incremented */
3435                 (WR_LEN_3_VALUE != write_seq) && 
3436                 /* Check added if the write length is less than 0xFF. 
3437                     If length is less than 0xFF, then write sequence   
3438                     shall not be incremented */
3439                 (write_len >= 0xFF)
3440                 )
3441             {
3442                 /* Sequence is incremented to the next level */
3443                 write_seq = (phFriNfc_Tpz_WrSeq_t)(write_seq + 1);
3444             }
3445             /* Byte number is incremented */
3446             ps_tpz_info->ByteNumber = (uint8_t)
3447                             (ps_tpz_info->ByteNumber + 1);
3448         }
3449         else
3450         {
3451             
3452             if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
3453             {
3454                 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
3455                             - write_index));
3456                 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
3457             }
3458             else
3459             {
3460                 ps_tpz_info->ByteNumber = (uint8_t)
3461                             (ps_tpz_info->ByteNumber + skip_size);
3462                 write_index = (uint16_t)(write_index + skip_size);
3463                 skip_size = 0;
3464             }
3465             
3466         }
3467     }
3468
3469     ps_tpz_info->WriteSeq = (uint8_t)write_seq;
3470
3471 #ifdef TOPAZ_RAW_SUPPORT
3472     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3473 #else
3474     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3475 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3476
3477     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf, 
3478                                             sizeof (write_buf));
3479     return result;
3480 }
3481
3482
3483
3484 static 
3485 NFCSTATUS 
3486 phFriNfc_Tpz_H_UpdateLenFieldZeroAfterRead (
3487     phFriNfc_NdefMap_t          *psNdefMap)
3488 {
3489     /* This function is called, only when the LENGTH field has to be updated 
3490         with the 0 */
3491     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
3492     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
3493     uint16_t                            write_len = 0;
3494     uint16_t                            write_index = 0;
3495     uint16_t                            prev_apdu_index = 0;
3496     uint16_t                            byte_addr = 0;
3497     phFriNfc_Tpz_WrSeq_t                write_seq;
3498     /* This variable is kept static because if the size to skip LOCK or RESERVED 
3499         bytes extends to next read then it shall be stored and used to skip the next 
3500         read bytes
3501     */
3502     static uint16_t                     skip_size = 0;
3503     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3504
3505     ps_tpz_info = &(psNdefMap->TopazContainer);
3506     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ? 
3507                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize);
3508
3509     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
3510
3511     (void)memcpy ((void *)write_buf, (void *)psNdefMap->SendRecvBuf, 
3512                     TOPAZ_WRITE_8_DATA_LENGTH);
3513
3514     prev_apdu_index = psNdefMap->ApduBuffIndex;
3515     write_seq = (phFriNfc_Tpz_WrSeq_t)ps_tpz_info->WriteSeq;
3516
3517     if (WR_LEN_1_0 == write_seq)
3518     {
3519          /* First LENGTH field is geting updated, so the skip size 
3520             reset is done */
3521         skip_size = 0;
3522     }
3523
3524     if (0 != ps_tpz_info->ByteNumber)
3525     {
3526         /* Byte Number is not 0, means that some data shall not be overwriteen till 
3527             that position in the block */
3528         write_index = (uint16_t)(write_index + ps_tpz_info->ByteNumber);   
3529         ps_tpz_info->ByteNumber = 0;
3530     }
3531
3532     if (0 != skip_size)
3533     {
3534         /* This is possible after updating the FIRST length field 
3535             skip size is skipped because of the pending LOCK or 
3536             RESERVED bytes
3537         */
3538         write_index = (uint16_t)(write_index + skip_size);        
3539     }
3540
3541     while ((write_index < TOPAZ_WRITE_8_DATA_LENGTH) && 
3542         (write_len != psNdefMap->ApduBuffIndex))
3543     {
3544         skip_size = 0;
3545         byte_addr = TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock, 
3546                                             ps_tpz_info->ByteNumber);
3547         skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, byte_addr);
3548
3549         if (0 == skip_size)
3550         {
3551             switch (write_seq)
3552             {
3553                 case WR_LEN_1_0:
3554                 {
3555                     /* First sequence is always to update 1st LENGTH field 
3556                         of the TLV */
3557                     write_buf[write_index] = 0x00;
3558                     write_index = (uint16_t)(write_index + 1);
3559                     if (write_len < 0xFF)
3560                     {
3561                         /* LENGTH field is only 1 byte, so update change the sequence to 
3562                             update user data */
3563                         write_seq = WR_DATA;
3564                     }
3565                     else
3566                     {
3567                         /* Go to the next LENGTH field to update */
3568                         write_seq = (phFriNfc_Tpz_WrSeq_t)((TOPAZ_WRITE_8_DATA_LENGTH != 
3569                                     write_index) ? 
3570                                     (write_seq + 1) : write_seq);
3571                     }
3572                     break;
3573                 }
3574
3575                 case WR_LEN_2_0:
3576                 case WR_LEN_3_0:
3577                 {
3578                     /* Update 2nd and 3rd LEGNTH field */
3579                     write_buf[write_index] = 0x00;
3580                     write_index = (uint16_t)(write_index + 1);
3581                     write_seq = (phFriNfc_Tpz_WrSeq_t)((TOPAZ_WRITE_8_DATA_LENGTH != 
3582                                 write_index) ? 
3583                                 (write_seq + 1) : write_seq);
3584                     break;
3585                 }                
3586
3587                 case WR_DATA:
3588                 default:
3589                 {
3590                     /* Update the buffer by the user data */
3591                     write_buf[write_index] = 
3592                             psNdefMap->ApduBuffer[psNdefMap->ApduBuffIndex];
3593                     
3594                     write_index = (uint16_t)(write_index + 1);
3595                     psNdefMap->ApduBuffIndex = (uint16_t)
3596                                         (psNdefMap->ApduBuffIndex + 1);
3597                     break;
3598                 }
3599                 
3600             }
3601             
3602             ps_tpz_info->ByteNumber = (uint8_t)
3603                             (ps_tpz_info->ByteNumber + 1);
3604         }
3605         else
3606         {
3607             /* LOCK and MEMORY bytes are found */
3608             if (skip_size >= (TOPAZ_WRITE_8_DATA_LENGTH - write_index))
3609             {
3610                 /* skip size has exceeded the block number, so calculate the 
3611                 remaining skip size  */
3612                 skip_size = (uint16_t)(skip_size - (TOPAZ_WRITE_8_DATA_LENGTH
3613                             - write_index));
3614                 write_index = (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH;
3615             }
3616             else
3617             {
3618                 /* skip the LOCK and MEMORY bytes size */
3619                 ps_tpz_info->ByteNumber = (uint8_t)
3620                             (ps_tpz_info->ByteNumber + skip_size);
3621                 write_index = (uint16_t)(write_index + skip_size);
3622                 skip_size = 0;
3623             }
3624         }
3625     }
3626
3627     if (psNdefMap->ApduBuffIndex == write_len)
3628     {
3629         /* User data has been completely copied and it is ready to write, so 
3630             change the sequence */
3631         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA;
3632     }
3633     else if ((WR_DATA == write_seq) && (prev_apdu_index == 
3634         psNdefMap->ApduBuffIndex))
3635     {
3636         /* The user data has not been written, only the LENGTH field is 
3637             updated */
3638         ps_tpz_info->WriteSeq = (uint8_t)((write_len < 0xFF) ? 
3639                                 WR_LEN_1_0 : WR_LEN_3_0);        
3640     }
3641     else
3642     {
3643         /*  Update the sequence in the context */
3644         ps_tpz_info->WriteSeq = (uint8_t)write_seq;
3645     }
3646
3647     ps_tpz_info->ByteNumber = 0;
3648
3649 #ifdef TOPAZ_RAW_SUPPORT
3650     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3651 #else
3652     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3653 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3654
3655     result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf, 
3656                                             sizeof (write_buf));
3657     return result;
3658 }
3659
3660 static 
3661 NFCSTATUS 
3662 phFriNfc_Tpz_H_RdForWrite (
3663     phFriNfc_NdefMap_t          *psNdefMap)
3664 {
3665     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
3666     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
3667     phFriNfc_Tpz_WrSeq_t                write_seq;
3668     uint16_t                            byte_addr = 0;
3669     uint8_t                             exit_while = FALSE;
3670     uint16_t                            skip_size = 0;
3671
3672     ps_tpz_info = &(psNdefMap->TopazContainer);
3673     write_seq = (phFriNfc_Tpz_WrSeq_t)(ps_tpz_info->WriteSeq);
3674
3675 #ifdef TOPAZ_RAW_SUPPORT
3676
3677     *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ8;
3678
3679 #else 
3680
3681     psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read8;
3682
3683 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3684     
3685     psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_FOR_WR_NDEF;
3686
3687     switch (write_seq)
3688     {
3689         case WR_LEN_1_0:
3690         case WR_LEN_1_VALUE:
3691         {
3692             byte_addr = (ps_tpz_info->NdefTLVByteAddress + 1);
3693             
3694             /* This loop is to skip the lock amd reserved bytes */
3695             while (FALSE == exit_while)
3696             {
3697                 if (TOPAZ_STATIC_LOCK_FIRST_BLOCK_NO == 
3698                     TOPAZ_BLK_FROM_BYTE_ADR (byte_addr))
3699                 {
3700                     byte_addr = (uint16_t)(byte_addr + 
3701                                 TOPAZ_STATIC_LOCK_RES_BYTES);
3702                 }
3703                 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, 
3704                                                             byte_addr);
3705                 if (0 != skip_size)
3706                 {
3707                     byte_addr = (uint16_t)(byte_addr + skip_size);
3708
3709                     
3710                 }
3711                 else
3712                 {
3713                     exit_while = TRUE;
3714                 }
3715             }
3716             break;
3717         }
3718
3719         case WR_LEN_2_0:
3720         case WR_LEN_3_0:
3721         case WR_LEN_2_VALUE:
3722         case WR_LEN_3_VALUE:
3723         {            
3724             byte_addr = (uint16_t)TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock, 
3725                                                     ps_tpz_info->ByteNumber); 
3726             /* This loop is for to skip the lock amd reserved bytes */
3727             while (FALSE == exit_while)
3728             {
3729                 skip_size = phFriNfc_Tpz_H_GetSkipSize (psNdefMap, 
3730                                                             byte_addr);
3731                 if (0 != skip_size)
3732                 {
3733                     byte_addr = (uint16_t)(byte_addr + skip_size);
3734                 }
3735                 else
3736                 {
3737                     exit_while = TRUE;
3738                 }
3739             }
3740             break;
3741         }
3742
3743         case WR_DATA_READ_REQD:
3744         {
3745             /* Lock or reserved bytes found bytes */
3746             byte_addr = (uint16_t)TOPAZ_BYTE_ADR_FROM_BLK (ps_tpz_info->CurrentBlock, 
3747                                                     ps_tpz_info->ByteNumber); 
3748             break;
3749         }
3750         
3751         default:
3752         {
3753             break;
3754         }
3755     }
3756
3757     ps_tpz_info->CurrentBlock = (uint8_t)
3758                         TOPAZ_BLK_FROM_BYTE_ADR (byte_addr);
3759     ps_tpz_info->ByteNumber = (uint8_t)
3760                         TOPAZ_BYTE_OFFSET_FROM_BYTE_ADR (byte_addr);
3761
3762     result = phFriNfc_Tpz_H_NxpRead (psNdefMap);
3763
3764     return result;
3765 }
3766
3767 static 
3768 uint16_t 
3769 phFriNfc_Tpz_H_CompareLockBlocks (
3770     phFriNfc_NdefMap_t          *psNdefMap, 
3771     uint8_t                     block_no, 
3772     uint16_t                    *p_skip_size)
3773 {
3774     uint16_t                            return_addr = 0;
3775     phFriNfc_LockCntrlTLVCont_t         *ps_locktlv_info = NULL;
3776
3777     ps_locktlv_info = &(psNdefMap->LockTlv);
3778
3779     if (block_no == ps_locktlv_info->BlkNum)
3780     {
3781         /* ps_tpz_info->ByteNumber = (uint8_t)ps_locktlv_info->ByteNum; */
3782         *p_skip_size = ps_locktlv_info->Size;
3783         return_addr = ps_locktlv_info->ByteAddr;
3784     }
3785    
3786     return return_addr;
3787 }
3788
3789 static 
3790 uint16_t 
3791 phFriNfc_Tpz_H_CompareMemBlocks (
3792     phFriNfc_NdefMap_t          *psNdefMap, 
3793     uint8_t                     block_no, 
3794     uint16_t                    *p_skip_size)
3795 {
3796     uint16_t                            return_addr = 0;
3797     phFriNfc_ResMemCntrlTLVCont_t       *ps_memtlv_info = NULL;
3798
3799     ps_memtlv_info = &(psNdefMap->MemTlv);
3800
3801     if (block_no == ps_memtlv_info->BlkNum)
3802     {
3803         /* ps_tpz_info->ByteNumber = (uint8_t)ps_memtlv_info->ByteNum; */
3804         *p_skip_size = ps_memtlv_info->Size;
3805         return_addr = ps_memtlv_info->ByteAddr;
3806     }
3807
3808     return return_addr;
3809 }
3810
3811
3812 static 
3813 NFCSTATUS 
3814 phFriNfc_Tpz_H_CopySendWrData (
3815     phFriNfc_NdefMap_t          *psNdefMap)
3816 {
3817     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
3818     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
3819     uint8_t                             write_buf[TOPAZ_WRITE_8_DATA_LENGTH];
3820     uint16_t                            write_len;
3821     uint8_t                             copy_length;
3822     uint16_t                            skip_size = 0;
3823
3824     ps_tpz_info = &(psNdefMap->TopazContainer);
3825     write_len = (uint16_t)((psNdefMap->ApduBufferSize < ps_tpz_info->NDEFRWSize) ? 
3826                 psNdefMap->ApduBufferSize : ps_tpz_info->NDEFRWSize); 
3827
3828     if (0 != phFriNfc_Tpz_H_CompareLockBlocks (psNdefMap, 
3829                 ps_tpz_info->CurrentBlock, &skip_size))
3830     {
3831         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
3832         ps_tpz_info->ByteNumber = 0;
3833         result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
3834     }
3835     else if (0 != phFriNfc_Tpz_H_CompareMemBlocks (psNdefMap, 
3836                 ps_tpz_info->CurrentBlock, &skip_size))
3837     {
3838         ps_tpz_info->WriteSeq = (uint8_t)WR_DATA_READ_REQD;
3839         ps_tpz_info->ByteNumber = 0;
3840         result = phFriNfc_Tpz_H_RdForWrite (psNdefMap);
3841     }
3842     else
3843     {
3844 #ifdef TOPAZ_RAW_SUPPORT
3845         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3846 #else
3847         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3848 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3849         psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE;
3850
3851         if ((write_len - psNdefMap->ApduBuffIndex) >= (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH)
3852         {
3853             copy_length = (uint8_t)TOPAZ_WRITE_8_DATA_LENGTH;
3854             (void)memcpy ((void *)write_buf, 
3855                     (void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex), 
3856                     copy_length);
3857
3858             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + 
3859                                         copy_length);
3860         }
3861         else
3862         {
3863             copy_length = (uint8_t)(write_len - psNdefMap->ApduBuffIndex);
3864
3865             (void)memcpy ((void *)write_buf, 
3866                     (void *)(psNdefMap->ApduBuffer + psNdefMap->ApduBuffIndex), 
3867                     TOPAZ_WRITE_8_DATA_LENGTH);
3868
3869             psNdefMap->ApduBuffIndex = (uint16_t)(psNdefMap->ApduBuffIndex + 
3870                                         copy_length);
3871
3872             (void)memset ((void *)(write_buf + copy_length), 0x00, 
3873                         (TOPAZ_WRITE_8_DATA_LENGTH - copy_length));
3874         }
3875
3876 #ifdef TOPAZ_RAW_SUPPORT
3877         *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_WRITE_E8;
3878 #else
3879         psNdefMap->Cmd.JewelCmd = phHal_eJewel_Write8E;
3880 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
3881
3882         result = phFriNfc_Tpz_H_NxpWrite (psNdefMap, write_buf, 
3883                                             sizeof (write_buf));
3884     }
3885
3886
3887     return result;
3888 }
3889
3890
3891 static 
3892 NFCSTATUS 
3893 phFriNfc_Tpz_H_ActualCardSize (
3894     phFriNfc_NdefMap_t          *psNdefMap)
3895 {
3896     NFCSTATUS                           result = NFCSTATUS_SUCCESS;
3897     phFriNfc_TopazCont_t                *ps_tpz_info = NULL;
3898     phFriNfc_LockCntrlTLVCont_t         *ps_locktlv_info = NULL;
3899     phFriNfc_ResMemCntrlTLVCont_t       *ps_memtlv_info = NULL;
3900     uint16_t                            ndef_value_byte_addr = 0;
3901     uint16_t                            ndef_read_write_size = 0;
3902
3903     ps_tpz_info = &(psNdefMap->TopazContainer);
3904     if (ps_tpz_info->ActualNDEFMsgSize > ps_tpz_info->RemainingSize)
3905     {
3906         ps_tpz_info->ActualNDEFMsgSize = 0;
3907         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3908                             NFCSTATUS_NO_NDEF_SUPPORT);
3909     }
3910     else
3911     {
3912         ndef_read_write_size = ps_tpz_info->RemainingSize;
3913         ndef_value_byte_addr = phFriNfc_Tpz_H_GetNDEFValueFieldAddrForRead 
3914                                 (psNdefMap);
3915         
3916         ps_locktlv_info = &(psNdefMap->LockTlv);
3917         if (ps_locktlv_info->ByteAddr > ndef_value_byte_addr)
3918         {
3919             ndef_read_write_size = (ndef_read_write_size -  
3920                                     ps_locktlv_info->Size);
3921         }
3922
3923         ps_memtlv_info = &(psNdefMap->MemTlv);
3924         if (ps_memtlv_info->ByteAddr > ndef_value_byte_addr)
3925         {
3926             ndef_read_write_size = (ndef_read_write_size -  
3927                                     ps_memtlv_info->Size);
3928         }
3929
3930         if (ps_tpz_info->ActualNDEFMsgSize > ndef_read_write_size)
3931         {
3932             ps_tpz_info->ActualNDEFMsgSize = 0;
3933             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3934                                 NFCSTATUS_NO_NDEF_SUPPORT);
3935         }
3936         else
3937         {
3938             ps_tpz_info->NDEFRWSize = (uint16_t)
3939                             ((ps_tpz_info->ActualNDEFMsgSize < 0xFF) ? 
3940                             (ndef_read_write_size - 2) : 
3941                             ndef_read_write_size);
3942         }
3943     }
3944
3945     return result;
3946 }
3947
3948 static 
3949 NFCSTATUS 
3950 phFriNfc_Tpz_H_ParseLockTLVType (
3951     phFriNfc_NdefMap_t          *psNdefMap, 
3952     uint8_t                     *p_parse_data, 
3953     uint16_t                    *p_parse_index, 
3954     uint16_t                    total_len_to_parse, 
3955     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute)
3956 {
3957     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
3958     uint16_t                    parse_index = *p_parse_index;
3959     phFriNfc_Tpz_ParseSeq_t     expected_seq = *seq_to_execute;
3960
3961     PHNFC_UNUSED_VARIABLE(psNdefMap);
3962     PHNFC_UNUSED_VARIABLE(total_len_to_parse);
3963
3964     switch (p_parse_data[parse_index])
3965     {
3966         case PH_FRINFC_TOPAZ_LOCK_CTRL_T:
3967         {
3968             expected_seq = LOCK_L_TLV;
3969             parse_index = (parse_index + 1);
3970             break;
3971         }
3972
3973         case PH_FRINFC_TOPAZ_NULL_T:
3974         {
3975             expected_seq = LOCK_T_TLV;
3976             parse_index = (parse_index + 1);
3977             break;
3978         }
3979
3980         default:
3981         {                        
3982             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
3983                                 NFCSTATUS_NO_NDEF_SUPPORT);
3984             break;
3985         }
3986     }
3987     
3988     
3989     *seq_to_execute = expected_seq;
3990     *p_parse_index = parse_index;
3991     return result;
3992 }
3993
3994 static 
3995 NFCSTATUS 
3996 phFriNfc_Tpz_H_ParseMemTLVType (
3997     phFriNfc_NdefMap_t          *psNdefMap, 
3998     uint8_t                     *p_parse_data, 
3999     uint16_t                    *p_parse_index, 
4000     uint16_t                    total_len_to_parse, 
4001     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute)
4002 {
4003     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
4004     uint16_t                    parse_index = *p_parse_index;
4005     phFriNfc_Tpz_ParseSeq_t     expected_seq = *seq_to_execute;
4006
4007     PHNFC_UNUSED_VARIABLE(psNdefMap);
4008     PHNFC_UNUSED_VARIABLE(total_len_to_parse);
4009
4010     switch (p_parse_data[parse_index])
4011     {
4012         case PH_FRINFC_TOPAZ_LOCK_CTRL_T:
4013         {
4014             expected_seq = LOCK_L_TLV;
4015             parse_index = (parse_index + 1);
4016             break;
4017         }
4018
4019         case PH_FRINFC_TOPAZ_NULL_T:
4020         {
4021             expected_seq = MEM_T_TLV;
4022             parse_index = (parse_index + 1);
4023             break;
4024         }
4025
4026         case PH_FRINFC_TOPAZ_MEM_CTRL_T:
4027         {
4028             expected_seq = MEM_L_TLV;
4029             parse_index = (parse_index + 1);
4030             break;
4031         }
4032
4033         default:
4034         {                        
4035             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4036                                 NFCSTATUS_NO_NDEF_SUPPORT);
4037             break;
4038         }
4039     }
4040     
4041     *seq_to_execute = expected_seq;
4042     *p_parse_index = parse_index;
4043     return result;
4044 }
4045
4046 static 
4047 NFCSTATUS 
4048 phFriNfc_Tpz_H_ParseNdefTLVType (
4049     phFriNfc_NdefMap_t          *psNdefMap, 
4050     uint8_t                     *p_parse_data, 
4051     uint16_t                    *p_parse_index, 
4052     uint16_t                    total_len_to_parse, 
4053     phFriNfc_Tpz_ParseSeq_t     *seq_to_execute)
4054 {
4055     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
4056     uint16_t                    parse_index = *p_parse_index;
4057     phFriNfc_Tpz_ParseSeq_t     expected_seq = *seq_to_execute;
4058
4059     PHNFC_UNUSED_VARIABLE(psNdefMap);
4060     PHNFC_UNUSED_VARIABLE(total_len_to_parse);
4061
4062     switch (p_parse_data[parse_index])
4063     {
4064         case PH_FRINFC_TOPAZ_MEM_CTRL_T:
4065         {
4066             /* TYPE field of Memory control TLV is found. 
4067                 This means that more than one memory control 
4068                 TLV exists */
4069             expected_seq = MEM_L_TLV;
4070             parse_index = (parse_index + 1);
4071             break;
4072         }
4073
4074         case PH_FRINFC_TOPAZ_NULL_T:
4075         {
4076             /* Skip the NULL TLV */
4077             expected_seq = NDEF_T_TLV;
4078             parse_index = (parse_index + 1);
4079             break;
4080         }
4081
4082         case PH_FRINFC_TOPAZ_NDEF_T:
4083         {
4084             /* TYPE field of NDEF TLV found, so next expected
4085                 sequence is LENGTH field */
4086             expected_seq = NDEF_L_TLV;
4087             parse_index = (parse_index + 1);
4088             break;
4089         }
4090
4091         default:
4092         {
4093             /* Reset the sequence */
4094             expected_seq = LOCK_T_TLV;
4095             result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4096                                 NFCSTATUS_NO_NDEF_SUPPORT);
4097             break;
4098         }
4099     }
4100     
4101     *seq_to_execute = expected_seq;
4102     *p_parse_index = parse_index;
4103     return result;
4104 }
4105
4106 static 
4107 uint16_t
4108 phFriNfc_Tpz_H_GetSkipSize (
4109     phFriNfc_NdefMap_t          *psNdefMap, 
4110     uint16_t                    byte_adr_card)
4111 {
4112     uint16_t                        return_size = 0;
4113     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
4114     phFriNfc_ResMemCntrlTLVCont_t   *ps_memtlv_info = NULL;
4115
4116     ps_locktlv_info = &(psNdefMap->LockTlv);
4117     ps_memtlv_info = &(psNdefMap->MemTlv);
4118
4119     /* If there are more than one LOCK CONTROL TLV, then 
4120     ADD A LOOP HERE OF THE NUMBER OF TLVs FOUND */
4121     if (byte_adr_card == ps_locktlv_info->ByteAddr)
4122     {
4123         return_size = ps_locktlv_info->Size;
4124     }
4125
4126     /* If there are more than one MEMORY CONTROL TLV, then 
4127         ADD A LOOP HERE OF THE NUMBER OF TLVs FOUND */
4128     if (byte_adr_card == ps_memtlv_info->ByteAddr)
4129     {
4130         return_size = ps_memtlv_info->Size;
4131     }
4132     return return_size;
4133 }
4134
4135 static 
4136 NFCSTATUS 
4137 phFriNfc_Tpz_H_GetLockBytesInfo (
4138     phFriNfc_NdefMap_t          *psNdefMap, 
4139     uint8_t                     *p_lock_info)
4140 {
4141     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
4142     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
4143     uint8_t                         page_address = 0;
4144     uint8_t                         bytes_offset = 0;
4145     uint8_t                         lock_index = 0;
4146
4147     ps_locktlv_info = &(psNdefMap->LockTlv);
4148
4149     page_address = (uint8_t)(p_lock_info[lock_index] >> NIBBLE_SIZE);
4150     bytes_offset = (uint8_t)(p_lock_info[lock_index] & TOPAZ_NIBBLE_MASK);
4151
4152     lock_index = (lock_index + 1);
4153     ps_locktlv_info->Size = (uint16_t)
4154                             (((p_lock_info[lock_index] % TOPAZ_BYTE_SIZE_IN_BITS) > 0)? 
4155                             ((p_lock_info[lock_index] / TOPAZ_BYTE_SIZE_IN_BITS) + 1) : 
4156                             (p_lock_info[lock_index] / TOPAZ_BYTE_SIZE_IN_BITS));
4157
4158     lock_index = (lock_index + 1);
4159     ps_locktlv_info->BytesPerPage = 
4160                             (p_lock_info[lock_index] & TOPAZ_NIBBLE_MASK);
4161     ps_locktlv_info->BytesLockedPerLockBit = 
4162                             (p_lock_info[lock_index] >> NIBBLE_SIZE);
4163
4164     /* Apply the formula to calculate byte address 
4165         ByteAddr = PageAddr*2^BytesPerPage + ByteOffset
4166     */
4167     ps_locktlv_info->ByteAddr = (uint16_t)((page_address 
4168                                 * (1 << ps_locktlv_info->BytesPerPage))
4169                                 + bytes_offset);
4170
4171     
4172     if (
4173         /* Out of bound memory check */    
4174         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) > 
4175         (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] * 
4176         TOPAZ_BYTES_PER_BLOCK)) || 
4177
4178         /* Check the static lock and reserved areas memory blocks */
4179         ((ps_locktlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) && 
4180         (ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) || 
4181         (((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) >= 
4182         TOPAZ_STATIC_LOCK_RES_START) && 
4183         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) < 
4184         TOPAZ_STATIC_LOCK_RES_END))
4185         )
4186     {
4187         ps_locktlv_info->ByteAddr = 0;
4188         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4189                             NFCSTATUS_NO_NDEF_SUPPORT);
4190     }
4191     else
4192     {
4193         ps_locktlv_info->BlkNum = (ps_locktlv_info->ByteAddr / 
4194                                     TOPAZ_BYTES_PER_BLOCK);
4195         ps_locktlv_info->ByteNum = (ps_locktlv_info->ByteAddr % 
4196                                     TOPAZ_BYTES_PER_BLOCK);
4197     }
4198
4199     return result;
4200 }
4201
4202 static 
4203 NFCSTATUS 
4204 phFriNfc_Tpz_H_GetMemBytesInfo (
4205     phFriNfc_NdefMap_t          *psNdefMap,      
4206     uint8_t                     *p_mem_info)
4207 {
4208     NFCSTATUS                       result = NFCSTATUS_SUCCESS;
4209     phFriNfc_ResMemCntrlTLVCont_t   *ps_memtlv_info = NULL;
4210     phFriNfc_LockCntrlTLVCont_t     *ps_locktlv_info = NULL;
4211     uint8_t                         page_address = 0;
4212     uint8_t                         bytes_offset = 0;
4213     uint8_t                         mem_index = 0;
4214
4215     ps_memtlv_info = &(psNdefMap->MemTlv);
4216     ps_locktlv_info = &(psNdefMap->LockTlv);
4217     page_address = (uint8_t)(p_mem_info[mem_index] >> NIBBLE_SIZE);
4218     bytes_offset = (uint8_t)(p_mem_info[mem_index] & TOPAZ_NIBBLE_MASK);
4219
4220     mem_index = (mem_index + 1);
4221     ps_memtlv_info->Size = (uint16_t)p_mem_info[mem_index];
4222
4223     mem_index = (mem_index + 1);
4224     ps_memtlv_info->BytesPerPage = 
4225                             (p_mem_info[mem_index] & TOPAZ_NIBBLE_MASK);
4226
4227     /* Apply the formula to calculate byte address 
4228         ByteAddr = PageAddr * 2^BytesPerPage + ByteOffset
4229     */
4230     ps_memtlv_info->ByteAddr = (uint16_t)((page_address 
4231                             * (1 << ps_memtlv_info->BytesPerPage))
4232                             + bytes_offset);
4233
4234     
4235     if (
4236         /* Check if the lock and memory bytes are overlapped */
4237         ((ps_memtlv_info->ByteAddr >= ps_locktlv_info->ByteAddr) &&
4238         (ps_memtlv_info->ByteAddr <= 
4239         (ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1))) || 
4240
4241         (((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) >= 
4242         ps_locktlv_info->ByteAddr) &&
4243         ((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) <= 
4244         (ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1))) || 
4245
4246         /* Check the static lock and reserved areas memory blocks */
4247         ((ps_memtlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) && 
4248         (ps_memtlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) || 
4249         (((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) >= 
4250         TOPAZ_STATIC_LOCK_RES_START) && 
4251         ((ps_memtlv_info->ByteAddr + ps_memtlv_info->Size - 1) < 
4252         TOPAZ_STATIC_LOCK_RES_END)) ||
4253
4254         /* Check if the memory address is out bound */
4255         ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) > 
4256         (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] * 
4257         TOPAZ_BYTES_PER_BLOCK))
4258         )
4259     {
4260         ps_memtlv_info->ByteAddr = 0;
4261         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
4262                             NFCSTATUS_NO_NDEF_SUPPORT);
4263     }
4264     else
4265     {
4266         ps_memtlv_info->BlkNum = (ps_memtlv_info->ByteAddr / 
4267                                     TOPAZ_BYTES_PER_BLOCK);
4268         ps_memtlv_info->ByteNum = (ps_memtlv_info->ByteAddr % 
4269                                     TOPAZ_BYTES_PER_BLOCK);
4270     }
4271
4272     return result;
4273 }
4274
4275 #ifdef UNIT_TEST
4276 #include <phUnitTestNfc_TopazDynamic_static.c>
4277 #endif
4278
4279 #endif  /*#if !(defined(PH_FRINFC_MAP_TOPAZ_DISABLED ) || defined (PH_FRINFC_MAP_TOPAZ_DYNAMIC_DISABLED ))*/
4280
4281
4282