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_FelicaMap.c 19 * \brief This component encapsulates read/write/check ndef/process functionalities, 20 * for the Felica Smart Card. 21 * 22 * Project: NFC-FRI 23 * 24 * $Date: Thu May 6 14:01:35 2010 $ 25 * $Author: ing07385 $ 26 * $Revision: 1.10 $ 27 * $Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $ 28 * 29 */ 30 31 #ifndef PH_FRINFC_MAP_FELICA_DISABLED 32 33 #include <phNfcTypes.h> 34 #include <phFriNfc_OvrHal.h> 35 #include <phFriNfc_FelicaMap.h> 36 #include <phFriNfc_MapTools.h> 37 38 39 /*! \ingroup grp_file_attributes 40 * \name NDEF Mapping 41 * 42 * File: \ref phFriNfc_FelicaMap.c 43 * 44 */ 45 /*@{*/ 46 47 #define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.10 $" 48 #define PHFRINFCNDEFMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $" 49 50 /*@}*/ 51 52 /* Helpers for Read and updating the attribute informations*/ 53 static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap); 54 static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap); 55 static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer, 56 uint8_t StartIndex, 57 uint8_t EndIndex, 58 uint16_t RecvChkSum); 59 60 #ifndef PH_HAL4_ENABLE 61 /* Helpers for Poll Related Operations*/ 62 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap, 63 const uint8_t sysCode[], 64 uint8_t state); 65 #endif /* #ifndef PH_HAL4_ENABLE */ 66 67 68 static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap); 69 70 /*Helpers for Reading Operations*/ 71 static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset); 72 static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap,uint8_t NbcOrNmaxb ); 73 static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap); 74 static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset); 75 static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc); 76 static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap); 77 78 /* Helpers for Writing Operations*/ 79 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap); 80 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap, 81 uint32_t NdefLen); 82 static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted); 83 static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap); 84 static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap); 85 86 /* Write Empty NDEF Message*/ 87 static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap); 88 89 /*Helpers for common checks*/ 90 static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap); 91 static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap, 92 uint8_t CrIndex, 93 NFCSTATUS Status); 94 95 static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer); 96 97 static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n ); 98 99 /*! 100 * \brief returns maximum number of blocks can be read from the Felica Smart Card. 101 * 102 * The function is useful in reading of NDEF information from a felica tag. 103 */ 104 105 static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap, uint8_t NbcOrNmaxb ) 106 { 107 uint16_t BlksToRead=0; 108 uint32_t DataLen = 0; 109 /* This part of the code is useful if we take account of Nbc blks reading*/ 110 if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NBC ) 111 { 112 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], 113 NdefMap->FelicaAttrInfo.LenBytes[1], 114 NdefMap->FelicaAttrInfo.LenBytes[2], 115 DataLen); 116 /* Calculate Nbc*/ 117 BlksToRead = (uint16_t) ( ((DataLen % 16) == 0) ? (DataLen >> 4) : ((DataLen >> 4) +1) ); 118 119 120 } 121 else if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NMAXB) 122 { 123 BlksToRead = NdefMap->FelicaAttrInfo.Nmaxb; 124 } 125 else 126 { 127 /* WARNING !!! code should not reach this point*/ 128 ; 129 } 130 return (BlksToRead); 131 } 132 133 /*! 134 * \brief Initiates Reading of NDEF information from the Felica Card. 135 * 136 * The function initiates the reading of NDEF information from a Remote Device. 137 * It performs a reset of the state and starts the action (state machine). 138 * A periodic call of the \ref phFriNfcNdefMap_Process has to be 139 * done once the action has been triggered. 140 */ 141 142 NFCSTATUS phFriNfc_Felica_RdNdef( phFriNfc_NdefMap_t *NdefMap, 143 uint8_t *PacketData, 144 uint32_t *PacketDataLength, 145 uint8_t Offset) 146 { 147 148 NFCSTATUS status = NFCSTATUS_PENDING; 149 uint32_t Nbc = 0; 150 151 NdefMap->ApduBufferSize = *PacketDataLength; 152 /*Store the packet data buffer*/ 153 NdefMap->ApduBuffer = PacketData; 154 155 NdefMap->NumOfBytesRead = PacketDataLength ; 156 *NdefMap->NumOfBytesRead = 0; 157 NdefMap->ApduBuffIndex = 0; 158 159 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; 160 NdefMap->Felica.Offset = Offset; 161 162 if( ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )||( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) 163 { 164 NdefMap->Felica.CurBlockNo = 0; 165 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP; 166 NdefMap->Felica.IntermediateCpyFlag = FALSE; 167 NdefMap->Felica.IntermediateCpyLen = 0; 168 NdefMap->Felica.Rd_NoBytesToCopy = 0; 169 NdefMap->Felica.EofCardReachedFlag= FALSE ; 170 NdefMap->Felica.LastBlkReachedFlag = FALSE; 171 NdefMap->Felica.CurrBytesRead = 0; 172 173 phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Rd_BytesToCopyBuff); 174 175 /* send request to read attribute information*/ 176 status = phFriNfc_Felica_HRdAttrInfo(NdefMap); 177 /* handle the error in Transc function*/ 178 if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 179 { 180 /* call respective CR */ 181 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status); 182 } 183 } 184 else 185 { 186 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); 187 188 /* Offset = Current, but the read has reached the End of NBC Blocks */ 189 if(( ( Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && (NdefMap->Felica.CurBlockNo == Nbc)) && 190 (NdefMap->Felica.EofCardReachedFlag == FELICA_RD_WR_EOF_CARD_REACHED )) 191 { 192 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 193 } 194 else 195 { 196 197 NdefMap->Felica.CurrBytesRead = ((NdefMap->Felica.CurBlockNo * 16)- NdefMap->Felica.Rd_NoBytesToCopy); 198 status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset); 199 200 } 201 } 202 return (status); 203 } 204 205 /*Read Operation Related Helper Routines*/ 206 207 /*! 208 * \brief Used in Read Opearation.Sets the Trx Buffer Len calls Transc Cmd. 209 * After a successful read operation, function does checks the user buffer size 210 * sets the status flags. 211 */ 212 213 static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset) 214 { 215 NFCSTATUS status = NFCSTATUS_PENDING; 216 uint16_t Nbc=0,TranscLen=0; 217 218 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); 219 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0) && (NdefMap->Felica.CurBlockNo < Nbc )) 220 { 221 /* if data is present in the internal buffer*/ 222 if (NdefMap->Felica.Rd_NoBytesToCopy > 0 ) 223 { 224 /* copy data to external buffer*/ 225 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap); 226 /*Check the size of user buffer*/ 227 status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap); 228 if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE )) 229 { 230 /* set the transc len and call transc cmd*/ 231 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); 232 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset); 233 } 234 else 235 { 236 /* Nothing to be done , if IntermediateRdFlag is set to zero*/ 237 ; 238 } 239 } 240 else 241 { 242 /* set the transc len and call transc cmd*/ 243 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); 244 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset); 245 } 246 } 247 else 248 { 249 /* Chk the Buffer size*/ 250 status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap); 251 if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE )) 252 { 253 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); 254 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset); 255 } 256 } 257 return (status); 258 } 259 260 /*! 261 * \brief Used in Read Opearation.Sets the Trx Buffer Len. 262 */ 263 264 static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc) 265 { 266 uint16_t TranscLen = 0,BlocksToRead=0; 267 268 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)% 16) == 0) 269 { 270 BlocksToRead = (uint16_t)( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16 ); 271 } 272 else 273 { 274 BlocksToRead = (uint16_t)(((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16) +1); 275 } 276 if ( (BlocksToRead > Nbc) ||( (BlocksToRead) > ( Nbc - NdefMap->Felica.CurBlockNo)) ) 277 { 278 BlocksToRead = Nbc - NdefMap->Felica.CurBlockNo; 279 } 280 281 282 if ( BlocksToRead >= NdefMap->FelicaAttrInfo.Nbr) 283 { 284 if( NdefMap->FelicaAttrInfo.Nbr < Nbc ) 285 { 286 TranscLen = NdefMap->FelicaAttrInfo.Nbr*16; 287 } 288 else 289 { 290 TranscLen = Nbc*16; 291 NdefMap->Felica.LastBlkReachedFlag =1; 292 } 293 } 294 else 295 { 296 if (BlocksToRead <= Nbc ) 297 { 298 if ( ( BlocksToRead * 16) == ((Nbc *16) - (NdefMap->Felica.CurBlockNo * 16))) 299 { 300 NdefMap->Felica.LastBlkReachedFlag =1; 301 302 } 303 TranscLen = BlocksToRead*16; 304 305 } 306 else 307 { 308 TranscLen = Nbc*16; 309 } 310 } 311 /* As Cur Blk changes, to remember the exact len what we had set 312 in the begining of each read operation*/ 313 NdefMap->Felica.TrxLen = TranscLen; 314 return (TranscLen); 315 } 316 317 /*! 318 * \brief Used in Read Opearation.After a successful read operation, 319 * Copies the data to user buffer. 320 */ 321 322 static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap) 323 { 324 uint8_t ResetFlag = FALSE, ExtrBytesToCpy = FALSE; 325 uint16_t Nbc=0; 326 uint32_t DataLen=0; 327 328 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC ); 329 330 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], 331 NdefMap->FelicaAttrInfo.LenBytes[1], 332 NdefMap->FelicaAttrInfo.LenBytes[2], 333 DataLen); 334 /* Internal Buffer has some old read bytes to cpy to user buffer*/ 335 if( NdefMap->Felica.Rd_NoBytesToCopy > 0 ) 336 { 337 if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.Rd_NoBytesToCopy ) 338 { 339 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 340 341 if (NdefMap->Felica.IntermediateCpyFlag == TRUE ) 342 { 343 /*Copy data from the internal buffer to user buffer*/ 344 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 345 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])), 346 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); 347 348 349 350 /* Store number of bytes copied frm internal buffer to User Buffer */ 351 NdefMap->Felica.IntermediateCpyLen += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 352 NdefMap->Felica.IntermediateCpyFlag = 1; 353 354 /* check do we reach len bytes any chance*/ 355 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], 356 NdefMap->FelicaAttrInfo.LenBytes[1], 357 NdefMap->FelicaAttrInfo.LenBytes[2], 358 DataLen); 359 /* Internal buffer has zero bytes for copy operation*/ 360 if ( NdefMap->Felica.Rd_NoBytesToCopy == 0) 361 { 362 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED; 363 } 364 } 365 else 366 { 367 /*Copy data from the internal buffer to apdu buffer*/ 368 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 369 NdefMap->Felica.Rd_BytesToCopyBuff, 370 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); 371 } 372 NdefMap->ApduBuffIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 373 374 } 375 else if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.Rd_NoBytesToCopy ) 376 { 377 if ( NdefMap->Felica.IntermediateCpyFlag == TRUE ) 378 { 379 /*Copy data internal buff to apdubuffer*/ 380 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 381 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])), 382 NdefMap->Felica.Rd_NoBytesToCopy); 383 } 384 else 385 { 386 /*Copy data internal buff to apdubuffer*/ 387 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 388 NdefMap->Felica.Rd_BytesToCopyBuff, 389 NdefMap->Felica.Rd_NoBytesToCopy); 390 } 391 392 /*increment the index,internal buffer len*/ 393 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; 394 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBuffIndex); 395 396 /* To reset the parameters*/ 397 ResetFlag = TRUE; 398 } 399 else 400 { 401 /* Extra Bytes to Copy from internal buffer to external buffer*/ 402 if ( NdefMap->Felica.IntermediateCpyFlag == TRUE ) 403 { 404 /*Copy data internal buff to apdubuffer*/ 405 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 406 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])), 407 NdefMap->Felica.Rd_NoBytesToCopy); 408 } 409 else 410 { 411 /*Copy data internal buff to apdubuffer*/ 412 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 413 NdefMap->Felica.Rd_BytesToCopyBuff, 414 NdefMap->Felica.Rd_NoBytesToCopy); 415 } 416 /*increment the index*/ 417 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; 418 419 /* To reset the parameters*/ 420 ResetFlag = TRUE; 421 } 422 }/*End of Internal Buffer has some old read bytes to cpy to user buffer*/ 423 else 424 { 425 /* check if last block is reached*/ 426 if ( ((NdefMap->Felica.LastBlkReachedFlag == 1) && (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= 16)) ) 427 { 428 /* greater than 16 but less than the data len size*/ 429 if (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= DataLen) 430 { 431 NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen) - (NdefMap->Felica.CurrBytesRead + 432 NdefMap->ApduBuffIndex)); 433 434 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 435 (&(NdefMap->SendRecvBuf[13])), 436 NdefMap->Felica.CurrBytesRead); 437 438 NdefMap->ApduBuffIndex += NdefMap->Felica.CurrBytesRead; 439 if ( NdefMap->ApduBuffIndex == DataLen) 440 { 441 ResetFlag = TRUE; 442 } 443 } 444 else 445 { 446 /* need to check exact no. of bytes to copy to buffer*/ 447 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= NdefMap->Felica.TrxLen )|| 448 ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= DataLen )) 449 { 450 451 ExtrBytesToCpy = TRUE; 452 } 453 else 454 { 455 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - (DataLen))); 456 457 if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)) 458 { 459 /*Reduce already copied bytes from the internal buffer*/ 460 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 461 ExtrBytesToCpy = TRUE; 462 } 463 else 464 { 465 ExtrBytesToCpy = FALSE; 466 } 467 } 468 if ( ExtrBytesToCpy == TRUE ) 469 { 470 NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen)- (NdefMap->Felica.CurrBytesRead + 471 NdefMap->ApduBuffIndex)); 472 473 if(NdefMap->Felica.CurrBytesRead < 474 (uint16_t)(NdefMap->ApduBufferSize - 475 NdefMap->ApduBuffIndex)) 476 { 477 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 478 (&(NdefMap->SendRecvBuf[13])), 479 NdefMap->Felica.CurrBytesRead); 480 } 481 else 482 { 483 (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 484 (&( NdefMap->SendRecvBuf[13])), 485 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); 486 } 487 488 if ( NdefMap->Felica.LastBlkReachedFlag == 1 ) 489 { 490 NdefMap->Felica.Rd_NoBytesToCopy = 491 (uint8_t)((NdefMap->Felica.CurrBytesRead > 492 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))? 493 (NdefMap->Felica.CurrBytesRead - 494 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)): 495 0); 496 497 ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy == 0)?TRUE:FALSE); 498 499 } 500 else 501 { 502 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)( NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); 503 } 504 505 /* Copy remained bytes back into internal buffer*/ 506 (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff, 507 (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])), 508 NdefMap->Felica.Rd_NoBytesToCopy); 509 510 /* set the intermediate flag : This flag remembers that there are still X no. bytes remained in 511 Internal Buffer Ex: User has given only one byte buffer,needs to cpy one byte at a time*/ 512 NdefMap->Felica.IntermediateCpyFlag = TRUE; 513 514 NdefMap->ApduBuffIndex += ((NdefMap->Felica.CurrBytesRead < 515 (uint16_t)(NdefMap->ApduBufferSize - 516 NdefMap->ApduBuffIndex))? 517 NdefMap->Felica.CurrBytesRead: 518 (uint16_t)(NdefMap->ApduBufferSize - 519 NdefMap->ApduBuffIndex)); 520 } 521 else 522 { 523 /*Copy data from the internal buffer to user buffer*/ 524 (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 525 (&( NdefMap->SendRecvBuf[13])), 526 NdefMap->Felica.Rd_NoBytesToCopy); 527 528 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; 529 ResetFlag = TRUE; 530 531 } 532 } 533 534 } 535 else 536 { 537 if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.TrxLen ) 538 { 539 /* Calculate exactly remained bytes to copy to internal buffer and set it*/ 540 if ( NdefMap->Felica.LastBlkReachedFlag == 1) 541 { 542 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - DataLen)); 543 544 if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)) 545 { 546 /*Reduce already copied bytes from the internal buffer*/ 547 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 548 ExtrBytesToCpy = TRUE; 549 } 550 } 551 else 552 { 553 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); 554 ExtrBytesToCpy = TRUE; 555 } 556 if ( ExtrBytesToCpy == TRUE ) 557 { 558 /*Copy the read data from trx buffer to apdu of size apdu*/ 559 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 560 (&(NdefMap->SendRecvBuf[13])), 561 NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 562 563 /*copy bytesToCopy to internal buffer*/ 564 (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff, 565 (&(NdefMap->SendRecvBuf[13+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])), 566 NdefMap->Felica.Rd_NoBytesToCopy); 567 568 NdefMap->Felica.IntermediateCpyFlag = TRUE; 569 NdefMap->ApduBuffIndex += (uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex; 570 } 571 else 572 { 573 /*Copy data from the internal buffer to user buffer*/ 574 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 575 (&(NdefMap->SendRecvBuf[13])), 576 NdefMap->Felica.Rd_NoBytesToCopy); 577 578 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy; 579 ResetFlag = TRUE; 580 581 } 582 if ( DataLen <= (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) ) 583 { 584 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED; 585 } 586 else 587 { 588 ; 589 } 590 } 591 else if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.TrxLen ) 592 { 593 /*Copy exactly remained last bytes to user buffer and increment the index*/ 594 /*13 : 1+12 : 1st byte entire pkt length + 12 bytes to skip manuf details*/ 595 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 596 (&(NdefMap->SendRecvBuf[13])), 597 (NdefMap->Felica.TrxLen )); 598 599 NdefMap->ApduBuffIndex += NdefMap->Felica.TrxLen; 600 } 601 else 602 { 603 if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > NdefMap->Felica.TrxLen ) 604 { 605 /*Copy the data to apdu buffer and increment the index */ 606 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 607 (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN])), 608 NdefMap->Felica.TrxLen); 609 610 NdefMap->ApduBuffIndex += (uint16_t)NdefMap->Felica.TrxLen; 611 } 612 } 613 } 614 } 615 if ( ResetFlag == TRUE ) 616 { 617 /* reset the internal buffer variables*/ 618 NdefMap->Felica.Rd_NoBytesToCopy =0; 619 NdefMap->Felica.IntermediateCpyLen =0; 620 NdefMap->Felica.IntermediateCpyFlag =FALSE; 621 } 622 return; 623 } 624 625 626 /*! 627 * \brief Used in Read Opearation.After a successful read operation, 628 Checks the relavent buffer sizes and set the status.Following function is used 629 when we read the Nmaxb blocks. Retained for future purpose. 630 */ 631 632 static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap) 633 { 634 NFCSTATUS status = NFCSTATUS_PENDING; 635 uint8_t ResetFlag = FALSE; 636 uint32_t Nbc = 0; 637 638 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); 639 640 /* set status to Success : User Buffer is full and Curblk < nmaxb*/ 641 if ( (( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) && 642 (NdefMap->Felica.CurBlockNo < Nbc )) 643 { 644 status = PHNFCSTVAL(CID_NFC_NONE, 645 NFCSTATUS_SUCCESS); 646 /*Reset the index, internal buffer counters back to zero*/ 647 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; 648 NdefMap->ApduBuffIndex = 0; 649 650 }/*if( (NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb )*/ 651 else 652 { 653 if (( ( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) && 654 (NdefMap->Felica.CurBlockNo == Nbc )) 655 { 656 status = PHNFCSTVAL(CID_NFC_NONE, 657 NFCSTATUS_SUCCESS); 658 659 ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy > 0 )? 660 FALSE: 661 TRUE); 662 if( ResetFlag== FALSE) 663 { 664 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; 665 /*Reset the index, internal buffer counters back to zero*/ 666 NdefMap->ApduBuffIndex = 0; 667 } 668 }/*if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb )*/ 669 else 670 { 671 /* reached reading all the blks available in the card: set EOF flag*/ 672 if ( NdefMap->ApduBuffIndex == (Nbc*16)) 673 { 674 status = PHNFCSTVAL(CID_NFC_NONE, 675 NFCSTATUS_SUCCESS); 676 ResetFlag = TRUE; 677 } 678 else 679 { 680 if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )> 0 ) 681 { 682 if ( NdefMap->Felica.CurBlockNo == Nbc ) 683 { 684 /* bytes pending in internal buffer , No Space in User Buffer*/ 685 if ( NdefMap->Felica.Rd_NoBytesToCopy > 0) 686 { 687 if ( NdefMap->Felica.EofCardReachedFlag == TRUE ) 688 { 689 status = PHNFCSTVAL(CID_NFC_NONE, 690 NFCSTATUS_SUCCESS); 691 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; 692 NdefMap->ApduBuffIndex=0; 693 } 694 else 695 { 696 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap); 697 if( NdefMap->Felica.Rd_NoBytesToCopy > 0 ) 698 { 699 status = PHNFCSTVAL(CID_NFC_NONE, 700 NFCSTATUS_SUCCESS); 701 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; 702 NdefMap->ApduBuffIndex=0; 703 } 704 else 705 { 706 /* EOF Card Reached set the internal EOF Flag*/ 707 status = PHNFCSTVAL(CID_NFC_NONE, 708 NFCSTATUS_SUCCESS); 709 710 ResetFlag = TRUE; 711 } 712 } 713 } 714 /* All bytes from internal buffer are copied and set eof flag*/ 715 else 716 { 717 status = PHNFCSTVAL(CID_NFC_NONE, 718 NFCSTATUS_SUCCESS); 719 ResetFlag = TRUE; 720 } 721 } 722 else 723 { 724 /* This flag is set to ensure that, need of Read Opearation 725 we completed coying the data from internal buffer to external buffer 726 left some more bytes,in User bufer so initiate the read operation */ 727 NdefMap->Felica.IntermediateRdFlag = TRUE; 728 } 729 } 730 else 731 { 732 status = PHNFCSTVAL(CID_NFC_NONE, 733 NFCSTATUS_SUCCESS); 734 } 735 } 736 } 737 if ( ResetFlag == TRUE) 738 { 739 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex; 740 /*Reset the index, internal buffer counters back to zero*/ 741 NdefMap->ApduBuffIndex = 0; 742 NdefMap->Felica.Rd_NoBytesToCopy=0; 743 NdefMap->Felica.EofCardReachedFlag=FELICA_RD_WR_EOF_CARD_REACHED; 744 745 } 746 747 } 748 return( status); 749 } 750 751 /*! 752 * \brief Used in Read Opearation.Sets the transceive Command for read. 753 */ 754 static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset) 755 { 756 NFCSTATUS TrxStatus = NFCSTATUS_PENDING; 757 uint16_t BufIndex=0,i=0; 758 759 /* set the felica cmd */ 760 #ifdef PH_HAL4_ENABLE 761 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; 762 #else 763 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; 764 #endif /* #ifdef PH_HAL4_ENABLE */ 765 766 /*Change the state to Read */ 767 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK; 768 769 /* set the complition routines for the mifare operations */ 770 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process; 771 NdefMap->MapCompletionInfo.Context = NdefMap; 772 773 /*set the additional informations for the data exchange*/ 774 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 775 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; 776 777 /* pkt len : updated at the end*/ 778 NdefMap->SendRecvBuf[BufIndex] = 0x00; 779 BufIndex ++; 780 781 NdefMap->SendRecvBuf[BufIndex] = 0x06; 782 BufIndex++; 783 784 /* IDm - Manufacturer Id : 8bytes*/ 785 #ifdef PH_HAL4_ENABLE 786 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 787 (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), 788 8); 789 #else 790 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 791 (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), 792 8); 793 #endif /* #ifdef PH_HAL4_ENABLE */ 794 795 BufIndex+=8; 796 797 /*Number of Services (n=1 ==> 0x80)*/ 798 NdefMap->SendRecvBuf[BufIndex] = 0x01; 799 BufIndex++; 800 801 /*Service Code List*/ 802 NdefMap->SendRecvBuf[BufIndex] = 0x0B; 803 BufIndex++; 804 805 NdefMap->SendRecvBuf[BufIndex] = 0x00; 806 BufIndex++; 807 808 /*Number of Blocks to read*/ 809 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TrxLen/16); 810 BufIndex++; 811 /* Set the Blk numbers as per the offset set by the user : Block List*/ 812 if ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN ) 813 { 814 for ( i=0;i<(TrxLen/16);i++) 815 { 816 /*1st Service Code list : byte 1*/ 817 NdefMap->SendRecvBuf[BufIndex] = 0x80; 818 BufIndex++; 819 820 /* No. Of Blocks*/ 821 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(i + 1); 822 BufIndex++; 823 } 824 } 825 else 826 { 827 for ( i= 1;i<=(TrxLen/16);i++) 828 { 829 /*1st Service Code list : byte 1*/ 830 NdefMap->SendRecvBuf[BufIndex] = 0x80; 831 BufIndex++; 832 833 /* No. Of Blocks*/ 834 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(NdefMap->Felica.CurBlockNo + i); 835 BufIndex++; 836 } 837 } 838 839 /* len of entire pkt*/ 840 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = (uint8_t) BufIndex; 841 842 /* Set the Pkt Len*/ 843 NdefMap->SendLength = BufIndex; 844 845 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; 846 847 TrxStatus = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice, 848 &NdefMap->MapCompletionInfo, 849 NdefMap->psRemoteDevInfo, 850 NdefMap->Cmd, 851 &NdefMap->psDepAdditionalInfo, 852 NdefMap->SendRecvBuf, 853 NdefMap->SendLength, 854 NdefMap->SendRecvBuf, 855 NdefMap->SendRecvLength); 856 return (TrxStatus); 857 } 858 859 /*! 860 * \brief Initiates Writing of NDEF information to the Remote Device. 861 * 862 * The function initiates the writing of NDEF information to a Remote Device. 863 * It performs a reset of the state and starts the action (state machine). 864 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action 865 * has been triggered. 866 */ 867 868 NFCSTATUS phFriNfc_Felica_WrNdef( phFriNfc_NdefMap_t *NdefMap, 869 uint8_t *PacketData, 870 uint32_t *PacketDataLength, 871 uint8_t Offset) 872 { 873 874 NFCSTATUS status = NFCSTATUS_PENDING; 875 876 NdefMap->ApduBufferSize = *PacketDataLength; 877 /*Store the packet data buffer*/ 878 NdefMap->ApduBuffer = PacketData; 879 880 /* To Update the Acutal written bytes to context*/ 881 NdefMap->WrNdefPacketLength = PacketDataLength; 882 *NdefMap->WrNdefPacketLength = 0; 883 884 885 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; 886 NdefMap->Felica.Offset = Offset; 887 888 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP; 889 status = phFriNfc_Felica_HRdAttrInfo(NdefMap); 890 /* handle the error in Transc function*/ 891 if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 892 { 893 /* call respective CR */ 894 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status); 895 } 896 return (status); 897 } 898 899 /*! 900 * \brief Initiates Writing of Empty NDEF information to the Remote Device. 901 * 902 * The function initiates the writing empty of NDEF information to a Remote Device. 903 * It performs a reset of the state and starts the action (state machine). 904 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action 905 * has been triggered. 906 */ 907 908 NFCSTATUS phFriNfc_Felica_EraseNdef( phFriNfc_NdefMap_t *NdefMap) 909 { 910 911 NFCSTATUS status = NFCSTATUS_PENDING; 912 static uint32_t PktDtLength =0; 913 914 if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID ) 915 { 916 /* Card is in invalid state, cannot have any read/write 917 operations*/ 918 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 919 NFCSTATUS_INVALID_FORMAT); 920 } 921 else if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY ) 922 { 923 /*Can't write to the card :No Grants */ 924 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 925 NFCSTATUS_WRITE_FAILED); 926 /* set the no. bytes written is zero*/ 927 NdefMap->WrNdefPacketLength = &PktDtLength; 928 *NdefMap->WrNdefPacketLength = 0; 929 } 930 else 931 { 932 933 /* set the Operation*/ 934 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP; 935 936 status = phFriNfc_Felica_HRdAttrInfo(NdefMap); 937 } 938 return (status); 939 } 940 941 942 /*! 943 * \brief Used in Write Opearation. 944 * check the value set for the Write Flag, in first write operation(begin), sets the 945 * WR flag in attribute blck. 946 * After a successful write operation, This function sets the WR flag off and updates 947 * the LEN bytes in attribute Block. 948 */ 949 950 static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted) 951 { 952 NFCSTATUS status = NFCSTATUS_PENDING; 953 954 uint16_t ChkSum=0,index=0; 955 uint8_t BufIndex=0, ErrFlag = FALSE; 956 uint32_t TotNoWrittenBytes=0; 957 958 /* Write Operation : Begin/End Check*/ 959 960 NdefMap->State = 961 (( isStarted == FELICA_WRITE_STARTED )? 962 PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN: 963 PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END); 964 965 if( ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN)|| 966 ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END) ) 967 { 968 969 /* Set the Felica Cmd*/ 970 #ifdef PH_HAL4_ENABLE 971 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; 972 #else 973 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; 974 #endif /* #ifdef PH_HAL4_ENABLE */ 975 976 /* 1st byte represents the length of the cmd packet*/ 977 NdefMap->SendRecvBuf[BufIndex] = 0x00; 978 BufIndex++; 979 980 /* Write/Update command code*/ 981 NdefMap->SendRecvBuf[BufIndex] = 0x08; 982 BufIndex++; 983 984 /* IDm - Manufacturer Id : 8bytes*/ 985 #ifdef PH_HAL4_ENABLE 986 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 987 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), 988 8); 989 #else 990 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 991 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), 992 8); 993 #endif /* #ifdef PH_HAL4_ENABLE */ 994 995 BufIndex+=8; 996 997 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ 998 BufIndex++; 999 1000 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/ 1001 BufIndex++; 1002 1003 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ 1004 BufIndex++; 1005 1006 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/ 1007 BufIndex++; 1008 1009 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/ 1010 BufIndex++; 1011 1012 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/ 1013 BufIndex++; 1014 1015 /* Fill Attribute Blk Information*/ 1016 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version; 1017 BufIndex++; 1018 1019 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr; 1020 BufIndex++; 1021 1022 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw; 1023 BufIndex++; 1024 1025 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8); 1026 BufIndex++; 1027 1028 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff)); 1029 BufIndex++; 1030 1031 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1032 BufIndex++; 1033 1034 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1035 BufIndex++; 1036 1037 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1038 BufIndex++; 1039 1040 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1041 BufIndex++; 1042 1043 if (isStarted == FELICA_WRITE_STARTED ) 1044 { 1045 NdefMap->SendRecvBuf[BufIndex] = 0x0F; /* Write Flag Made On*/ 1046 BufIndex++; 1047 1048 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/ 1049 BufIndex++; 1050 1051 /* Len Bytes*/ 1052 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[0]; 1053 BufIndex++; 1054 1055 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[1]; 1056 BufIndex++; 1057 1058 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[2]; 1059 BufIndex++; 1060 } 1061 else 1062 { 1063 /* Case: Previous Write Operation failed and integration context continues with write 1064 operation with offset set to Current. In this case, if we find Internal Bytes remained in the 1065 felica context is true(>0) and current block number is Zero. Then we shouldn't allow the module 1066 to write the data to card, as this is a invalid case*/ 1067 if ( (NdefMap->Felica.Wr_BytesRemained > 0) && (NdefMap->Felica.CurBlockNo == 0)) 1068 { 1069 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1070 NFCSTATUS_INVALID_PARAMETER); 1071 ErrFlag = TRUE; 1072 } 1073 else 1074 { 1075 1076 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Write Flag Made Off*/ 1077 BufIndex++; 1078 1079 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/ 1080 BufIndex++; 1081 1082 if ( NdefMap->Felica.Wr_BytesRemained > 0 ) 1083 { 1084 TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained))); 1085 } 1086 else 1087 { 1088 TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16); 1089 1090 } 1091 1092 /* Update Len Bytes*/ 1093 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(( TotNoWrittenBytes & 0x00ff0000) >> 16); 1094 BufIndex++; 1095 1096 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((TotNoWrittenBytes & 0x0000ff00) >> 8); 1097 BufIndex++; 1098 1099 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TotNoWrittenBytes & 0x000000ff); 1100 BufIndex++; 1101 } 1102 } 1103 1104 if ( ErrFlag != TRUE ) 1105 { 1106 /* check sum update*/ 1107 for ( index = 16 ; index < 30 ; index ++) 1108 { 1109 ChkSum += NdefMap->SendRecvBuf[index]; 1110 } 1111 1112 /* fill check sum in command pkt*/ 1113 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8); 1114 BufIndex++; 1115 1116 NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff); 1117 BufIndex++; 1118 1119 /* update length of the cmd pkt*/ 1120 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; 1121 1122 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; 1123 1124 /* Update the Send Len*/ 1125 NdefMap->SendLength = BufIndex; 1126 1127 /*set the completion routines for the desfire card operations*/ 1128 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process; 1129 NdefMap->MapCompletionInfo.Context = NdefMap; 1130 1131 /*set the additional informations for the data exchange*/ 1132 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 1133 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; 1134 1135 /*Call the Overlapped HAL Transceive function */ 1136 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, 1137 &NdefMap->MapCompletionInfo, 1138 NdefMap->psRemoteDevInfo, 1139 NdefMap->Cmd, 1140 &NdefMap->psDepAdditionalInfo, 1141 NdefMap->SendRecvBuf, 1142 NdefMap->SendLength, 1143 NdefMap->SendRecvBuf, 1144 NdefMap->SendRecvLength); 1145 } 1146 } 1147 else 1148 { 1149 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1150 NFCSTATUS_INVALID_PARAMETER); 1151 1152 } 1153 return (status); 1154 } 1155 1156 static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap) 1157 { 1158 NFCSTATUS status = NFCSTATUS_PENDING; 1159 1160 uint16_t ChkSum=0,index=0; 1161 uint8_t BufIndex=0; 1162 1163 /* Write Operation : To Erase the present NDEF Data*/ 1164 1165 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG; 1166 1167 /* Set the Felica Cmd*/ 1168 #ifdef PH_HAL4_ENABLE 1169 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; 1170 #else 1171 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; 1172 #endif /* #ifdef PH_HAL4_ENABLE */ 1173 1174 /* 1st byte represents the length of the cmd packet*/ 1175 NdefMap->SendRecvBuf[BufIndex] = 0x00; 1176 BufIndex++; 1177 1178 /* Write/Update command code*/ 1179 NdefMap->SendRecvBuf[BufIndex] = 0x08; 1180 BufIndex++; 1181 1182 /* IDm - Manufacturer Id : 8bytes*/ 1183 #ifdef PH_HAL4_ENABLE 1184 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 1185 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), 1186 8); 1187 #else 1188 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 1189 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), 1190 8); 1191 #endif /* #ifdef PH_HAL4_ENABLE */ 1192 1193 1194 BufIndex+=8; 1195 1196 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ 1197 BufIndex++; 1198 1199 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/ 1200 BufIndex++; 1201 1202 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ 1203 BufIndex++; 1204 1205 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/ 1206 BufIndex++; 1207 1208 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/ 1209 BufIndex++; 1210 1211 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/ 1212 BufIndex++; 1213 1214 /* Fill Attribute Blk Information*/ 1215 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version; 1216 BufIndex++; 1217 1218 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr; 1219 BufIndex++; 1220 1221 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw; 1222 BufIndex++; 1223 1224 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8); 1225 BufIndex++; 1226 1227 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff)); 1228 BufIndex++; 1229 1230 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1231 BufIndex++; 1232 1233 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1234 BufIndex++; 1235 1236 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1237 BufIndex++; 1238 1239 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/ 1240 BufIndex++; 1241 1242 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.WriteFlag; 1243 BufIndex++; 1244 1245 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/ 1246 BufIndex++; 1247 1248 /* Len Bytes are set to 0 : Empty Msg*/ 1249 NdefMap->SendRecvBuf[BufIndex] = 0x00; 1250 BufIndex++; 1251 1252 NdefMap->SendRecvBuf[BufIndex] = 0x00; 1253 BufIndex++; 1254 1255 NdefMap->SendRecvBuf[BufIndex] = 0x00; 1256 BufIndex++; 1257 1258 /* check sum update*/ 1259 for ( index = 16 ; index < 30 ; index ++) 1260 { 1261 ChkSum += NdefMap->SendRecvBuf[index]; 1262 } 1263 1264 /* fill check sum in command pkt*/ 1265 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8); 1266 BufIndex++; 1267 1268 NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff); 1269 BufIndex++; 1270 1271 /* update length of the cmd pkt*/ 1272 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; 1273 1274 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; 1275 1276 /* Update the Send Len*/ 1277 NdefMap->SendLength = BufIndex; 1278 1279 /*set the completion routines for the desfire card operations*/ 1280 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process; 1281 NdefMap->MapCompletionInfo.Context = NdefMap; 1282 1283 /*set the additional informations for the data exchange*/ 1284 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 1285 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; 1286 1287 /*Call the Overlapped HAL Transceive function */ 1288 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, 1289 &NdefMap->MapCompletionInfo, 1290 NdefMap->psRemoteDevInfo, 1291 NdefMap->Cmd, 1292 &NdefMap->psDepAdditionalInfo, 1293 NdefMap->SendRecvBuf, 1294 NdefMap->SendLength, 1295 NdefMap->SendRecvBuf, 1296 NdefMap->SendRecvLength); 1297 1298 return (status); 1299 } 1300 1301 1302 1303 1304 /*! 1305 * \brief Used in Write Opearation. 1306 * This Function is called after a successful validation and storing of attribution block 1307 * content in to context. 1308 * If the write operation is initiated with begin,function initiates the write operation with 1309 * RdWr flag. 1310 * If the Offset is set to Current, Checks for the EOF card reached status and writes data to 1311 * The Card 1312 */ 1313 1314 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap) 1315 { 1316 NFCSTATUS status = NFCSTATUS_PENDING; 1317 uint32_t DataLen=0; 1318 1319 /*check RW Flag Access Rights*/ 1320 /* set to read only cannot write*/ 1321 if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00) 1322 1323 { 1324 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1325 NFCSTATUS_INVALID_DEVICE_REQUEST); 1326 } 1327 else 1328 { 1329 if ( ( NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || 1330 ( ( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) && 1331 (NdefMap->Felica.Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN ) )) 1332 { 1333 /* check allready written number of bytes and apdu buffer size*/ 1334 if (NdefMap->ApduBufferSize > (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16)) 1335 { 1336 NdefMap->Felica.EofCardReachedFlag = FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET; 1337 } 1338 else 1339 { 1340 NdefMap->Felica.EofCardReachedFlag = FALSE; 1341 } 1342 1343 1344 /* reset the internal variables initiate toupdate the attribute blk*/ 1345 NdefMap->Felica.Wr_BytesRemained = 0; 1346 NdefMap->Felica.CurBlockNo = 0; 1347 NdefMap->Felica.NoBlocksWritten = 0; 1348 phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Wr_RemainedBytesBuff); 1349 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED); 1350 1351 } 1352 else 1353 { 1354 if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR ) 1355 { 1356 /* Calculate the Allready Written No. Of Blocks*/ 1357 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], 1358 NdefMap->FelicaAttrInfo.LenBytes[1], 1359 NdefMap->FelicaAttrInfo.LenBytes[2], 1360 DataLen); 1361 1362 if (( NdefMap->ApduBufferSize + (DataLen )) > 1363 (uint32_t)( NdefMap->FelicaAttrInfo.Nmaxb *16)) 1364 { 1365 if(( DataLen ) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16) ) 1366 { 1367 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1368 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 1369 } 1370 else 1371 { 1372 1373 NdefMap->Felica.EofCardReachedFlag =FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET; 1374 NdefMap->ApduBuffIndex =0; 1375 NdefMap->Felica.NoBlocksWritten = 0; 1376 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED); 1377 } 1378 } 1379 else 1380 { 1381 NdefMap->ApduBuffIndex =0; 1382 NdefMap->Felica.NoBlocksWritten = 0; 1383 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED); 1384 } 1385 }/*if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )*/ 1386 } 1387 } 1388 return (status); 1389 } 1390 1391 /*! 1392 * \brief Used in Read Opearation. 1393 * This Function is called after a successful validation and storing of attribution block 1394 * content in to context. 1395 * While Offset is set to Current, Checks for the EOF card reached status and reads data from 1396 * The Card 1397 */ 1398 1399 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap, 1400 uint32_t NdefLen) 1401 { 1402 NFCSTATUS status = NFCSTATUS_PENDING; 1403 1404 /*check WR Flag Access Rights*/ 1405 /* set to still writing data state only cannot Read*/ 1406 if ( NdefMap->FelicaAttrInfo.WriteFlag == 0x0F ) 1407 { 1408 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_READ_FAILED); 1409 /* As we are not able to continue with reading data 1410 bytes read set to zero*/ 1411 *NdefMap->NumOfBytesRead = 0; 1412 } 1413 else 1414 { 1415 status = phFriNfc_MapTool_SetCardState( NdefMap,NdefLen); 1416 if ( status == NFCSTATUS_SUCCESS) 1417 { 1418 /* Read data From the card*/ 1419 status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset); 1420 } 1421 } 1422 1423 return (status); 1424 } 1425 1426 /*! 1427 * \brief Used in Write Opearation. 1428 * This function writes the data in terms of blocks. 1429 * Each write operation supports,minimum Nbw blocks of bytes. 1430 * Also checks for the EOF,>=NBW,<NBW etc 1431 */ 1432 static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap) 1433 { 1434 NFCSTATUS status = NFCSTATUS_PENDING; 1435 1436 uint8_t BufIndex=0, 1437 i=0, 1438 BlkNo=0, 1439 PadBytes=0, 1440 CurBlk=1, 1441 NoOfBlks=0, 1442 NbwCheck=0, 1443 TotNoBlks=0; 1444 1445 uint32_t BytesRemainedInCard=0, 1446 BytesRemained=0, 1447 TotNoWrittenBytes=0; 1448 1449 if( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0 ) 1450 { 1451 /* Prepare the write cmd pkt for felica*/ 1452 /* 1st byte represents the length of the cmd packet*/ 1453 NdefMap->SendRecvBuf[BufIndex] = 0x00; 1454 BufIndex++; 1455 1456 /* Write/Update command code*/ 1457 NdefMap->SendRecvBuf[BufIndex] = 0x08; 1458 BufIndex++; 1459 1460 /* IDm - Manufacturer Id : 8bytes*/ 1461 #ifdef PH_HAL4_ENABLE 1462 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 1463 (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)), 1464 8); 1465 #else 1466 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 1467 (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)), 1468 8); 1469 #endif /* #ifdef PH_HAL4_ENABLE */ 1470 1471 BufIndex+=8; 1472 1473 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ 1474 BufIndex++; 1475 1476 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/ 1477 BufIndex++; 1478 1479 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ 1480 BufIndex++; 1481 1482 if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET) 1483 { 1484 /* check for the eof card reached flag.Need to write only mamximum bytes(memory)to card. 1485 Used when, offset set to begin case*/ 1486 BytesRemainedInCard= ( (NdefMap->FelicaAttrInfo.Nmaxb*16) - (NdefMap->Felica.CurBlockNo * 16)); 1487 } 1488 else 1489 { 1490 /* Offset : Cuurent*/ 1491 if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET ) 1492 { 1493 /* caculate previously written Ndef blks*/ 1494 (void)phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); 1495 1496 if ( NdefMap->Felica.Wr_BytesRemained ) 1497 { 1498 TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained))); 1499 } 1500 else 1501 { 1502 TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16); 1503 } 1504 /* Determine exactly, how many bytes we can write*/ 1505 BytesRemainedInCard = (NdefMap->FelicaAttrInfo.Nmaxb*16 - (TotNoWrittenBytes)); 1506 } 1507 1508 } 1509 /* Write Data Pending in the Internal Buffer*/ 1510 if(NdefMap->Felica.Wr_BytesRemained > 0) 1511 { 1512 /* update the number of blocks to write with the block list elements*/ 1513 /* Total Number of blocks to write*/ 1514 NdefMap->SendRecvBuf[BufIndex] = 0; 1515 BufIndex++; 1516 1517 /* Update this Total no. Bloks later*/ 1518 NoOfBlks = BufIndex; 1519 1520 /* As we are writing atleast one block*/ 1521 TotNoBlks = 1; 1522 1523 /* check do we have some extra bytes to write? in User Buffer*/ 1524 if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained)) 1525 { 1526 /* Have we reached EOF?*/ 1527 if ( NdefMap->Felica.EofCardReachedFlag ) 1528 { 1529 BytesRemained = BytesRemainedInCard; 1530 } 1531 else 1532 { 1533 /* This value tells how many extra bytes we can write other than internal buffer bytes*/ 1534 BytesRemained = (uint8_t)NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained); 1535 } 1536 1537 if ( BytesRemained ) 1538 { 1539 /* Not reached EOF*/ 1540 if (!NdefMap->Felica.EofCardReachedFlag) 1541 { 1542 /* Calculate How many blks we need to write*/ 1543 BlkNo =((uint8_t)( BytesRemained )/16); 1544 1545 /* check blocks to write exceeds nbw*/ 1546 if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw ) 1547 { 1548 BlkNo = NdefMap->FelicaAttrInfo.Nbw; 1549 /* No. Blks to write are more than Nbw*/ 1550 NbwCheck = 1; 1551 } 1552 else 1553 { 1554 if ((( BytesRemained %16) == 0)&& (BlkNo == 0 )) 1555 { 1556 BlkNo=1; 1557 } 1558 } 1559 /* check do we need pad bytes?*/ 1560 if( (!NbwCheck && (uint8_t)( BytesRemained)%16) != 0) 1561 { 1562 BlkNo++; 1563 PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained); 1564 NdefMap->Felica.PadByteFlag = TRUE; 1565 NdefMap->Felica.NoBlocksWritten = BlkNo; 1566 TotNoBlks += BlkNo; 1567 1568 } 1569 else 1570 { 1571 if ( NbwCheck ) 1572 { 1573 /* as we have to write only 8 blocks and already we have pad bytes so we have 1574 to strat from previous block*/ 1575 TotNoBlks += BlkNo - 1; 1576 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1; 1577 } 1578 else 1579 { 1580 if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 )) 1581 { 1582 TotNoBlks += BlkNo; 1583 } 1584 else 1585 { 1586 1587 } 1588 if ( NdefMap->Felica.PadByteFlag ) 1589 { 1590 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1; 1591 1592 } 1593 } 1594 } 1595 } 1596 else 1597 { 1598 /* we have reached the eof card & hv bytes to write*/ 1599 BlkNo =(uint8_t)(( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained)) )/16); 1600 1601 /* check are we exceeding the NBW limit, while a write?*/ 1602 if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw ) 1603 { 1604 BlkNo = NdefMap->FelicaAttrInfo.Nbw; 1605 1606 /* No. Blks to write are more than Nbw*/ 1607 NbwCheck = 1; 1608 1609 } 1610 else 1611 { 1612 if ((( BytesRemained %16) == 0)&& (BlkNo == 0 )) 1613 { 1614 BlkNo=1; 1615 } 1616 } 1617 1618 /*check Total how many blocks to write*/ 1619 if(((!NbwCheck) &&( BytesRemained- (16 - NdefMap->Felica.Wr_BytesRemained))%16) != 0) 1620 { 1621 BlkNo++; 1622 PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained); 1623 NdefMap->Felica.PadByteFlag = TRUE; 1624 NdefMap->Felica.NoBlocksWritten = BlkNo; 1625 TotNoBlks += BlkNo; 1626 1627 } 1628 else 1629 { 1630 if ( NbwCheck ) 1631 { 1632 /* as we have to write only 8 blocks and already we have pad bytes so we have 1633 to strat from previous last block*/ 1634 TotNoBlks += BlkNo - 1; 1635 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1; 1636 } 1637 else 1638 { 1639 /* we need to write only one block ( bytesremanind + internal buffer size = 16)*/ 1640 if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 )) 1641 { 1642 TotNoBlks += BlkNo; 1643 } 1644 else 1645 { 1646 ;/* we are not incrementing the Total no. of blocks to write*/ 1647 } 1648 1649 if ( NdefMap->Felica.PadByteFlag ) 1650 { 1651 NdefMap->Felica.NoBlocksWritten = TotNoBlks -1; 1652 1653 } 1654 } 1655 } 1656 } 1657 }/*if ( BytesRemained )*/ 1658 else 1659 { 1660 ; /*Nothing to process here*/ 1661 } 1662 }/*if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))*/ 1663 else 1664 { 1665 /* No new blks to write*/ 1666 NdefMap->Felica.NoBlocksWritten = 0; 1667 } 1668 /* Prepare the Blk List for Write Operation*/ 1669 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ 1670 for ( i=0; i< TotNoBlks; i++) 1671 { 1672 NdefMap->SendRecvBuf[BufIndex] = 0x80; 1673 BufIndex++; 1674 /* remember the previous Blk no and continue from there*/ 1675 if ( NdefMap->Felica.PadByteFlag == TRUE ) 1676 { 1677 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i; 1678 BufIndex++; 1679 } 1680 else 1681 { 1682 CurBlk = NdefMap->Felica.CurBlockNo +1; 1683 NdefMap->SendRecvBuf[BufIndex] = CurBlk + i; 1684 BufIndex++; 1685 } 1686 } 1687 /* Copy relevant data to Transc buffer*/ 1688 if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained)) 1689 { 1690 1691 /*Copy the Remained bytes from the internal buffer to trxbuffer */ 1692 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 1693 NdefMap->Felica.Wr_RemainedBytesBuff, 1694 NdefMap->Felica.Wr_BytesRemained); 1695 1696 /*Increment the buff index*/ 1697 BufIndex += NdefMap->Felica.Wr_BytesRemained; 1698 1699 1700 /*append copy 16-bytesToPad to trxBuffer*/ 1701 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 1702 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 1703 (16 - NdefMap->Felica.Wr_BytesRemained)); 1704 1705 /* Update Number Of Bytes Writtened*/ 1706 NdefMap->NumOfBytesWritten = 16 - NdefMap->Felica.Wr_BytesRemained; 1707 1708 /* increment the index*/ 1709 BufIndex += 16 - NdefMap->Felica.Wr_BytesRemained; 1710 1711 if ( BytesRemained ) 1712 { 1713 if (!NdefMap->Felica.EofCardReachedFlag) 1714 { 1715 /* check nbw limit*/ 1716 if ( NbwCheck != 1 ) 1717 { 1718 /* Copy Extra Bytes other than the internal buffer bytes*/ 1719 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 1720 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), 1721 (NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained))); 1722 1723 1724 /* Update Number Of Bytes Writtened*/ 1725 NdefMap->NumOfBytesWritten += (uint16_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained)); 1726 1727 BufIndex += (uint8_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained)); 1728 1729 if ( PadBytes ) 1730 { 1731 for(i= 0; i< PadBytes; i++) 1732 { 1733 NdefMap->SendRecvBuf[BufIndex] =0x00; 1734 BufIndex++; 1735 } 1736 /* no of bytes remained copy*/ 1737 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes); 1738 1739 /*copy the data to internal buffer : Bytes remained*/ 1740 (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff, 1741 (&( NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])), 1742 ( NdefMap->Felica.Wr_BytesRemained)); 1743 } 1744 else 1745 { 1746 /* No Bytes in Internal buffer*/ 1747 NdefMap->Felica.Wr_BytesRemained = 0; 1748 } 1749 1750 } 1751 else 1752 { 1753 1754 /*Copy Nbw*16 bytes of data to the trx buffer*/ 1755 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 1756 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), 1757 (NdefMap->FelicaAttrInfo.Nbw - 1) * 16); 1758 1759 /* increment the Buffindex*/ 1760 BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16); 1761 1762 NdefMap->Felica.Wr_BytesRemained = 0; 1763 NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16); 1764 NdefMap->Felica.PadByteFlag =FALSE; 1765 } 1766 }/*if (!NdefMap->Felica.EofCardReachedFlag)*/ 1767 else 1768 { 1769 /* check nbw limit*/ 1770 if ( NbwCheck != 1 ) 1771 { 1772 /* handle EOF card reached case*/ 1773 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])), 1774 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), 1775 ( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained) ))); 1776 1777 /* Update Number Of Bytes Writtened*/ 1778 NdefMap->NumOfBytesWritten += (uint16_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)); 1779 1780 BufIndex += (uint8_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)); 1781 1782 if ( PadBytes ) 1783 { 1784 for(i= 0; i< PadBytes; i++) 1785 { 1786 NdefMap->SendRecvBuf[BufIndex] =0x00; 1787 BufIndex++; 1788 } 1789 1790 /*no of bytes remained copy*/ 1791 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes); 1792 1793 /*copy the data to internal buffer : Bytes remained*/ 1794 (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff, 1795 (&(NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])), 1796 (NdefMap->Felica.Wr_BytesRemained)); 1797 1798 } 1799 else 1800 { 1801 NdefMap->Felica.Wr_BytesRemained = 0; 1802 } 1803 } 1804 else 1805 { 1806 1807 /*Copy Nbw*16 bytes of data to the trx buffer*/ 1808 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 1809 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])), 1810 (NdefMap->FelicaAttrInfo.Nbw - 1) * 16); 1811 1812 /* increment the Buffindex*/ 1813 BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16); 1814 1815 NdefMap->Felica.Wr_BytesRemained = 0; 1816 NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16); 1817 1818 NdefMap->Felica.PadByteFlag =FALSE; 1819 } 1820 } 1821 }/*if ( BytesRemained )*/ 1822 else 1823 { 1824 NdefMap->Felica.Wr_BytesRemained = 0; 1825 } 1826 /* Update Total No. of blocks writtened*/ 1827 NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks; 1828 }/*if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained))*/ 1829 else 1830 { 1831 /*copy the internal buffer data to trx buffer*/ 1832 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 1833 NdefMap->Felica.Wr_RemainedBytesBuff, 1834 (NdefMap->Felica.Wr_BytesRemained)); 1835 1836 /* increment the index*/ 1837 BufIndex+=NdefMap->Felica.Wr_BytesRemained; 1838 1839 /*append the apdusize data to the trx buffer*/ 1840 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 1841 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 1842 NdefMap->ApduBufferSize); 1843 1844 /* Index increment*/ 1845 BufIndex+= (uint8_t)NdefMap->ApduBufferSize; 1846 1847 /* Tells how many bytes present in the internal buffer*/ 1848 BytesRemained = NdefMap->Felica.Wr_BytesRemained + NdefMap->ApduBufferSize; 1849 1850 PadBytes = (uint8_t)(16-BytesRemained); 1851 1852 /* Pad empty bytes with Zeroes to complete 16 bytes*/ 1853 for(i= 0; i< PadBytes; i++) 1854 { 1855 NdefMap->SendRecvBuf[BufIndex] =0x00; 1856 BufIndex++; 1857 } 1858 1859 /* Update Number Of Bytes Writtened*/ 1860 NdefMap->NumOfBytesWritten = (uint16_t)NdefMap->ApduBufferSize; 1861 1862 /* Flag set to understand that , we have received less no. of bytes than 1863 present in the internal buffer*/ 1864 NdefMap->Felica.IntermediateWrFlag = TRUE; 1865 1866 if ( NdefMap->Felica.PadByteFlag ) 1867 { 1868 NdefMap->Felica.NoBlocksWritten = 0; 1869 } 1870 } 1871 1872 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; 1873 NdefMap->SendLength = BufIndex; 1874 /* Update Total No. of blocks writtened*/ 1875 NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks; 1876 } 1877 else 1878 { 1879 /*Fresh write, starting from a new block*/ 1880 if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) 1881 { 1882 /* check for the card size and write Nbw Blks*/ 1883 if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw) 1884 { 1885 /* update the number of blocks to write with the block list elements*/ 1886 /* Total Number of blocks to write*/ 1887 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw; 1888 BufIndex++; 1889 1890 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ 1891 for ( i=1; i<= NdefMap->FelicaAttrInfo.Nbw; i++) 1892 { 1893 NdefMap->SendRecvBuf[BufIndex] = 0x80; 1894 BufIndex++; 1895 1896 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i; 1897 BufIndex++; 1898 } 1899 /*Copy Nbw*16 bytes of data to the trx buffer*/ 1900 1901 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 1902 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 1903 NdefMap->FelicaAttrInfo.Nbw * 16); 1904 1905 /* increment the Buffindex*/ 1906 BufIndex += (NdefMap->FelicaAttrInfo.Nbw*16); 1907 1908 /* update the length*/ 1909 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; 1910 1911 NdefMap->Felica.Wr_BytesRemained = 0; 1912 NdefMap->NumOfBytesWritten = (NdefMap->FelicaAttrInfo.Nbw*16); 1913 NdefMap->Felica.NoBlocksWritten = NdefMap->FelicaAttrInfo.Nbw; 1914 1915 /* update the Send length*/ 1916 NdefMap->SendLength = BufIndex; 1917 1918 NdefMap->Felica.PadByteFlag = FALSE; 1919 }/*if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)*/ 1920 else 1921 { 1922 /* we need to write less than nbw blks*/ 1923 /* update the number of blocks to write with the block list elements*/ 1924 /* Total Number of blocks to write*/ 1925 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); 1926 BufIndex++; 1927 1928 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ 1929 for ( i=1; i<= (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); i++) 1930 { 1931 NdefMap->SendRecvBuf[BufIndex] = 0x80; 1932 BufIndex++; 1933 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i; 1934 BufIndex++; 1935 } 1936 1937 /*Copy Nbw*16 bytes of data to the trx buffer*/ 1938 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 1939 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 1940 (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16); 1941 1942 /* increment the Buffindex*/ 1943 BufIndex += (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo )*16); 1944 1945 /* update the length*/ 1946 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; 1947 1948 NdefMap->NumOfBytesWritten = ((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16); 1949 NdefMap->Felica.NoBlocksWritten = (uint8_t)(NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); 1950 1951 /* update the Send length*/ 1952 NdefMap->SendLength = BufIndex; 1953 1954 NdefMap->Felica.PadByteFlag =FALSE; 1955 NdefMap->Felica.Wr_BytesRemained = 0; 1956 } 1957 }/* if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */ 1958 else 1959 { 1960 /*chk eof reached*/ 1961 if ( NdefMap->Felica.EofCardReachedFlag) 1962 { 1963 BlkNo =((uint8_t)(BytesRemainedInCard )/16); 1964 if(((uint8_t)( BytesRemainedInCard )%16) != 0) 1965 { 1966 BlkNo++; 1967 PadBytes = ((BlkNo * 16) - (uint8_t)(BytesRemainedInCard )); 1968 NdefMap->Felica.PadByteFlag = TRUE; 1969 } 1970 } 1971 else 1972 { 1973 1974 BlkNo =((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16); 1975 if(((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)%16) != 0) 1976 { 1977 BlkNo++; 1978 PadBytes = (BlkNo * 16) - (uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 1979 NdefMap->Felica.PadByteFlag = TRUE; 1980 1981 } 1982 1983 1984 } 1985 1986 /* update the number of blocks to write with the block list elements*/ 1987 /* Total Number of blocks to write*/ 1988 NdefMap->SendRecvBuf[BufIndex] = BlkNo; 1989 BufIndex++; 1990 1991 NdefMap->Felica.NoBlocksWritten = BlkNo; 1992 1993 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/ 1994 for ( i=0; i< BlkNo; i++) 1995 { 1996 NdefMap->SendRecvBuf[BufIndex] = 0x80; 1997 BufIndex++; 1998 { 1999 CurBlk = NdefMap->Felica.CurBlockNo +1; 2000 NdefMap->SendRecvBuf[BufIndex] = CurBlk + i; 2001 BufIndex++; 2002 } 2003 } 2004 if ( NdefMap->Felica.EofCardReachedFlag ) 2005 { 2006 /*Copy last data to the trx buffer*/ 2007 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 2008 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 2009 BytesRemainedInCard ); 2010 2011 /* increment the bufindex and bytes written*/ 2012 BufIndex += (uint8_t )BytesRemainedInCard ; 2013 NdefMap->NumOfBytesWritten = (uint16_t)BytesRemainedInCard ; 2014 } 2015 else 2016 { 2017 /*Copy data to the trx buffer*/ 2018 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 2019 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])), 2020 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)); 2021 2022 /* increment the bufindex and bytes written*/ 2023 BufIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 2024 NdefMap->NumOfBytesWritten = (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 2025 } 2026 if ( PadBytes ) 2027 { 2028 for(i= 0; i< PadBytes; i++) 2029 { 2030 NdefMap->SendRecvBuf[BufIndex] =0x00; 2031 BufIndex++; 2032 } 2033 /*no of bytes remained copy*/ 2034 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes); 2035 2036 if ( NdefMap->Felica.EofCardReachedFlag ) 2037 { 2038 /*copy the data to internal buffer : Bytes remained*/ 2039 (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff, 2040 (&(NdefMap->ApduBuffer[((BytesRemainedInCard - (BytesRemainedInCard % 16)))])), 2041 ( NdefMap->Felica.Wr_BytesRemained)); 2042 2043 } 2044 else 2045 { 2046 /*copy the data to internal buffer : Bytes remained*/ 2047 (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff, 2048 (&(NdefMap->ApduBuffer[((NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained))])), 2049 ( NdefMap->Felica.Wr_BytesRemained)); 2050 2051 } 2052 }/*if ( PadBytes )*/ 2053 else 2054 { 2055 NdefMap->Felica.Wr_BytesRemained = 0; 2056 NdefMap->Felica.PadByteFlag = FALSE; 2057 } 2058 /* update the pkt len*/ 2059 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; 2060 NdefMap->SendLength = BufIndex; 2061 } 2062 }/* else of if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */ 2063 status = phFriNfc_Felica_HWriteDataBlk(NdefMap); 2064 } 2065 else 2066 { 2067 /*0 represents the write operation ended*/ 2068 status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED); 2069 } 2070 return (status); 2071 } 2072 2073 2074 /*! 2075 * \brief Used in Write Opearation. 2076 * This function prepares and sends transcc Cmd Pkt. 2077 */ 2078 2079 static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap) 2080 { 2081 NFCSTATUS status = NFCSTATUS_PENDING; 2082 2083 /*set the additional informations for the data exchange*/ 2084 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 2085 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; 2086 2087 /*Set the ISO14434 command*/ 2088 #ifdef PH_HAL4_ENABLE 2089 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; 2090 #else 2091 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; 2092 #endif /* #ifdef PH_HAL4_ENABLE */ 2093 2094 /* set the state*/ 2095 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK; 2096 2097 /* set send receive length*/ 2098 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; 2099 2100 /*Call the Overlapped HAL Transceive function */ 2101 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, 2102 &NdefMap->MapCompletionInfo, 2103 NdefMap->psRemoteDevInfo, 2104 NdefMap->Cmd, 2105 &NdefMap->psDepAdditionalInfo, 2106 NdefMap->SendRecvBuf, 2107 NdefMap->SendLength, 2108 NdefMap->SendRecvBuf, 2109 NdefMap->SendRecvLength); 2110 return (status); 2111 } 2112 2113 /*! 2114 * \brief Check whether a particular Remote Device is NDEF compliant. 2115 * The function checks whether the peer device is NDEF compliant. 2116 */ 2117 2118 NFCSTATUS phFriNfc_Felica_ChkNdef( phFriNfc_NdefMap_t *NdefMap) 2119 { 2120 NFCSTATUS status = NFCSTATUS_PENDING; 2121 2122 #ifndef PH_HAL4_ENABLE 2123 uint8_t sysCode[2]; 2124 #endif /* #ifndef PH_HAL4_ENABLE */ 2125 2126 #ifdef PH_HAL4_ENABLE 2127 2128 /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/ 2129 status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap); 2130 2131 if (status == NFCSTATUS_SUCCESS) 2132 { 2133 2134 /* set the operation type to Check ndef type*/ 2135 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP; 2136 status = phFriNfc_Felica_HRdAttrInfo(NdefMap); 2137 } 2138 #else 2139 2140 /* set the system code for selecting the wild card*/ 2141 sysCode[0] = 0x12; 2142 sysCode[1] = 0xFC; 2143 2144 status = phFriNfc_Felica_HPollCard( NdefMap,sysCode,PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP); 2145 #endif /* #ifdef PH_HAL4_ENABLE */ 2146 2147 return (status); 2148 2149 } 2150 /*! 2151 * \brief Check whether a particular Remote Device is NDEF compliant. 2152 * selects the wild card and then NFC Forum Reference Applications 2153 */ 2154 2155 #ifndef PH_HAL4_ENABLE 2156 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap, 2157 const uint8_t sysCode[], 2158 uint8_t state) 2159 { 2160 NFCSTATUS status = NFCSTATUS_PENDING; 2161 2162 /*Format the Poll Packet for selecting the wild card "0xff 0xff as system code*/ 2163 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[0] = 0x00; 2164 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[1] = sysCode[0]; 2165 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[2] = sysCode[1]; 2166 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[3] = 0x01; 2167 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[4] = 0x03; 2168 2169 /* set the length to zero*/ 2170 NdefMap->FelicaPollDetails.DevInputParam->GeneralByteLength =0x00; 2171 2172 NdefMap->NoOfDevices = PH_FRINFC_NDEFMAP_FELI_NUM_DEVICE_TO_DETECT; 2173 2174 /*set the completion routines for the felica card operations*/ 2175 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process; 2176 NdefMap->MapCompletionInfo.Context = NdefMap; 2177 2178 /*Set Ndef State*/ 2179 NdefMap->State = state; 2180 2181 /* Harsha: This is a special case for felica. 2182 Make a copy of the remote device information and send it for 2183 polling. Return the original remote device information to the 2184 caller. The user does not need the updated results of the poll 2185 that we are going to call now. This is only used for checking 2186 whether the felica card is NDEF compliant or not. */ 2187 (void) memcpy( &NdefMap->FelicaPollDetails.psTempRemoteDevInfo, 2188 NdefMap->psRemoteDevInfo, 2189 sizeof(phHal_sRemoteDevInformation_t)); 2190 2191 /* Reset the session opened flag */ 2192 NdefMap->FelicaPollDetails.psTempRemoteDevInfo.SessionOpened = 0x00; 2193 2194 /*Call the Overlapped HAL POLL function */ 2195 status = phFriNfc_OvrHal_Poll( NdefMap->LowerDevice, 2196 &NdefMap->MapCompletionInfo, 2197 NdefMap->OpModeType, 2198 &NdefMap->FelicaPollDetails.psTempRemoteDevInfo, 2199 &NdefMap->NoOfDevices, 2200 NdefMap->FelicaPollDetails.DevInputParam); 2201 2202 return (status); 2203 } 2204 #endif /* #ifndef PH_HAL4_ENABLE */ 2205 /*! 2206 * \brief Checks validity of system code sent from the lower device, during poll operation. 2207 */ 2208 2209 static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap) 2210 { 2211 NFCSTATUS status = NFCSTATUS_PENDING; 2212 2213 #ifdef PH_HAL4_ENABLE 2214 /* copy the IDm and PMm in Manufacture Details Structure*/ 2215 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID), 2216 (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm, 2217 8); 2218 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter), 2219 (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm, 2220 8); 2221 status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); 2222 #else 2223 2224 2225 /* Check the System Code for 0x12,0xFC*/ 2226 if( (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCodeAvailable == 1) 2227 && (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCode[0] == 0x12) 2228 && (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCode[1] == 0xFC)) 2229 { 2230 2231 /* copy the IDm and PMm in Manufacture Details Structure*/ 2232 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID), 2233 (uint8_t *)NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t, 2234 8); 2235 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter), 2236 (uint8_t *)NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.PMm, 2237 8); 2238 2239 2240 status = PHNFCSTVAL(CID_NFC_NONE, 2241 NFCSTATUS_SUCCESS); 2242 2243 } 2244 else 2245 { 2246 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 2247 NFCSTATUS_NO_NDEF_SUPPORT); 2248 } 2249 #endif /* #ifdef PH_HAL4_ENABLE */ 2250 2251 return (status); 2252 2253 } 2254 2255 2256 2257 /*! 2258 * \brief Completion Routine, Processing function, needed to avoid long blocking. 2259 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion 2260 * Routine in order to be able to notify the component that an I/O has finished and data are 2261 * ready to be processed. 2262 */ 2263 2264 void phFriNfc_Felica_Process(void *Context, 2265 NFCSTATUS Status) 2266 { 2267 uint8_t CRFlag = FALSE; 2268 uint16_t RecvTxLen = 0, 2269 BytesToRecv = 0, 2270 Nbc = 0; 2271 uint32_t TotNoWrittenBytes = 0, 2272 NDEFLen=0; 2273 2274 /*Set the context to Map Module*/ 2275 phFriNfc_NdefMap_t *NdefMap = (phFriNfc_NdefMap_t *)Context; 2276 2277 if ( Status == NFCSTATUS_SUCCESS ) 2278 { 2279 switch (NdefMap->State) 2280 { 2281 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP: 2282 2283 /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/ 2284 Status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap); 2285 2286 if (Status == NFCSTATUS_SUCCESS) 2287 { 2288 /* Mantis ID : 645*/ 2289 /* set the operation type to Check ndef type*/ 2290 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP; 2291 Status = phFriNfc_Felica_HRdAttrInfo(NdefMap); 2292 /* handle the error in Transc function*/ 2293 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2294 { 2295 CRFlag = TRUE; 2296 } 2297 } 2298 else 2299 { 2300 CRFlag = TRUE; 2301 } 2302 if ( CRFlag == TRUE ) 2303 { 2304 /* call respective CR */ 2305 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status); 2306 2307 } 2308 break; 2309 2310 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR: 2311 /* check for the status flag1 and status flag2for the successful read operation*/ 2312 if ( NdefMap->SendRecvBuf[10] == 0x00) 2313 { 2314 /* check the Manuf Id in the receive buffer*/ 2315 Status = phFriNfc_Felica_HCheckManufId(NdefMap); 2316 if ( Status == NFCSTATUS_SUCCESS) 2317 { 2318 /* Update the Attribute Information in to the context structure*/ 2319 Status = phFriNfc_Felica_HUpdateAttrInfo(NdefMap); 2320 if ( Status == NFCSTATUS_SUCCESS ) 2321 { 2322 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], 2323 NdefMap->FelicaAttrInfo.LenBytes[1], 2324 NdefMap->FelicaAttrInfo.LenBytes[2], 2325 NDEFLen); 2326 2327 if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP ) 2328 { 2329 /* Proceed With Write Functinality*/ 2330 Status = phFriNfc_Felica_HChkAttrBlkForWrOp(NdefMap); 2331 /* handle the error in Transc function*/ 2332 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2333 { 2334 /* call respective CR */ 2335 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2336 } 2337 } 2338 else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP ) 2339 { 2340 /* Proceed With Read Functinality*/ 2341 Status = phFriNfc_Felica_HChkAttrBlkForRdOp(NdefMap,NDEFLen); 2342 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2343 { 2344 /* call respective CR */ 2345 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status); 2346 } 2347 } 2348 else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP ) 2349 { 2350 2351 Status = phFriNfc_MapTool_SetCardState( NdefMap, 2352 NDEFLen); 2353 /* check status value*/ 2354 NdefMap->CardType = PH_FRINFC_NDEFMAP_FELICA_SMART_CARD; 2355 /*reset the buffer index*/ 2356 NdefMap->ApduBuffIndex = 0; 2357 /* set the Next operation Flag to indicate need of reading attribute information*/ 2358 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_OP_NONE; 2359 /* call respective CR */ 2360 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status); 2361 } 2362 else if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP ) 2363 { 2364 /* Proceed With Write Functinality*/ 2365 Status = phFriNfc_Felica_HWrEmptyMsg(NdefMap); 2366 /* handle the error in Transc function*/ 2367 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2368 { 2369 /* call respective CR */ 2370 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_ERASE_NDEF,Status); 2371 } 2372 } 2373 else 2374 { 2375 2376 /* invalid operation occured*/ 2377 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 2378 NFCSTATUS_INVALID_DEVICE_REQUEST); 2379 CRFlag =TRUE ; 2380 } 2381 } 2382 else 2383 { 2384 CRFlag =TRUE ; 2385 } 2386 } 2387 else 2388 { 2389 CRFlag =TRUE ; 2390 } 2391 } 2392 else 2393 { 2394 CRFlag =TRUE; 2395 /*handle the Error case*/ 2396 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 2397 NFCSTATUS_READ_FAILED); 2398 } 2399 if ( CRFlag == TRUE ) 2400 { 2401 /* call respective CR */ 2402 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status); 2403 } 2404 break; 2405 2406 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN: 2407 /* chk the status flags 1 and 2*/ 2408 if ( NdefMap->SendRecvBuf[10] == 0x00 ) 2409 { 2410 /* Update Data Call*/ 2411 Status =phFriNfc_Felica_HUpdateData(NdefMap); 2412 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2413 { 2414 /* call respective CR */ 2415 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2416 } 2417 } 2418 else 2419 { 2420 /*handle the Error case*/ 2421 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 2422 NFCSTATUS_WRITE_FAILED); 2423 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2424 2425 } 2426 break; 2427 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END: 2428 2429 /* chk the status flags 1 and 2*/ 2430 if ( NdefMap->SendRecvBuf[10] == 0x00) 2431 { 2432 /* Entire Write Operation is complete*/ 2433 Status = PHNFCSTVAL(CID_NFC_NONE,\ 2434 NFCSTATUS_SUCCESS); 2435 } 2436 else 2437 { 2438 /*handle the Error case*/ 2439 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 2440 NFCSTATUS_WRITE_FAILED); 2441 } 2442 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2443 break; 2444 2445 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG : 2446 2447 /* chk the status flags 1 and 2*/ 2448 if ( NdefMap->SendRecvBuf[10] == 0x00) 2449 { 2450 /* Entire Write Operation is complete*/ 2451 Status = PHNFCSTVAL(CID_NFC_NONE,\ 2452 NFCSTATUS_SUCCESS); 2453 } 2454 else 2455 { 2456 /*handle the Error case*/ 2457 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 2458 NFCSTATUS_WRITE_FAILED); 2459 } 2460 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2461 break; 2462 2463 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK : 2464 if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE ) 2465 { 2466 /* chk the status flags 1 and 2*/ 2467 if ( NdefMap->SendRecvBuf[10] == 0x00 ) 2468 { 2469 /* This is used when we have bytes less than 16 bytes*/ 2470 if ( NdefMap->Felica.IntermediateWrFlag == TRUE ) 2471 { 2472 /* after Successful write copy the last writtened bytes back to the 2473 internal buffer*/ 2474 (void)memcpy( (&(NdefMap->Felica.Wr_RemainedBytesBuff[NdefMap->Felica.Wr_BytesRemained])), 2475 NdefMap->ApduBuffer, 2476 NdefMap->NumOfBytesWritten); 2477 2478 NdefMap->Felica.Wr_BytesRemained += 2479 (uint8_t)( NdefMap->NumOfBytesWritten); 2480 2481 /* Increment the Send Buffer index */ 2482 NdefMap->ApduBuffIndex += 2483 NdefMap->NumOfBytesWritten; 2484 2485 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; 2486 NdefMap->Felica.IntermediateWrFlag = FALSE; 2487 /* Call Update Data()*/ 2488 Status = phFriNfc_Felica_HUpdateData(NdefMap); 2489 } 2490 else 2491 { 2492 /* update the index and bytes writtened*/ 2493 NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; 2494 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex; 2495 if ( NdefMap->Felica.EofCardReachedFlag ) 2496 { 2497 if ( NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb) 2498 { 2499 NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten; 2500 } 2501 if (( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) && 2502 ( NdefMap->ApduBuffIndex == (NdefMap->FelicaAttrInfo.Nmaxb*16))) 2503 { 2504 NdefMap->Felica.EofCardReachedFlag = FELICA_RD_WR_EOF_CARD_REACHED ; 2505 /*0 represents the write ended*/ 2506 Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED); 2507 if( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2508 { 2509 /* call respective CR */ 2510 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2511 } 2512 } 2513 else 2514 { 2515 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0], 2516 NdefMap->FelicaAttrInfo.LenBytes[1], 2517 NdefMap->FelicaAttrInfo.LenBytes[2], 2518 TotNoWrittenBytes); 2519 if ( ( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) && 2520 ((TotNoWrittenBytes + NdefMap->ApduBuffIndex) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb*16))) 2521 { 2522 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED; 2523 /*0 represents the write ended*/ 2524 Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED); 2525 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2526 { 2527 /* call respective CR */ 2528 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2529 } 2530 } 2531 else 2532 { 2533 /* Call Update Data()*/ 2534 Status = phFriNfc_Felica_HUpdateData(NdefMap); 2535 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2536 { 2537 /* call respective CR */ 2538 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2539 } 2540 } 2541 } 2542 }/*if ( NdefMap->Felica.EofCardReachedFlag )*/ 2543 else 2544 { 2545 NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten; 2546 /* Call Update Data()*/ 2547 Status = phFriNfc_Felica_HUpdateData(NdefMap); 2548 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2549 { 2550 /* call respective CR */ 2551 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2552 } 2553 } 2554 } 2555 }/*if ( NdefMap->SendRecvBuf[10] == 0x00 )*/ 2556 else 2557 { 2558 /*handle the Error case*/ 2559 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 2560 NFCSTATUS_WRITE_FAILED); 2561 CRFlag = TRUE; 2562 2563 } 2564 }/*if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )*/ 2565 else 2566 { 2567 /*return Error "Invalid Write Response Code"*/ 2568 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 2569 NFCSTATUS_WRITE_FAILED); 2570 CRFlag = TRUE; 2571 2572 } 2573 if ( CRFlag == TRUE ) 2574 { 2575 /* Reset following parameters*/ 2576 NdefMap->ApduBuffIndex=0; 2577 NdefMap->Felica.Wr_BytesRemained = 0; 2578 NdefMap->ApduBufferSize = 0; 2579 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status); 2580 } 2581 2582 break; 2583 2584 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK : 2585 2586 /* check the Manuf Id in the receive buffer*/ 2587 Status = phFriNfc_Felica_HCheckManufId(NdefMap); 2588 if ( Status == NFCSTATUS_SUCCESS ) 2589 { 2590 if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_RD_RESP_BYTE ) 2591 { 2592 /* calculate the Nmaxb*/ 2593 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC); 2594 /*get Receive length from the card for corss verifications*/ 2595 RecvTxLen= phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc); 2596 BytesToRecv = NdefMap->SendRecvBuf[12]*16; 2597 2598 /* chk the status flags 1 */ 2599 if ( NdefMap->SendRecvBuf[10] == 0x00) 2600 { 2601 if ( RecvTxLen == BytesToRecv) 2602 { 2603 NdefMap->Felica.CurBlockNo += (uint8_t)(RecvTxLen/16); 2604 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap); 2605 Status = phFriNfc_Felica_HReadData(NdefMap,PH_FRINFC_NDEFMAP_SEEK_CUR); 2606 /* handle the error in Transc function*/ 2607 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 2608 { 2609 CRFlag =TRUE; 2610 } 2611 } 2612 else 2613 { 2614 CRFlag =TRUE; 2615 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 2616 NFCSTATUS_INVALID_RECEIVE_LENGTH); 2617 /*set the buffer index back to zero*/ 2618 NdefMap->ApduBuffIndex = 0; 2619 NdefMap->Felica.Rd_NoBytesToCopy = 0; 2620 } 2621 } 2622 else 2623 { 2624 NdefMap->ApduBuffIndex=0; 2625 /*handle the Error case*/ 2626 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 2627 NFCSTATUS_READ_FAILED); 2628 CRFlag =TRUE; 2629 } 2630 } 2631 else 2632 { 2633 CRFlag =TRUE; 2634 NdefMap->ApduBuffIndex=0; 2635 /*return Error "Invalid Read Response Code"*/ 2636 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 2637 NFCSTATUS_READ_FAILED); 2638 } 2639 } 2640 else 2641 { 2642 CRFlag =TRUE; 2643 } 2644 if ( CRFlag ==TRUE ) 2645 { 2646 /* call respective CR */ 2647 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status); 2648 } 2649 break; 2650 2651 default: 2652 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 2653 NFCSTATUS_INVALID_DEVICE_REQUEST); 2654 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status); 2655 break; 2656 2657 2658 } 2659 } 2660 else 2661 { 2662 /* Call CR for unknown Error's*/ 2663 switch ( NdefMap->State) 2664 { 2665 case PH_FRINFC_NDEFMAP_FELI_STATE_CHK_NDEF : 2666 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_WILD_CARD : 2667 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP : 2668 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR : 2669 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_CHK_NDEF, 2670 Status); 2671 break; 2672 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK : 2673 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN : 2674 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END : 2675 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_WR_NDEF, 2676 Status); 2677 break; 2678 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK : 2679 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_RD_NDEF, 2680 Status); 2681 break; 2682 default : 2683 /*set the invalid state*/ 2684 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST); 2685 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status); 2686 break; 2687 } 2688 } 2689 2690 } 2691 2692 /*! 2693 * \brief Prepares Cmd Pkt for reading attribute Blk information. 2694 */ 2695 static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap) 2696 { 2697 2698 NFCSTATUS status = NFCSTATUS_PENDING; 2699 uint8_t BufIndex = 0; 2700 2701 /* Set the Felica Cmd*/ 2702 #ifdef PH_HAL4_ENABLE 2703 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; 2704 #else 2705 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd; 2706 #endif /* #ifdef PH_HAL4_ENABLE */ 2707 2708 /*set the additional informations for the data exchange*/ 2709 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 2710 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; 2711 2712 /* 1st byte represents the length of the cmd packet*/ 2713 NdefMap->SendRecvBuf[BufIndex] = 0x00; 2714 BufIndex++; 2715 2716 /* Read/check command code*/ 2717 NdefMap->SendRecvBuf[BufIndex] = 0x06; 2718 BufIndex++; 2719 2720 /* IDm - Manufacturer Id : 8bytes*/ 2721 #ifdef PH_HAL4_ENABLE 2722 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 2723 (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm, 2724 8); 2725 #else 2726 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])), 2727 (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t, 2728 8); 2729 2730 #endif /* #ifdef PH_HAL4_ENABLE */ 2731 2732 BufIndex+=8; 2733 2734 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/ 2735 BufIndex++; 2736 2737 NdefMap->SendRecvBuf[BufIndex] = 0x0B; /* Service Code List*/ 2738 BufIndex++; 2739 2740 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/ 2741 BufIndex++; 2742 2743 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to read)*/ 2744 BufIndex++; 2745 2746 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/ 2747 BufIndex++; 2748 2749 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/ 2750 BufIndex++; 2751 2752 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex; 2753 2754 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength; 2755 2756 /* Update the Send Len*/ 2757 NdefMap->SendLength = BufIndex; 2758 2759 /* Change the state to PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR */ 2760 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR; 2761 2762 /*set the completion routines for the desfire card operations*/ 2763 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process; 2764 NdefMap->MapCompletionInfo.Context = NdefMap; 2765 2766 /*Call the Overlapped HAL Transceive function */ 2767 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice, 2768 &NdefMap->MapCompletionInfo, 2769 NdefMap->psRemoteDevInfo, 2770 NdefMap->Cmd, 2771 &NdefMap->psDepAdditionalInfo, 2772 NdefMap->SendRecvBuf, 2773 NdefMap->SendLength, 2774 NdefMap->SendRecvBuf, 2775 NdefMap->SendRecvLength); 2776 return (status); 2777 2778 } 2779 2780 /*! 2781 * \brief Validated manufacturer Details, during the read/write operations. 2782 */ 2783 2784 static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap) 2785 { 2786 NFCSTATUS status = NFCSTATUS_PENDING; 2787 2788 uint8_t result = 0; 2789 2790 /* check the stored manufacture id with the received manufacture id*/ 2791 result = (uint8_t)(phFriNfc_Felica_MemCompare( (void *)(&(NdefMap->SendRecvBuf[2])), 2792 (void *)NdefMap->FelicaManufDetails.ManufID, 2793 8)); 2794 2795 if ( result != 0) 2796 { 2797 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE); 2798 2799 } 2800 else 2801 { 2802 status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); 2803 2804 } 2805 return (status); 2806 } 2807 2808 static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer, 2809 uint8_t StartIndex, 2810 uint8_t EndIndex, 2811 uint16_t RecvChkSum) 2812 { 2813 NFCSTATUS Result = NFCSTATUS_SUCCESS; 2814 uint16_t CheckSum=0, 2815 BufIndex=0; 2816 2817 for(BufIndex = StartIndex;BufIndex <=EndIndex;BufIndex++) 2818 { 2819 CheckSum += TempBuffer[BufIndex]; 2820 } 2821 if( RecvChkSum != CheckSum ) 2822 { 2823 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 2824 NFCSTATUS_INVALID_FORMAT); 2825 } 2826 return (Result); 2827 } 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 /*! 2840 * \brief On successful read attribute blk information, this function validates and stores the 2841 * Attribute informations in to the context. 2842 */ 2843 static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap) 2844 { 2845 NFCSTATUS status = NFCSTATUS_PENDING; 2846 uint8_t CRFlag = FALSE, 2847 Nmaxb1, Nmaxb2 = 0, 2848 ChkSum1 = 0, ChkSum2=0; 2849 2850 uint16_t Nmaxblk = 0, 2851 RecvChkSum=0, 2852 NdefBlk = 0; 2853 uint32_t DataLen =0; 2854 2855 2856 /* Validate T3VNo and NFCDevVNo */ 2857 status = phFriNfc_MapTool_ChkSpcVer(NdefMap, 2858 PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX); 2859 if ( status != NFCSTATUS_SUCCESS ) 2860 { 2861 CRFlag = TRUE; 2862 } 2863 else 2864 { 2865 /* get the Nmaxb from the receive buffer*/ 2866 Nmaxb1 = NdefMap->SendRecvBuf[16]; 2867 Nmaxb2 = NdefMap->SendRecvBuf[17]; 2868 2869 Nmaxblk = (((uint16_t)Nmaxb1 << 8) | (Nmaxb2 & 0x00ff)); 2870 2871 if ( Nmaxblk != 0 ) 2872 { 2873 /* check the Nbr against the Nmaxb*/ 2874 if ( NdefMap->SendRecvBuf[14] > Nmaxblk ) 2875 { 2876 CRFlag = TRUE; 2877 } 2878 else 2879 { 2880 /*check Nbw > Nmaxb*/ 2881 /*check the write flag validity*/ 2882 /*check for the RFU bytes validity*/ 2883 if ( (NdefMap->SendRecvBuf[15] > Nmaxblk) || 2884 ((NdefMap->SendRecvBuf[22] != 0x00) && (NdefMap->SendRecvBuf[22] !=0x0f ))|| 2885 ( (NdefMap->SendRecvBuf[23] != 0x00) && (NdefMap->SendRecvBuf[23] !=0x01 ))|| 2886 ( NdefMap->SendRecvBuf[18] != 0x00) || 2887 ( NdefMap->SendRecvBuf[19] != 0x00) || 2888 ( NdefMap->SendRecvBuf[20] != 0x00) || 2889 ( NdefMap->SendRecvBuf[21] != 0x00)) 2890 2891 { 2892 CRFlag = TRUE; 2893 } 2894 else 2895 { 2896 /* check the validity of the actual ndef data len*/ 2897 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES( NdefMap->SendRecvBuf[24], 2898 NdefMap->SendRecvBuf[25], 2899 NdefMap->SendRecvBuf[26], 2900 DataLen); 2901 2902 2903 /* Calculate Nbc*/ 2904 NdefBlk = (uint16_t )((( DataLen % 16) == 0 ) ? (DataLen >> 4) : ((DataLen >> 4) +1)); 2905 2906 /* check Nbc against Nmaxb*/ 2907 if ((NdefBlk > Nmaxblk)) 2908 { 2909 CRFlag = TRUE; 2910 } 2911 else 2912 { 2913 /*Store the attribute information in phFriNfc_Felica_AttrInfo*/ 2914 NdefMap->FelicaAttrInfo.Version = NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX]; 2915 NdefMap->FelicaAttrInfo.Nbr = NdefMap->SendRecvBuf[14]; 2916 NdefMap->FelicaAttrInfo.Nbw = NdefMap->SendRecvBuf[15]; 2917 2918 NdefMap->FelicaAttrInfo.Nmaxb = Nmaxblk; 2919 2920 NdefMap->FelicaAttrInfo.WriteFlag = NdefMap->SendRecvBuf[22]; 2921 NdefMap->FelicaAttrInfo.RdWrFlag = NdefMap->SendRecvBuf[23]; 2922 2923 /* Get CheckSum*/ 2924 ChkSum1 = NdefMap->SendRecvBuf[27]; 2925 ChkSum2 = NdefMap->SendRecvBuf[28]; 2926 2927 RecvChkSum = (((uint16_t)ChkSum1 << 8) | (ChkSum2 & 0x00ff)); 2928 2929 /* Check the check sum validity?*/ 2930 status = phFriNfc_Felica_HCalCheckSum(NdefMap->SendRecvBuf, 2931 PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX, 2932 26, 2933 RecvChkSum); 2934 if ( status != NFCSTATUS_SUCCESS ) 2935 { 2936 CRFlag = TRUE; 2937 } 2938 else 2939 { 2940 /*check RW Flag Access Rights*/ 2941 /* set to read only cannot write*/ 2942 if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00 ) 2943 { 2944 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; 2945 } 2946 else if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x01 ) // additional check for R/W access 2947 { 2948 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE; 2949 } 2950 else // otherwise invalid 2951 { 2952 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; 2953 } 2954 2955 NdefMap->FelicaAttrInfo.LenBytes[0] = NdefMap->SendRecvBuf[24]; 2956 NdefMap->FelicaAttrInfo.LenBytes[1] = NdefMap->SendRecvBuf[25]; 2957 NdefMap->FelicaAttrInfo.LenBytes[2] = NdefMap->SendRecvBuf[26]; 2958 status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); 2959 } 2960 } 2961 } 2962 } 2963 } 2964 else 2965 { 2966 CRFlag = TRUE; 2967 } 2968 } 2969 if ( (status == NFCSTATUS_INVALID_FORMAT ) && (CRFlag == TRUE )) 2970 { 2971 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; 2972 } 2973 if ( CRFlag == TRUE ) 2974 { 2975 /*Return Status Error Invalid Format*/ 2976 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT); 2977 } 2978 2979 return (status); 2980 } 2981 2982 /*! 2983 * \brief this shall notify the integration software with respective 2984 * success/error status along with the completion routines. 2985 */ 2986 static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap, 2987 uint8_t CrIndex, 2988 NFCSTATUS Status) 2989 { 2990 /* set the state back to the Reset_Init state*/ 2991 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; 2992 2993 /* set the completion routine*/ 2994 NdefMap->CompletionRoutine[CrIndex]. 2995 CompletionRoutine(NdefMap->CompletionRoutine->Context, Status); 2996 } 2997 2998 /*! 2999 * \brief this shall initialise the internal buffer data to zero. 3000 */ 3001 static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer) 3002 { 3003 uint8_t index=0; 3004 3005 for( index = 0; index< 16 ; index++) 3006 { 3007 Buffer[index] = 0; 3008 } 3009 } 3010 3011 static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n ) 3012 { 3013 int8_t diff = 0; 3014 int8_t *char_1 =(int8_t *)s1; 3015 int8_t *char_2 =(int8_t *)s2; 3016 if(NULL == s1 || NULL == s2) 3017 { 3018 PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare"); 3019 } 3020 else 3021 { 3022 for(;((n>0)&&(diff==0));n--,char_1++,char_2++) 3023 { 3024 diff = *char_1 - *char_2; 3025 } 3026 } 3027 return (int)diff; 3028 } 3029 3030 3031 #ifdef UNIT_TEST 3032 #include <phUnitTestNfc_Felica_static.c> 3033 #endif 3034 3035 #endif /* PH_FRINFC_MAP_FELICA_DISABLED */ 3036