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