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 */ 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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