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