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