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