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