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_TopazMap.c 19 * \brief NFC Ndef Mapping For Remote Devices. 20 * 21 * Project: NFC-FRI 22 * 23 * $Date: Mon Dec 13 14:14:14 2010 $ 24 * $Author: ing02260 $ 25 * $Revision: 1.23 $ 26 * $Aliases: $ 27 * 28 */ 29 30 31 32 #include <phFriNfc_NdefMap.h> 33 #include <phFriNfc_TopazMap.h> 34 #include <phFriNfc_MapTools.h> 35 #include <phFriNfc_OvrHal.h> 36 37 #ifndef PH_FRINFC_MAP_TOPAZ_DISABLED 38 /*! \ingroup grp_file_attributes 39 * \name NDEF Mapping 40 * 41 * File: \ref phFriNfcNdefMap.c 42 * 43 */ 44 /*@{*/ 45 #define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.23 $" 46 #define PHFRINFCTOPAZMAP_FILEALIASES "$Aliases: $" 47 /*@}*/ 48 /****************** Start of macros ********************/ 49 /* Below MACRO is used for the WRITE error scenario, 50 in case PN544 returns error for any WRITE, then 51 read the written block and byte number, to check the data 52 written to the card is correct or not 53 */ 54 /* #define TOPAZ_RF_ERROR_WORKAROUND */ 55 56 #ifdef FRINFC_READONLY_NDEF 57 58 #define CC_BLOCK_NUMBER (0x01U) 59 #define LOCK_BLOCK_NUMBER (0x0EU) 60 61 #define LOCK0_BYTE_NUMBER (0x00U) 62 #define LOCK0_BYTE_VALUE (0xFFU) 63 64 #define LOCK1_BYTE_NUMBER (0x01U) 65 #define LOCK1_BYTE_VALUE (0x7FU) 66 67 #define CC_RWA_BYTE_NUMBER (0x03U) 68 #define CC_READ_ONLY_VALUE (0x0FU) 69 70 #endif /* #ifdef FRINFC_READONLY_NDEF */ 71 72 #ifdef TOPAZ_RF_ERROR_WORKAROUND 73 74 /* Below MACROs are added for the error returned from HAL, if the 75 below error has occured during the WRITE, then read the error 76 returned blocks to confirm */ 77 #define FRINFC_RF_TIMEOUT_89 (0x89U) 78 #define FRINFC_RF_TIMEOUT_90 (0x90U) 79 80 /* State specific to read after the RF ERROR for the WRITE */ 81 #define PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ (0x0FU) 82 83 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */ 84 85 /****************** End of macros ********************/ 86 87 /*! 88 * \name Topaz Mapping - Helper Functions 89 * 90 */ 91 /*@{*/ 92 93 /*! 94 * \brief \copydoc page_ovr Helper function for Topaz. This function shall read 8 bytes 95 * from the card. 96 */ 97 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap, 98 uint16_t BlockNo, 99 uint16_t ByteNo); 100 101 /*! 102 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process 103 * read id command 104 */ 105 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap); 106 107 /*! 108 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process 109 * read all command 110 */ 111 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap); 112 113 /*! 114 * \brief \copydoc page_ovr Helper function for Topaz. This function depends on 115 * function called by the user 116 */ 117 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap); 118 119 /*! 120 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC 121 * bytes 122 */ 123 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap); 124 125 /*! 126 * \brief \copydoc page_ovr Helper function for Topaz. This function finds 127 * NDEF TLV 128 */ 129 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap); 130 131 /*! 132 * \brief \copydoc page_ovr Helper function for Topaz. This function writes a 133 * byte into the card 134 */ 135 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap, 136 uint16_t BlockNo, 137 uint16_t ByteNo, 138 uint8_t ByteVal 139 ); 140 141 /*! 142 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the 143 * NMN write 144 */ 145 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap); 146 147 /*! 148 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the length field of 149 * the NDEF TLV 150 */ 151 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap); 152 153 /*! 154 * \brief \copydoc page_ovr Helper function for Topaz. This function updates length field 155 * of the NDEF TLV after complete write. 156 */ 157 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t *NdefMap); 158 159 /*! 160 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the card data 161 * to the user buffer 162 */ 163 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf( phFriNfc_NdefMap_t *NdefMap); 164 165 /*! 166 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the 167 * written data 168 */ 169 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData( phFriNfc_NdefMap_t *NdefMap); 170 171 /*! 172 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the block 173 * number is correct or not 174 */ 175 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t *NdefMap); 176 177 /*! 178 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the 0th 179 * byte of block 1 has Zero 180 */ 181 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t *NdefMap); 182 183 /*! 184 * \brief \copydoc page_ovr Helper function for Topaz. This function calls the 185 * completion routine 186 */ 187 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t *NdefMap, 188 NFCSTATUS Status); 189 190 /*! 191 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks 192 * the CC byte in check ndef function 193 */ 194 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t *NdefMap); 195 196 /*! 197 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks 198 * the lock bits and set a card state 199 */ 200 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t *NdefMap); 201 202 /*! 203 * \brief \copydoc page_ovr Helper function for Topaz. This function writes CC bytes or 204 * type of the TLV 205 */ 206 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t *NdefMap); 207 208 #ifdef TOPAZ_RF_ERROR_WORKAROUND 209 210 /*! 211 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written 212 * value after the 213 */ 214 static 215 NFCSTATUS 216 phFriNfc_Tpz_H_CheckWrittenData ( 217 phFriNfc_NdefMap_t *psNdefMap, 218 uint8_t state_rf_error); 219 220 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */ 221 222 /*! 223 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written 224 * CC bytes are correct 225 */ 226 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t *NdefMap); 227 /*@}*/ 228 void phFriNfc_TopazMap_H_Reset(phFriNfc_NdefMap_t *NdefMap) 229 { 230 /* Initialising the Topaz structure variable */ 231 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_INVALID_OPE; 232 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1; 233 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0; 234 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_VAL0; 235 (void)memset(NdefMap->TopazContainer.ReadBuffer, PH_FRINFC_TOPAZ_VAL0, 236 sizeof(NdefMap->TopazContainer.ReadBuffer)); 237 NdefMap->TopazContainer.ReadWriteCompleteFlag = PH_FRINFC_TOPAZ_FLAG0; 238 NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_VAL0; 239 (void)memset(NdefMap->TopazContainer.UID, PH_FRINFC_TOPAZ_VAL0, 240 sizeof(NdefMap->TopazContainer.UID)); 241 NdefMap->TopazContainer.Cur_RW_Index=0; 242 NdefMap->TopazContainer.ByteRWFrmCard =0; 243 } 244 245 /*! 246 * \brief Check whether a particular Remote Device is NDEF compliant. 247 * 248 * The function checks whether the peer device is NDEF compliant. 249 * 250 * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t 251 * structure describing the component context. 252 * 253 * \retval NFCSTATUS_PENDING The action has been successfully triggered. 254 * \retval Others An error has occurred. 255 * 256 */ 257 258 NFCSTATUS phFriNfc_TopazMap_ChkNdef( phFriNfc_NdefMap_t *NdefMap) 259 { 260 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 261 NFCSTATUS_INVALID_PARAMETER); 262 if ( NdefMap != NULL) 263 { 264 /* Update the previous operation */ 265 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; 266 /* Update the CR index to know from which operation completion 267 routine has to be called */ 268 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF; 269 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1; 270 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0; 271 272 /* Set card state */ 273 NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_CARD; 274 275 /* Change the state to Check Ndef Compliant */ 276 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID; 277 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE; 278 279 #ifdef TOPAZ_RAW_SUPPORT 280 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 281 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID; 282 #else 283 #ifdef PH_HAL4_ENABLE 284 NdefMap->Cmd.JewelCmd = phHal_eJewel_RID; 285 #else 286 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid; 287 #endif 288 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 289 290 Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock, 291 NdefMap->TopazContainer.ByteNumber); 292 } 293 return Result; 294 } 295 296 #ifdef FRINFC_READONLY_NDEF 297 298 NFCSTATUS 299 phFriNfc_TopazMap_ConvertToReadOnly ( 300 phFriNfc_NdefMap_t *NdefMap) 301 { 302 NFCSTATUS result = NFCSTATUS_SUCCESS; 303 304 result = phFriNfc_Tpz_H_WrAByte (NdefMap, CC_BLOCK_NUMBER, 305 CC_RWA_BYTE_NUMBER, CC_READ_ONLY_VALUE); 306 307 if (NFCSTATUS_PENDING == PHNFCSTATUS(result)) 308 { 309 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE; 310 } 311 return result; 312 } 313 314 #endif /* #ifdef FRINFC_READONLY_NDEF */ 315 316 /*! 317 * \brief Initiates Reading of NDEF information from the Remote Device. 318 * 319 * The function initiates the reading of NDEF information from a Remote Device. 320 * It performs a reset of the state and starts the action (state machine). 321 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action 322 * has been triggered. 323 */ 324 NFCSTATUS phFriNfc_TopazMap_RdNdef( phFriNfc_NdefMap_t *NdefMap, 325 uint8_t *PacketData, 326 uint32_t *PacketDataLength, 327 uint8_t Offset) 328 { 329 NFCSTATUS Result = NFCSTATUS_SUCCESS; 330 331 /* Copy user buffer to the context */ 332 NdefMap->ApduBuffer = PacketData; 333 /* Copy user length to the context */ 334 NdefMap->ApduBufferSize = *PacketDataLength; 335 /* Update the user memory size to a context variable */ 336 NdefMap->NumOfBytesRead = PacketDataLength; 337 /* Number of bytes read from the card is zero. 338 This variable returns the number of bytes read 339 from the card. */ 340 *NdefMap->NumOfBytesRead = PH_FRINFC_TOPAZ_VAL0; 341 /* Index to know the length read */ 342 NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0; 343 /* Store the offset in the context */ 344 NdefMap->Offset = Offset; 345 /* Update the CR index to know from which operation completion 346 routine has to be called */ 347 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF; 348 349 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation == 350 PH_FRINFC_NDEFMAP_WRITE_OPE)) 351 { 352 /* If previous operation is not read then the read shall 353 start from BEGIN */ 354 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN; 355 /* Initialise current block and byte number */ 356 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1; 357 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0; 358 /* State has to be changed */ 359 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL; 360 NdefMap->TopazContainer.ReadWriteCompleteFlag = 361 PH_FRINFC_TOPAZ_FLAG0; 362 /* Topaz command = READALL */ 363 #ifdef TOPAZ_RAW_SUPPORT 364 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 365 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL; 366 #else 367 368 #ifdef PH_HAL4_ENABLE 369 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll; 370 #else 371 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll; 372 #endif 373 374 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 375 } 376 377 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; 378 /* Offset = Current, but the read has reached the End of Card */ 379 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && 380 (NdefMap->TopazContainer.ReadWriteCompleteFlag == 381 PH_FRINFC_TOPAZ_FLAG1)) 382 { 383 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 384 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 385 } 386 else 387 { 388 /* if the offset is begin then call READALL else copy the data 389 from the user buffer */ 390 Result = ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)? 391 phFriNfc_Tpz_H_RdBytes(NdefMap, 392 NdefMap->TopazContainer.CurrentBlock, 393 NdefMap->TopazContainer.ByteNumber): 394 phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap)); 395 } 396 397 return Result; 398 } 399 400 /*! 401 * \brief Initiates Writing of NDEF information to the Remote Device. 402 * 403 * The function initiates the writing of NDEF information to a Remote Device. 404 * It performs a reset of the state and starts the action (state machine). 405 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action 406 * has been triggered. 407 */ 408 NFCSTATUS phFriNfc_TopazMap_WrNdef( phFriNfc_NdefMap_t *NdefMap, 409 uint8_t *PacketData, 410 uint32_t *PacketDataLength, 411 uint8_t Offset) 412 { 413 NFCSTATUS Result = NFCSTATUS_SUCCESS; 414 uint8_t TempByteVal = 0; 415 /* Copy user buffer to the context */ 416 NdefMap->ApduBuffer = PacketData; 417 /* Copy user length to the context */ 418 NdefMap->ApduBufferSize = *PacketDataLength; 419 /* Index to know the length written */ 420 NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0; 421 /* Update the user memory size to a context variable */ 422 NdefMap->WrNdefPacketLength = PacketDataLength; 423 /* Number of bytes written to the card is zero. 424 This variable returns the number of bytes written 425 to the card. */ 426 *NdefMap->WrNdefPacketLength = PH_FRINFC_TOPAZ_VAL0; 427 /* Update the CR index to know from which operation completion 428 routine has to be called */ 429 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF; 430 /* Store the offset in the context */ 431 NdefMap->Offset = Offset; 432 433 434 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || 435 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE)) 436 { 437 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN; 438 /* Initialise current block and byte number */ 439 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1; 440 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0; 441 /* State has to be changed */ 442 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL; 443 /* Topaz command = READALL */ 444 445 #ifdef TOPAZ_RAW_SUPPORT 446 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 447 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL; 448 #else 449 #ifdef PH_HAL4_ENABLE 450 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll; 451 #else 452 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll; 453 #endif 454 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 455 NdefMap->TopazContainer.ReadWriteCompleteFlag = 456 PH_FRINFC_TOPAZ_FLAG0; 457 NdefMap->TopazContainer.RemainingSize = NdefMap->CardMemSize; 458 TempByteVal = NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1]; 459 } 460 else 461 { 462 /* State has to be changed */ 463 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE; 464 /* copy the user data to write into the card */ 465 TempByteVal = NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]; 466 } 467 468 /* Update the previous operation to write operation */ 469 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; 470 if((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && 471 (NdefMap->TopazContainer.ReadWriteCompleteFlag == 472 PH_FRINFC_TOPAZ_FLAG1)) 473 { 474 /* Offset = Current, but the read has reached the End of Card */ 475 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 476 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 477 } 478 else 479 { 480 /* Check the block */ 481 phFriNfc_Tpz_H_BlkChk(NdefMap); 482 /* if offset is begin then call READALL else start writing */ 483 Result = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)? 484 phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock, 485 NdefMap->TopazContainer.ByteNumber): 486 phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock, 487 NdefMap->TopazContainer.ByteNumber,TempByteVal)); 488 } 489 490 return Result; 491 } 492 493 494 /*! 495 * \brief Completion Routine, Processing function, needed to avoid long blocking. 496 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion 497 * Routine in order to be able to notify the component that an I/O has finished and data are 498 * ready to be processed. 499 * 500 */ 501 502 void phFriNfc_TopazMap_Process( void *Context, 503 NFCSTATUS Status) 504 { 505 506 phFriNfc_NdefMap_t *psNdefMap = NULL; 507 508 #ifdef TOPAZ_RF_ERROR_WORKAROUND 509 510 static uint8_t rf_error_state = 0; 511 512 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */ 513 #ifdef FRINFC_READONLY_NDEF 514 static uint8_t written_lock_byte = 0; 515 #endif /* #ifdef FRINFC_READONLY_NDEF */ 516 517 psNdefMap = (phFriNfc_NdefMap_t *)Context; 518 519 if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER)) 520 { 521 switch (psNdefMap->State) 522 { 523 #ifdef FRINFC_READONLY_NDEF 524 case PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE: 525 { 526 if((CC_READ_ONLY_VALUE == *psNdefMap->SendRecvBuf) 527 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)) 528 { 529 written_lock_byte = 0; 530 #ifdef TOPAZ_RAW_SUPPORT 531 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ; 532 #else 533 #ifdef PH_HAL4_ENABLE 534 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1; 535 #else 536 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1; 537 #endif /* #ifdef PH_HAL4_ENABLE */ 538 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 539 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER, 540 LOCK0_BYTE_NUMBER); 541 542 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status)) 543 { 544 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE; 545 } 546 } 547 else 548 { 549 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 550 NFCSTATUS_INVALID_RECEIVE_LENGTH); 551 } 552 break; 553 } 554 555 case PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE: 556 { 557 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength) 558 { 559 Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER, 560 LOCK0_BYTE_NUMBER, 561 LOCK0_BYTE_VALUE); 562 563 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status)) 564 { 565 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE; 566 } 567 } 568 break; 569 } 570 571 case PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE: 572 { 573 if((LOCK0_BYTE_VALUE == *psNdefMap->SendRecvBuf) 574 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)) 575 { 576 #ifdef TOPAZ_RAW_SUPPORT 577 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ; 578 #else 579 #ifdef PH_HAL4_ENABLE 580 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1; 581 #else 582 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1; 583 #endif /* #ifdef PH_HAL4_ENABLE */ 584 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 585 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER, 586 LOCK1_BYTE_NUMBER); 587 588 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status)) 589 { 590 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE; 591 } 592 } 593 else 594 { 595 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 596 NFCSTATUS_INVALID_RECEIVE_LENGTH); 597 } 598 } 599 600 case PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE: 601 { 602 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength) 603 { 604 written_lock_byte = (uint8_t)(*psNdefMap->SendRecvBuf | LOCK1_BYTE_VALUE); 605 Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER, 606 LOCK1_BYTE_NUMBER, 607 written_lock_byte); 608 609 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status)) 610 { 611 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE; 612 } 613 } 614 break; 615 } 616 617 case PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE: 618 { 619 if((written_lock_byte == *psNdefMap->SendRecvBuf) 620 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)) 621 { 622 written_lock_byte = 0; 623 /* Do nothing */ 624 } 625 else 626 { 627 written_lock_byte = 0; 628 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 629 NFCSTATUS_INVALID_RECEIVE_LENGTH); 630 } 631 } 632 #endif /* #ifdef FRINFC_READONLY_NDEF */ 633 case PH_FRINFC_TOPAZ_STATE_WRITE: 634 { 635 Status = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap); 636 break; 637 } 638 639 case PH_FRINFC_TOPAZ_STATE_READID: 640 { 641 Status = phFriNfc_Tpz_H_ProReadID (psNdefMap); 642 break; 643 } 644 645 case PH_FRINFC_TOPAZ_STATE_READALL: 646 { 647 Status = phFriNfc_Tpz_H_ProReadAll (psNdefMap); 648 break; 649 } 650 651 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN: 652 { 653 Status = phFriNfc_Tpz_H_ProWrNMN (psNdefMap); 654 break; 655 } 656 657 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV: 658 { 659 Status = phFriNfc_Tpz_H_ProWrTLV (psNdefMap); 660 break; 661 } 662 663 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV: 664 { 665 Status = phFriNfc_Tpz_H_ProCCTLV (psNdefMap); 666 break; 667 } 668 669 #ifdef TOPAZ_RF_ERROR_WORKAROUND 670 671 case PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ: 672 { 673 Status = phFriNfc_Tpz_H_CheckWrittenData (psNdefMap, 674 rf_error_state); 675 break; 676 } 677 678 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */ 679 680 default: 681 { 682 Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP, 683 NFCSTATUS_INVALID_DEVICE_REQUEST); 684 break; 685 } 686 } 687 } 688 else 689 { 690 #ifdef TOPAZ_RF_ERROR_WORKAROUND 691 692 if ((FRINFC_RF_TIMEOUT_89 == PHNFCSTATUS (Status)) || 693 (FRINFC_RF_TIMEOUT_90 == PHNFCSTATUS (Status)) || 694 (NFCSTATUS_RF_TIMEOUT == PHNFCSTATUS (Status))) 695 { 696 uint8_t byte_number = 0; 697 uint8_t block_number = 0; 698 699 rf_error_state = psNdefMap->State; 700 701 #ifdef TOPAZ_RAW_SUPPORT 702 703 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ; 704 705 #else 706 707 #ifdef PH_HAL4_ENABLE 708 709 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1; 710 711 #else 712 713 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1; 714 715 #endif /* #ifdef PH_HAL4_ENABLE */ 716 717 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 718 719 /* Update the state variable to the new work around state*/ 720 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ; 721 722 /* Switch is used to know, if the error occured during WRITE or READ */ 723 switch (rf_error_state) 724 { 725 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN: 726 { 727 /* Block and byte number is updated for NMN */ 728 byte_number = PH_FRINFC_TOPAZ_VAL0; 729 block_number = PH_FRINFC_TOPAZ_VAL1; 730 break; 731 } 732 733 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV: 734 { 735 /* Get the L field of the TLV block */ 736 block_number = (uint8_t)(((psNdefMap->TLVStruct.NdefTLVByte + 737 PH_FRINFC_TOPAZ_VAL1) > 738 PH_FRINFC_TOPAZ_VAL7)? 739 (psNdefMap->TLVStruct.NdefTLVBlock + 740 PH_FRINFC_TOPAZ_VAL1): 741 psNdefMap->TLVStruct.NdefTLVBlock); 742 /* Get the L byte */ 743 byte_number = (uint8_t)((psNdefMap->TLVStruct.NdefTLVByte + 744 PH_FRINFC_TOPAZ_VAL1) % 745 PH_FRINFC_TOPAZ_VAL8); 746 break; 747 } 748 749 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV: 750 { 751 switch (psNdefMap->TopazContainer.InternalState) 752 { 753 case PH_FRINFC_TOPAZ_WR_CC_BYTE0: 754 { 755 /* Block and byte number is updated for the CC byte 0 */ 756 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1; 757 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL0; 758 break; 759 } 760 761 case PH_FRINFC_TOPAZ_WR_CC_BYTE1: 762 { 763 /* Block and byte number is updated for the CC byte 1 */ 764 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1; 765 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1; 766 break; 767 } 768 769 case PH_FRINFC_TOPAZ_WR_CC_BYTE2: 770 { 771 /* Block and byte number is updated for the CC byte 2 */ 772 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1; 773 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL2; 774 break; 775 } 776 777 case PH_FRINFC_TOPAZ_WR_CC_BYTE3: 778 { 779 /* Block and byte number is updated for the CC byte 3 */ 780 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1; 781 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL3; 782 break; 783 } 784 785 case PH_FRINFC_TOPAZ_WR_T_OF_TLV: 786 { 787 /* Block and byte number is updated for the Type field of the TLV */ 788 block_number = psNdefMap->TLVStruct.NdefTLVBlock; 789 byte_number = (uint8_t)psNdefMap->TLVStruct.NdefTLVByte; 790 break; 791 } 792 793 default: 794 { 795 /* Do nothing */ 796 break; 797 } 798 } /* switch (psNdefMap->TopazContainer.InternalState) */ 799 break; 800 } 801 802 case PH_FRINFC_TOPAZ_STATE_WRITE: 803 { 804 /* Block and byte number is updated for the written error data */ 805 block_number = psNdefMap->TopazContainer.CurrentBlock; 806 byte_number = psNdefMap->TopazContainer.ByteNumber; 807 break; 808 } 809 810 default: 811 { 812 /* Error occured is not during WRITE, so update 813 state variable to the previous state */ 814 psNdefMap->State = rf_error_state; 815 break; 816 } 817 } /* switch (rf_error_state) */ 818 819 /* The below check is added, to know if the error is for 820 the WRITE or READ scenario, 821 If the error is for READ, then state variable is not updated 822 If the error is for WRITE, then state variable is updated with 823 PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ value */ 824 if (PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ == psNdefMap->State) 825 { 826 /* Read the data with the updated block and byte number */ 827 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, block_number, 828 byte_number); 829 } 830 } 831 832 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */ 833 } 834 835 /* Call Completion Routine, if Status != PENDING */ 836 if (NFCSTATUS_PENDING != Status) 837 { 838 phFriNfc_Tpz_H_Complete(psNdefMap, Status); 839 } 840 } 841 842 843 #ifdef TOPAZ_RF_ERROR_WORKAROUND 844 845 static 846 NFCSTATUS 847 phFriNfc_Tpz_H_CheckWrittenData ( 848 phFriNfc_NdefMap_t *psNdefMap, 849 uint8_t state_rf_error) 850 { 851 NFCSTATUS result = NFCSTATUS_SUCCESS; 852 853 switch (state_rf_error) 854 { 855 case PH_FRINFC_TOPAZ_STATE_WRITE: 856 { 857 result = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap); 858 break; 859 } 860 861 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN: 862 { 863 result = phFriNfc_Tpz_H_ProWrNMN (psNdefMap); 864 break; 865 } 866 867 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV: 868 { 869 result = phFriNfc_Tpz_H_ProWrTLV (psNdefMap); 870 break; 871 } 872 873 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV: 874 { 875 result = phFriNfc_Tpz_H_ProCCTLV (psNdefMap); 876 break; 877 } 878 879 default: 880 { 881 break; 882 } 883 } 884 885 return result; 886 } 887 888 889 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */ 890 891 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap, 892 uint16_t BlockNo, 893 uint16_t ByteNo) 894 { 895 NFCSTATUS Result = NFCSTATUS_SUCCESS; 896 #ifdef TOPAZ_RAW_SUPPORT 897 uint8_t index = 0; 898 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 899 900 /* set the data for additional data exchange*/ 901 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0; 902 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0; 903 NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0; 904 905 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process; 906 NdefMap->MapCompletionInfo.Context = NdefMap; 907 908 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; 909 910 /* Depending on the jewel command, the send length is decided */ 911 #ifdef TOPAZ_RAW_SUPPORT 912 switch(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0]) 913 #else 914 switch(NdefMap->Cmd.JewelCmd) 915 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 916 { 917 918 #ifdef TOPAZ_RAW_SUPPORT 919 case PH_FRINFC_TOPAZ_CMD_READID: 920 #else 921 #ifdef PH_HAL4_ENABLE 922 case phHal_eJewel_RID: 923 #else 924 case phHal_eJewelCmdListJewelRid: 925 #endif 926 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 927 928 #ifdef TOPAZ_RAW_SUPPORT 929 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 930 /*Copy command to Send Buffer*/ 931 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID; 932 index ++; 933 934 /*Copy UID of the tag to Send Buffer*/ 935 (void)memset(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1]), 936 0x00,(0x06)); 937 index = index + 0x06; 938 939 /* Update the length of the command buffer*/ 940 NdefMap->SendLength = index; 941 #else 942 /* For READ ID and READ ALL, send length is 0 */ 943 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0; 944 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 945 break; 946 947 #ifdef TOPAZ_RAW_SUPPORT 948 case PH_FRINFC_TOPAZ_CMD_READALL: 949 #else 950 #ifdef PH_HAL4_ENABLE 951 case phHal_eJewel_ReadAll: 952 #else 953 case phHal_eJewelCmdListJewelReadAll: 954 #endif 955 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 956 957 #ifdef TOPAZ_RAW_SUPPORT 958 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 959 /*Copy command to Send Buffer*/ 960 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL; 961 index ++; 962 963 /*Copy 0x00 to Send Buffer*/ 964 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00; 965 index ++; 966 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00; 967 index ++; 968 969 /*Copy UID of the tag to Send Buffer*/ 970 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]), 971 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid), 972 TOPAZ_UID_LENGTH_FOR_READ_WRITE); 973 974 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE); 975 976 /* Update the length of the command buffer*/ 977 NdefMap->SendLength = index; 978 #else 979 /* For READ ID and READ ALL, send length is 0 */ 980 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0; 981 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 982 break; 983 984 #ifdef TOPAZ_RAW_SUPPORT 985 case PH_FRINFC_TOPAZ_CMD_READ: 986 #else 987 #ifdef PH_HAL4_ENABLE 988 case phHal_eJewel_Read1: 989 #else 990 case phHal_eJewelCmdListJewelRead1: 991 #endif 992 993 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 994 995 #ifdef TOPAZ_RAW_SUPPORT 996 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 997 /*Copy command to Send Buffer*/ 998 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READ; 999 index ++; 1000 1001 /*Copy Address to Send Buffer*/ 1002 /* Calculate send length 1003 7 | 6 5 4 3 | 2 1 0 | 1004 | block no | byte no | 1005 */ 1006 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 1007 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + 1008 ByteNo); 1009 index ++; 1010 /*Copy 0x00 to Send Buffer*/ 1011 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00; 1012 index ++; 1013 1014 /*Copy UID of the tag to Send Buffer*/ 1015 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]), 1016 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid), 1017 TOPAZ_UID_LENGTH_FOR_READ_WRITE); 1018 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE); 1019 1020 /* Update the length of the command buffer*/ 1021 NdefMap->SendLength = index; 1022 #else 1023 /* Calculate send length 1024 7 | 6 5 4 3 | 2 1 0 | 1025 | block no | byte no | 1026 */ 1027 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = 1028 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + 1029 ByteNo); 1030 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL1; 1031 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 1032 1033 break; 1034 #ifdef TOPAZ_RAW_SUPPORT 1035 #else 1036 #ifdef PH_HAL4_ENABLE 1037 case phHal_eJewel_Read: 1038 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = 0x00; 1039 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00; 1040 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 104; 1041 NdefMap->SendLength = 3; 1042 break; 1043 #endif 1044 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 1045 1046 default: 1047 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1048 NFCSTATUS_INVALID_DEVICE_REQUEST); 1049 } 1050 1051 if(Result == NFCSTATUS_SUCCESS) 1052 { 1053 /* Call the Overlapped HAL Transceive function */ 1054 Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, 1055 &NdefMap->MapCompletionInfo, 1056 NdefMap->psRemoteDevInfo, 1057 NdefMap->Cmd, 1058 &NdefMap->psDepAdditionalInfo, 1059 NdefMap->SendRecvBuf, 1060 NdefMap->SendLength, 1061 NdefMap->SendRecvBuf, 1062 NdefMap->SendRecvLength); 1063 } 1064 return Result; 1065 } 1066 1067 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap, 1068 uint16_t BlockNo, 1069 uint16_t ByteNo, 1070 uint8_t ByteVal 1071 ) 1072 { 1073 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1074 uint8_t index = 0; 1075 1076 1077 PHNFC_UNUSED_VARIABLE(ByteVal); 1078 /* set the data for additional data exchange*/ 1079 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0; 1080 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0; 1081 NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0; 1082 1083 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process; 1084 NdefMap->MapCompletionInfo.Context = NdefMap; 1085 1086 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; 1087 /* Command used to write 1 byte */ 1088 #ifdef TOPAZ_RAW_SUPPORT 1089 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 1090 #else 1091 #ifdef PH_HAL4_ENABLE 1092 NdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E; 1093 #else 1094 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelWriteErase1; 1095 #endif 1096 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 1097 1098 #ifdef TOPAZ_RAW_SUPPORT 1099 /*Copy command to Send Buffer*/ 1100 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_WRITE_1E; 1101 index ++; 1102 1103 /*Copy Address to Send Buffer*/ 1104 /* Calculate send length 1105 7 | 6 5 4 3 | 2 1 0 | 1106 | block no | byte no | 1107 */ 1108 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 1109 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + 1110 ByteNo); 1111 index ++; 1112 /*Copy Data byte to Send Buffer*/ 1113 NdefMap->SendRecvBuf[index] = ByteVal; 1114 index ++; 1115 1116 /*Copy UID of the tag to Send Buffer*/ 1117 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]), 1118 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid), 1119 TOPAZ_UID_LENGTH_FOR_READ_WRITE); 1120 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE); 1121 1122 /* Update the length of the command buffer*/ 1123 NdefMap->SendLength = index; 1124 1125 #else 1126 /* Depending on the jewel command, the send length is decided */ 1127 /* Calculate send length 1128 7 | 6 5 4 3 | 2 1 0 | 1129 | block no | byte no | 1130 */ 1131 NdefMap->SendRecvBuf[index] = 1132 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) + 1133 ByteNo); 1134 index ++; 1135 NdefMap->SendRecvBuf[index] = ByteVal; 1136 index ++; 1137 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL2; 1138 1139 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 1140 1141 /* Call the Overlapped HAL Transceive function */ 1142 Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, 1143 &NdefMap->MapCompletionInfo, 1144 NdefMap->psRemoteDevInfo, 1145 NdefMap->Cmd, 1146 &NdefMap->psDepAdditionalInfo, 1147 NdefMap->SendRecvBuf, 1148 NdefMap->SendLength, 1149 NdefMap->SendRecvBuf, 1150 NdefMap->SendRecvLength); 1151 1152 return Result; 1153 } 1154 1155 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap) 1156 { 1157 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1158 NFCSTATUS_INVALID_RECEIVE_LENGTH); 1159 1160 if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] & 1161 PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) && 1162 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL6)) 1163 { 1164 /* Copy UID to the context, Used when the READ ALL command is used */ 1165 (void)memcpy(NdefMap->TopazContainer.UID, 1166 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2], 1167 PH_FRINFC_TOPAZ_VAL4); 1168 1169 /* State has to be changed */ 1170 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL; 1171 /* Topaz command = READALL */ 1172 #ifdef TOPAZ_RAW_SUPPORT 1173 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw; 1174 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL; 1175 #else 1176 #ifdef PH_HAL4_ENABLE 1177 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll; 1178 #else 1179 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll; 1180 #endif 1181 #endif /* #ifdef TOPAZ_RAW_SUPPORT */ 1182 1183 /* Read all bytes from the card */ 1184 Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock, 1185 NdefMap->TopazContainer.ByteNumber); 1186 } 1187 1188 return Result; 1189 } 1190 1191 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap) 1192 { 1193 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1194 NFCSTATUS_INVALID_RECEIVE_LENGTH); 1195 int32_t memcompare = PH_FRINFC_TOPAZ_VAL0; 1196 1197 /* Compare the UID of READ ALL command with the stored UID */ 1198 #ifdef PH_HAL4_ENABLE 1199 if ((NdefMap->TopazContainer.UID[0] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2]) && 1200 (NdefMap->TopazContainer.UID[1] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 1]) && 1201 (NdefMap->TopazContainer.UID[2] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 2]) && 1202 (NdefMap->TopazContainer.UID[3] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 3])) 1203 { 1204 memcompare = PH_FRINFC_TOPAZ_VAL0; 1205 } 1206 else 1207 { 1208 memcompare = PH_FRINFC_TOPAZ_VAL1; 1209 } 1210 #else 1211 memcompare = memcmp(NdefMap->TopazContainer.UID, 1212 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2], 1213 PH_FRINFC_TOPAZ_VAL4); 1214 #endif /* #ifdef PH_HAL4_ENABLE */ 1215 1216 if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] & 1217 PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) && 1218 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_READALL_RESP) && 1219 (memcompare == PH_FRINFC_TOPAZ_VAL0)) 1220 { 1221 /* Copy 96 bytes from the read/write memory space */ 1222 (void)memcpy(NdefMap->TopazContainer.ReadBuffer, 1223 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL10], 1224 PH_FRINFC_TOPAZ_TOTAL_RWBYTES); 1225 1226 /* Check the lock bits and set the card state */ 1227 phFriNfc_Tpz_H_ChkLockBits(NdefMap); 1228 1229 Result = phFriNfc_Tpz_H_CallNxtOp(NdefMap); 1230 } 1231 return Result; 1232 } 1233 1234 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap) 1235 { 1236 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1237 NFCSTATUS_INVALID_RECEIVE_LENGTH); 1238 /* Depending on the operation (check, read or write ndef), process the 1239 read data */ 1240 switch(NdefMap->PrevOperation) 1241 { 1242 case PH_FRINFC_NDEFMAP_CHECK_OPE: 1243 /* Check the capabilty container values, according 1244 to the spec */ 1245 Result = phFriNfc_Tpz_H_ChkCCinChkNdef(NdefMap); 1246 1247 if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INVALID) 1248 { 1249 /* Check the spec version */ 1250 Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap, 1251 NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]); 1252 /* Check the CC header size: Only valid ones are 1253 0x0C for 96 bytes. */ 1254 if ((Result == NFCSTATUS_SUCCESS) && 1255 ( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] <= 1256 PH_FRINFC_TOPAZ_CC_BYTE2_MAX)) 1257 { 1258 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap); 1259 /* As there is possibility of either having or not having TLV in 1260 Topaz, no need to send the Actual status to the context*/ 1261 Result = NFCSTATUS_SUCCESS; 1262 } 1263 } 1264 else 1265 { 1266 Result = NFCSTATUS_SUCCESS; 1267 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED; 1268 NdefMap->CardMemSize = 1269 NdefMap->TopazContainer.RemainingSize = (uint16_t) 1270 /* 1271 4 is decremented from the max size because of the 4 CC bytes 1272 2 is decremented because of the NDEF TLV T and L byte 1273 to get the actual data size 1274 */ 1275 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4 - 1276 PH_FRINFC_TOPAZ_VAL2); 1277 } 1278 break; 1279 1280 case PH_FRINFC_NDEFMAP_READ_OPE: 1281 /* Check the capabilty container values, according 1282 to the spec */ 1283 Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap); 1284 1285 /* If success, find the ndef TLV */ 1286 Result = ((Result != NFCSTATUS_SUCCESS)? 1287 (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1288 NFCSTATUS_INVALID_FORMAT)): 1289 phFriNfc_Tpz_H_findNDEFTLV(NdefMap)); 1290 1291 if(Result == NFCSTATUS_SUCCESS) 1292 { 1293 NdefMap->TopazContainer.ByteNumber += PH_FRINFC_TOPAZ_VAL2; 1294 /* If success, copy the read bytes to the user buffer */ 1295 Result = phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap); 1296 } 1297 break; 1298 1299 case PH_FRINFC_NDEFMAP_WRITE_OPE: 1300 default: 1301 if((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE) || 1302 (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED)) 1303 { 1304 /* Check the capabilty container values, according 1305 to the spec */ 1306 Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap); 1307 if(Result == NFCSTATUS_SUCCESS) 1308 { 1309 /* Find the NDEF TLV */ 1310 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap); 1311 1312 /* Write the TLV */ 1313 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV; 1314 } 1315 else 1316 { 1317 NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4; 1318 NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1; 1319 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4; 1320 /* Write the TLV */ 1321 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE0; 1322 } 1323 /* Write CC bytes */ 1324 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap); 1325 } 1326 break; 1327 } 1328 return Result; 1329 } 1330 1331 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap) 1332 { 1333 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1334 NFCSTATUS_NO_NDEF_SUPPORT); 1335 1336 if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] == 1337 PH_FRINFC_TOPAZ_CC_BYTE0) 1338 { 1339 /* Check the spec version */ 1340 Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap, 1341 NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]); 1342 /* Check the CC header size: Only valid ones are 1343 0x0C for 96 bytes. */ 1344 Result = ((( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] > 1345 PH_FRINFC_TOPAZ_CC_BYTE2_MAX) || (Result != 1346 NFCSTATUS_SUCCESS))? 1347 (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1348 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED)): 1349 Result); 1350 1351 /* Get the read/write card memory size */ 1352 NdefMap->TopazContainer.RemainingSize = 1353 NdefMap->CardMemSize = ((Result == NFCSTATUS_SUCCESS)? 1354 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4): 1355 NdefMap->CardMemSize); 1356 1357 /* if the call is from write ndef then check for read write access */ 1358 if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) && 1359 (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] != 1360 PH_FRINFC_TOPAZ_CC_BYTE3_RW) && (Result == NFCSTATUS_SUCCESS))) 1361 { 1362 Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1363 NFCSTATUS_INVALID_FORMAT)); 1364 } 1365 1366 /* if the call is from read ndef then check for read only or read write access */ 1367 if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) && 1368 ((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] != 1369 PH_FRINFC_TOPAZ_CC_BYTE3_RW) && 1370 (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] != 1371 PH_FRINFC_TOPAZ_CC_BYTE3_RO))&& (Result == NFCSTATUS_SUCCESS))) 1372 { 1373 Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1374 NFCSTATUS_INVALID_FORMAT)); 1375 } 1376 } 1377 return Result; 1378 } 1379 1380 extern NFCSTATUS phFriNfc_Tpz_H_ChkSpcVer( phFriNfc_NdefMap_t *NdefMap, 1381 uint8_t VersionNo) 1382 { 1383 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1384 uint8_t TagVerNo = VersionNo; 1385 1386 /* To remove "warning (VS C4100) : unreferenced formal parameter" */ 1387 PHNFC_UNUSED_VARIABLE(NdefMap); 1388 1389 if ( TagVerNo == 0 ) 1390 { 1391 /*Return Status Error Invalid Format*/ 1392 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT); 1393 } 1394 else 1395 { 1396 /* calculate the major and minor version number of T3VerNo */ 1397 if( (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == 1398 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&& 1399 ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM >= 1400 PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo))) || 1401 (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM == 1402 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&& 1403 ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM < 1404 PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo) ))) 1405 { 1406 Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); 1407 } 1408 else 1409 { 1410 if (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM < 1411 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo) ) || 1412 ( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM > 1413 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo))) 1414 { 1415 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT); 1416 } 1417 } 1418 } 1419 return Result; 1420 } 1421 1422 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap) 1423 { 1424 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1425 NFCSTATUS_NO_NDEF_SUPPORT); 1426 uint8_t index = PH_FRINFC_TOPAZ_VAL4; 1427 1428 /* If remaining size is less than 3 then, there cant be any 1429 TLV present in the card */ 1430 while((index < PH_FRINFC_TOPAZ_TOTAL_RWBYTES) && 1431 (NdefMap->TopazContainer.RemainingSize >= PH_FRINFC_TOPAZ_VAL3)) 1432 { 1433 switch(NdefMap->TopazContainer.ReadBuffer[index]) 1434 { 1435 case PH_FRINFC_TOPAZ_NDEF_T: 1436 /* To get the length field of the TLV */ 1437 index++; 1438 /* Type and length are not data bytes, so to know the exact 1439 remaining size in the card, the below operation is done */ 1440 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2; 1441 /* Set the card state depending on the L value */ 1442 Result = phFriNfc_MapTool_SetCardState(NdefMap, 1443 (uint32_t)NdefMap->TopazContainer.ReadBuffer[index]); 1444 /* Check the TLV is correct */ 1445 if((NdefMap->TopazContainer.ReadBuffer[index] > 1446 NdefMap->TopazContainer.RemainingSize) || 1447 ((NdefMap->TopazContainer.ReadBuffer[index] == 1448 PH_FRINFC_TOPAZ_VAL0) && (NdefMap->PrevOperation == 1449 PH_FRINFC_NDEFMAP_READ_OPE)) || (Result != NFCSTATUS_SUCCESS)) 1450 { 1451 /* L field value cant be greater than the remaining size, so error */ 1452 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1453 NFCSTATUS_NO_NDEF_SUPPORT); 1454 /* To break out of the loop */ 1455 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES; 1456 } 1457 else 1458 { 1459 /* So remaining size also changes, according to the position of NDEF TLV */ 1460 NdefMap->TLVStruct.BytesRemainLinTLV = 1461 NdefMap->TopazContainer.ReadBuffer[index]; 1462 1463 /* Get the byte number */ 1464 NdefMap->TLVStruct.NdefTLVByte = (uint16_t)((index - PH_FRINFC_TOPAZ_VAL1) % 1465 PH_FRINFC_TOPAZ_VAL8); 1466 /* Get the block number */ 1467 NdefMap->TLVStruct.NdefTLVBlock = (uint8_t)(((index - PH_FRINFC_TOPAZ_VAL1) / 1468 PH_FRINFC_TOPAZ_VAL8) + 1469 PH_FRINFC_TOPAZ_VAL1); 1470 /* TLV found flag is set */ 1471 NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_TOPAZ_FLAG1; 1472 /* To know the position of V field in the TLV */ 1473 NdefMap->TopazContainer.ByteNumber = (uint8_t)(((NdefMap->TLVStruct.NdefTLVBlock - 1) * 8) + 1474 NdefMap->TLVStruct.NdefTLVByte); 1475 /* To break out of the loop */ 1476 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES; 1477 Result = NFCSTATUS_SUCCESS; 1478 } 1479 break; 1480 1481 case PH_FRINFC_TOPAZ_NULL_T: 1482 /* Null TLV, Skip the TLV */ 1483 NdefMap->TopazContainer.RemainingSize--; 1484 index++; 1485 break; 1486 1487 case PH_FRINFC_TOPAZ_TERM_T: 1488 /* No more TLV present in the card, so error */ 1489 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES; 1490 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1491 NFCSTATUS_NO_NDEF_SUPPORT); 1492 break; 1493 1494 default: 1495 /* Go till the length field of the TLV */ 1496 index++; 1497 /* Type and length is not the data, so to know the exact 1498 remaining size in the card, the below operation is done */ 1499 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2; 1500 if(NdefMap->TopazContainer.ReadBuffer[index] > 1501 NdefMap->TopazContainer.RemainingSize) 1502 { 1503 /* L field value cant be greater than the remaining size, so error */ 1504 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES; 1505 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1506 NFCSTATUS_NO_NDEF_SUPPORT); 1507 } 1508 else 1509 { 1510 /* Remaining size of the free space available in the card changes, 1511 according to the position of NDEF TLV */ 1512 NdefMap->TopazContainer.RemainingSize = 1513 NdefMap->TopazContainer.RemainingSize - 1514 NdefMap->TopazContainer.ReadBuffer[index]; 1515 1516 /* Get the position of the next TLV */ 1517 index = (uint8_t)(index + 1518 (NdefMap->TopazContainer.ReadBuffer[index] + 1519 PH_FRINFC_TOPAZ_VAL1)); 1520 } 1521 break; 1522 } 1523 } 1524 1525 /* If no Ndef TLV found and operation done is read */ 1526 if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) && 1527 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE)) 1528 { 1529 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1530 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 1531 } 1532 if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) && 1533 ((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) || 1534 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_CHECK_OPE))) 1535 { 1536 NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4; 1537 NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1; 1538 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4; 1539 NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_TOTAL_RWBYTES1; 1540 } 1541 return Result; 1542 } 1543 1544 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf(phFriNfc_NdefMap_t *NdefMap) 1545 { 1546 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1547 1548 /* Check the the TLV size and the user size */ 1549 if(NdefMap->ApduBufferSize >= 1550 NdefMap->TLVStruct.BytesRemainLinTLV) 1551 { 1552 /* Copy the read bytes to user buffer till the value (V) 1553 of TLV ends */ 1554 (void)memcpy(NdefMap->ApduBuffer, 1555 &(NdefMap->TopazContainer.ReadBuffer[ 1556 NdefMap->TopazContainer.ByteNumber]), 1557 NdefMap->TLVStruct.BytesRemainLinTLV); 1558 1559 /* Update the number of read bytes to the user */ 1560 *(NdefMap->NumOfBytesRead) = 1561 NdefMap->TLVStruct.BytesRemainLinTLV; 1562 /* There is no byte to read */ 1563 NdefMap->TopazContainer.ByteNumber = 1564 PH_FRINFC_TOPAZ_VAL0; 1565 /* No further read is possible */ 1566 NdefMap->TopazContainer.ReadWriteCompleteFlag = 1567 PH_FRINFC_TOPAZ_FLAG1; 1568 /* Remaining size in the card can be greater than length field in 1569 the TLV */ 1570 NdefMap->TopazContainer.RemainingSize = 1571 NdefMap->TopazContainer.RemainingSize - 1572 NdefMap->TLVStruct.BytesRemainLinTLV; 1573 /* TLV has been completely read, no more bytes to read */ 1574 NdefMap->TLVStruct.BytesRemainLinTLV = 1575 PH_FRINFC_TOPAZ_VAL0; 1576 } 1577 else 1578 { 1579 /* Copy read bytes till the user buffer size */ 1580 (void)memcpy(NdefMap->ApduBuffer, 1581 &(NdefMap->TopazContainer.ReadBuffer[ 1582 NdefMap->TopazContainer.ByteNumber]), 1583 NdefMap->ApduBufferSize); 1584 1585 /* Update the number of read bytes to the user */ 1586 *(NdefMap->NumOfBytesRead) = 1587 NdefMap->ApduBufferSize; 1588 /* Get the next byte number to read */ 1589 NdefMap->TopazContainer.ByteNumber = 1590 (uint8_t)(NdefMap->TopazContainer.ByteNumber + 1591 NdefMap->ApduBufferSize); 1592 /* Free space left in the card */ 1593 NdefMap->TopazContainer.RemainingSize 1594 = NdefMap->TopazContainer.RemainingSize 1595 - (uint16_t)NdefMap->ApduBufferSize; 1596 /* Bytes left in the TLV */ 1597 NdefMap->TLVStruct.BytesRemainLinTLV = 1598 NdefMap->TLVStruct.BytesRemainLinTLV - 1599 (uint16_t)NdefMap->ApduBufferSize; 1600 } 1601 return Result; 1602 } 1603 1604 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap) 1605 { 1606 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1607 NFCSTATUS_INVALID_RECEIVE_LENGTH); 1608 uint8_t BlockNo = PH_FRINFC_TOPAZ_VAL0, 1609 ByteNo = PH_FRINFC_TOPAZ_VAL0; 1610 1611 if((NdefMap->TopazContainer.InternalState == 1612 PH_FRINFC_TOPAZ_WR_NMN_0) && 1613 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1614 PH_FRINFC_TOPAZ_VAL0) && 1615 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1616 { 1617 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV; 1618 /* Get the L field of the TLV block */ 1619 BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) > 1620 PH_FRINFC_TOPAZ_VAL7)? 1621 (NdefMap->TLVStruct.NdefTLVBlock + PH_FRINFC_TOPAZ_VAL1): 1622 NdefMap->TLVStruct.NdefTLVBlock); 1623 /* Get the L byte */ 1624 ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) % 1625 PH_FRINFC_TOPAZ_VAL8); 1626 1627 1628 /* Here the NMN is written 0, so internal state is used */ 1629 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV_0; 1630 /* Write the length value = 0x00 , Write L field of TLV = 0 inside this*/ 1631 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo, 1632 PH_FRINFC_TOPAZ_VAL0); 1633 } 1634 else 1635 { 1636 if((NdefMap->TopazContainer.InternalState == 1637 PH_FRINFC_TOPAZ_WR_NMN_E1) && 1638 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1639 PH_FRINFC_TOPAZ_CC_BYTE0) && 1640 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1641 { 1642 /* Card state is initialised or invalid */ 1643 NdefMap->CardState = (uint8_t)((NdefMap->CardState == 1644 PH_NDEFMAP_CARD_STATE_INITIALIZED)? 1645 PH_NDEFMAP_CARD_STATE_READ_WRITE: 1646 NdefMap->CardState); 1647 /* update the length to the user */ 1648 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; 1649 Result = NFCSTATUS_SUCCESS; 1650 } 1651 } 1652 return Result; 1653 } 1654 1655 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap) 1656 { 1657 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1658 NFCSTATUS_INVALID_RECEIVE_LENGTH); 1659 if((NdefMap->TopazContainer.InternalState == 1660 PH_FRINFC_TOPAZ_WR_L_TLV_0) && 1661 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1662 PH_FRINFC_TOPAZ_VAL0) && 1663 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1664 { 1665 /* state is writing user data to the card */ 1666 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE; 1667 1668 NdefMap->TopazContainer.ByteNumber++; 1669 /* Check the byte number */ 1670 phFriNfc_Tpz_H_BlkChk(NdefMap); 1671 1672 /* Write data to the specified location */ 1673 /* Write the data to the card from the user buffer */ 1674 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, 1675 NdefMap->TopazContainer.CurrentBlock, 1676 NdefMap->TopazContainer.ByteNumber, 1677 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex] 1678 ); 1679 } 1680 else 1681 { 1682 if((NdefMap->TopazContainer.InternalState == 1683 PH_FRINFC_TOPAZ_WR_L_TLV) && 1684 (((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) && 1685 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1686 NdefMap->ApduBuffIndex)) || 1687 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && 1688 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1689 (NdefMap->ApduBuffIndex + NdefMap->TLVStruct.BytesRemainLinTLV)))) && 1690 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1691 { 1692 /* Update the L value in the context */ 1693 NdefMap->TLVStruct.BytesRemainLinTLV = 1694 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)? 1695 NdefMap->ApduBuffIndex: 1696 (NdefMap->TLVStruct.BytesRemainLinTLV + NdefMap->ApduBuffIndex)); 1697 1698 /* Write 0xE1 in block number = 1 and byte number = 0 */ 1699 Result = phFriNfc_Tpz_H_WrByte0ValE1(NdefMap); 1700 } 1701 } 1702 return Result; 1703 } 1704 1705 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData(phFriNfc_NdefMap_t *NdefMap) 1706 { 1707 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1708 NFCSTATUS_INVALID_RECEIVE_LENGTH); 1709 /* send buffer should be equal to receive buffer */ 1710 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1711 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]) && 1712 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1713 { 1714 /* Increment the index */ 1715 NdefMap->ApduBuffIndex += PH_FRINFC_TOPAZ_VAL1; 1716 1717 /* Remaining space left in the card is less by one */ 1718 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL1; 1719 1720 /* Increment the byte number */ 1721 NdefMap->TopazContainer.ByteNumber++; 1722 1723 /* Check the block number */ 1724 phFriNfc_Tpz_H_BlkChk(NdefMap); 1725 1726 /* check for the user space or the card size */ 1727 if((NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex) || 1728 (NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0)) 1729 { 1730 /* Set write complete, if the end of card is reached */ 1731 NdefMap->TopazContainer.ReadWriteCompleteFlag = (uint8_t) 1732 ((NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0)? 1733 PH_FRINFC_TOPAZ_FLAG1:PH_FRINFC_TOPAZ_FLAG0); 1734 1735 Result = phFriNfc_Tpz_H_WrLByte(NdefMap); 1736 } 1737 else 1738 { 1739 /* State is continued to be in write */ 1740 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE; 1741 1742 /* Write the byte to the specified location , and Byte to write */ 1743 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock, 1744 NdefMap->TopazContainer.ByteNumber, 1745 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex] 1746 ); 1747 } 1748 } 1749 return Result; 1750 } 1751 1752 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t *NdefMap) 1753 { 1754 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1755 uint8_t BlockNo = PH_FRINFC_TOPAZ_VAL0, 1756 ByteNo = PH_FRINFC_TOPAZ_VAL0; 1757 uint8_t TempByteVal = 0; 1758 BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte + 1759 PH_FRINFC_TOPAZ_VAL1) > 1760 PH_FRINFC_TOPAZ_VAL7)? 1761 (NdefMap->TLVStruct.NdefTLVBlock + 1762 PH_FRINFC_TOPAZ_VAL1): 1763 NdefMap->TLVStruct.NdefTLVBlock); 1764 1765 ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte + 1766 PH_FRINFC_TOPAZ_VAL1) % PH_FRINFC_TOPAZ_VAL8); 1767 /* Update L field */ 1768 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV; 1769 /* Internal state for write */ 1770 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV; 1771 /* Update the length field depending on the offset */ 1772 TempByteVal = (uint8_t) 1773 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)? 1774 NdefMap->ApduBuffIndex: 1775 (NdefMap->ApduBuffIndex + 1776 NdefMap->TLVStruct.BytesRemainLinTLV)); 1777 /* Write the L field */ 1778 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, BlockNo, ByteNo,TempByteVal); 1779 return Result; 1780 } 1781 1782 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t *NdefMap) 1783 { 1784 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1785 1786 /* Update L field */ 1787 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN; 1788 /* Internal state for writing 0xE1 */ 1789 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_E1; 1790 /* Update the length field depending on the offset */ 1791 /* Write the L field */ 1792 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, PH_FRINFC_TOPAZ_VAL1, 1793 PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_CC_BYTE0); 1794 return Result; 1795 } 1796 1797 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t *NdefMap, 1798 NFCSTATUS Status) 1799 { 1800 /* set the state back to the Reset_Init state*/ 1801 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; 1802 1803 /* set the completion routine*/ 1804 NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex]. 1805 CompletionRoutine(NdefMap->CompletionRoutine->Context, Status); 1806 } 1807 1808 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t *NdefMap) 1809 { 1810 NdefMap->TopazContainer.CurrentBlock = 1811 (uint8_t)((NdefMap->TopazContainer.ByteNumber > 1812 PH_FRINFC_TOPAZ_VAL7)? 1813 (NdefMap->TopazContainer.CurrentBlock + 1814 PH_FRINFC_TOPAZ_VAL1): 1815 NdefMap->TopazContainer.CurrentBlock); 1816 1817 NdefMap->TopazContainer.ByteNumber = (uint8_t)(NdefMap->TopazContainer.ByteNumber % 1818 PH_FRINFC_TOPAZ_VAL8); 1819 } 1820 1821 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t *NdefMap) 1822 { 1823 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1824 NFCSTATUS_NO_NDEF_SUPPORT); 1825 1826 if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] == 1827 PH_FRINFC_TOPAZ_CC_BYTE0) 1828 { 1829 /* Check the most significant nibble of byte 3 (RWA) = 0 */ 1830 Result = (((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] & 1831 PH_FRINFC_TOPAZ_BYTE3_MSB)== PH_FRINFC_TOPAZ_VAL0)? 1832 NFCSTATUS_SUCCESS: 1833 Result); 1834 1835 /* Card size is initialised */ 1836 NdefMap->CardMemSize = NdefMap->TopazContainer.RemainingSize = 1837 ((Result == NFCSTATUS_SUCCESS)? 1838 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4): 1839 NdefMap->CardMemSize); 1840 } 1841 1842 if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY) 1843 { 1844 NdefMap->CardState = (uint8_t)((Result == NFCSTATUS_SUCCESS)? 1845 PH_NDEFMAP_CARD_STATE_INITIALIZED: 1846 PH_NDEFMAP_CARD_STATE_INVALID); 1847 } 1848 1849 return Result; 1850 } 1851 1852 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t *NdefMap) 1853 { 1854 /* Set the card state */ 1855 NdefMap->CardState = (uint8_t) 1856 (((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_0] == 1857 PH_FRINFC_TOPAZ_LOCKBIT_BYTE114) && 1858 ((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] == 1859 PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_1) || 1860 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] == 1861 PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_2)))? 1862 PH_NDEFMAP_CARD_STATE_READ_WRITE: 1863 PH_NDEFMAP_CARD_STATE_READ_ONLY); 1864 1865 /* Set the card state from CC bytes */ 1866 if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE) 1867 { 1868 if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READWRITE) 1869 { 1870 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE; 1871 } 1872 else if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READONLY) 1873 { 1874 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; 1875 } 1876 else 1877 { 1878 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; 1879 } 1880 } 1881 } 1882 1883 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t *NdefMap) 1884 { 1885 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1886 uint8_t ByteNo = PH_FRINFC_TOPAZ_VAL0, 1887 BlockNo = PH_FRINFC_TOPAZ_VAL0; 1888 uint8_t TempByteVal = 0; 1889 switch(NdefMap->TopazContainer.InternalState) 1890 { 1891 case PH_FRINFC_TOPAZ_WR_CC_BYTE0: 1892 /* To write the CC bytes */ 1893 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE0; 1894 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL0; 1895 BlockNo = PH_FRINFC_TOPAZ_VAL1; 1896 break; 1897 1898 case PH_FRINFC_TOPAZ_WR_CC_BYTE1: 1899 /* To write the CC bytes */ 1900 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE1; 1901 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL1; 1902 BlockNo = PH_FRINFC_TOPAZ_VAL1; 1903 break; 1904 1905 case PH_FRINFC_TOPAZ_WR_CC_BYTE2: 1906 /* To write the CC bytes */ 1907 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE2_MAX; 1908 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL2; 1909 BlockNo = PH_FRINFC_TOPAZ_VAL1; 1910 break; 1911 1912 case PH_FRINFC_TOPAZ_WR_CC_BYTE3: 1913 /* To write the CC bytes */ 1914 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE3_RW; 1915 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL3; 1916 BlockNo = PH_FRINFC_TOPAZ_VAL1; 1917 break; 1918 1919 case PH_FRINFC_TOPAZ_WR_T_OF_TLV: 1920 default: 1921 /* To write the NDEF TLV (if not present) */ 1922 TempByteVal = PH_FRINFC_TOPAZ_NDEF_T; 1923 ByteNo = (uint8_t)NdefMap->TLVStruct.NdefTLVByte; 1924 BlockNo = NdefMap->TLVStruct.NdefTLVBlock; 1925 break; 1926 } 1927 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV; 1928 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,TempByteVal); 1929 return Result; 1930 } 1931 1932 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t *NdefMap) 1933 { 1934 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1935 NFCSTATUS_INVALID_RECEIVE_LENGTH); 1936 switch(NdefMap->TopazContainer.InternalState) 1937 { 1938 case PH_FRINFC_TOPAZ_WR_CC_BYTE0: 1939 /* Process the CC byte */ 1940 /* Check the response */ 1941 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1942 PH_FRINFC_TOPAZ_CC_BYTE0) && 1943 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1944 { 1945 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE1; 1946 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap); 1947 } 1948 break; 1949 1950 case PH_FRINFC_TOPAZ_WR_CC_BYTE1: 1951 /* Process the CC byte */ 1952 /* Check the response */ 1953 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1954 PH_FRINFC_TOPAZ_CC_BYTE1) && 1955 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1956 { 1957 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE2; 1958 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap); 1959 } 1960 break; 1961 1962 case PH_FRINFC_TOPAZ_WR_CC_BYTE2: 1963 /* Process the CC byte */ 1964 /* Check the response */ 1965 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1966 PH_FRINFC_TOPAZ_CC_BYTE2_MAX) && 1967 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1968 { 1969 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE3; 1970 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap); 1971 } 1972 break; 1973 1974 case PH_FRINFC_TOPAZ_WR_CC_BYTE3: 1975 /* Process the CC byte */ 1976 /* Check the response */ 1977 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1978 PH_FRINFC_TOPAZ_CC_BYTE3_RW) && 1979 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1980 { 1981 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV; 1982 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap); 1983 } 1984 break; 1985 1986 case PH_FRINFC_TOPAZ_WR_T_OF_TLV: 1987 default: 1988 /* Check the response */ 1989 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] == 1990 PH_FRINFC_TOPAZ_NDEF_T) && 1991 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1)) 1992 { 1993 /* Increment the Byte Number */ 1994 NdefMap->TopazContainer.ByteNumber++; 1995 /* Check the block and byte number */ 1996 phFriNfc_Tpz_H_BlkChk(NdefMap); 1997 /* Process the T of NDEF TLV */ 1998 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN; 1999 2000 /* Here the NMN is written 0, so internal state is used */ 2001 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_0; 2002 2003 /*Inside this call Write NMN (block number 1 and byte number 0) = 0 */ 2004 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, PH_FRINFC_TOPAZ_VAL1, 2005 PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_VAL0); 2006 } 2007 break; 2008 } 2009 return Result; 2010 } 2011 2012 #ifdef UNIT_TEST 2013 #include <phUnitTestNfc_Topaz_static.c> 2014 #endif 2015 2016 #endif /* PH_FRINFC_MAP_TOPAZ_DISABLED */ 2017