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