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