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