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_Desfire.c 19 * \brief This component encapsulates read/write/check ndef/process functionalities, 20 * for the Desfire Card. 21 * 22 * Project: NFC-FRI 23 * 24 * $Date: Thu Jul 23 13:45:00 2009 $ 25 * $Author: ing07336 $ 26 * $Revision: 1.10 $ 27 * $Aliases: NFC_FRI1.1_WK930_R30_1,NFC_FRI1.1_WK934_PREP_1,NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $ 28 * 29 */ 30 31 #ifndef PH_FRINFC_MAP_DESFIRE_DISABLED 32 33 #include <phFriNfc_OvrHal.h> 34 #include <phFriNfc_DesfireMap.h> 35 #include <phFriNfc_MapTools.h> 36 37 38 /*! \ingroup grp_file_attributes 39 * \name NDEF Mapping 40 * 41 * File: \ref phFriNfc_Desfire.c 42 * 43 */ 44 /*@{*/ 45 #define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.10 $" 46 #define PHFRINFCNDEFMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK930_R30_1,NFC_FRI1.1_WK934_PREP_1,NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $" 47 48 /*@}*/ 49 50 /*@}*/ 51 52 /*! 53 * \name Desfire Mapping - Helper Functions 54 * 55 */ 56 /*@{*/ 57 58 /*! 59 * \brief \copydoc page_ovr Helper function for Desfire. This function specifies 60 * the card is a Desfire card or not. 61 */ 62 static NFCSTATUS phFriNfc_Desfire_SelectSmartTag( phFriNfc_NdefMap_t *NdefMap); 63 64 /*! 65 * \brief \copydoc page_ovr Helper function for Desfire. This function is used 66 * to selct a file in the card. 67 */ 68 static NFCSTATUS phFriNfc_Desfire_SelectFile ( phFriNfc_NdefMap_t *NdefMap); 69 70 /*! 71 * \brief \copydoc page_ovr Helper function for Desfire. This function is to 72 * read the card. 73 */ 74 static NFCSTATUS phFriNfc_Desfire_ReadBinary( phFriNfc_NdefMap_t *NdefMap); 75 76 /*! 77 * \brief \copydoc page_ovr Helper function for Desfire. This function is to 78 * write to the card. 79 */ 80 static NFCSTATUS phFriNfc_Desfire_UpdateBinary( phFriNfc_NdefMap_t *NdefMap); 81 82 /*! 83 * \brief \copydoc page_ovr Helper function for Desfire. This function is to 84 * update the capability container of the card. 85 */ 86 static NFCSTATUS phFriNfc_Desfire_Update_SmartTagCapContainer( phFriNfc_NdefMap_t *NdefMap); 87 88 89 /* Completion Helper*/ 90 static void phFriNfc_Desfire_HCrHandler( phFriNfc_NdefMap_t *NdefMap, 91 NFCSTATUS Status); 92 93 /* Calculates the Le Bytes for Read Operation*/ 94 static uint32_t phFriNfc_Desfire_HGetLeBytes( phFriNfc_NdefMap_t *NdefMap); 95 96 static NFCSTATUS phFriNfc_Desf_HChkAndParseTLV( phFriNfc_NdefMap_t *NdefMap, 97 uint8_t BuffIndex); 98 99 static NFCSTATUS phFriNfc_Desfire_HSetGet_NLEN( phFriNfc_NdefMap_t *NdefMap); 100 101 static void phFriNfc_Desfire_HProcReadData( phFriNfc_NdefMap_t *NdefMap); 102 103 static void phFriNfc_Desfire_HChkNDEFFileAccessRights( phFriNfc_NdefMap_t *NdefMap); 104 static NFCSTATUS phFriNfc_Desfire_HSendTransCmd(phFriNfc_NdefMap_t *NdefMap,uint8_t SendRecvLen); 105 106 #ifdef PH_HAL4_ENABLE 107 108 #else 109 110 /* Following are the API's are used to get the version of the desfire card*/ 111 static NFCSTATUS phFriNfc_Desfire_HGetHWVersion(phFriNfc_NdefMap_t *NdefMap); 112 static NFCSTATUS phFriNfc_Desfire_HGetSWVersion(phFriNfc_NdefMap_t *NdefMap); 113 static NFCSTATUS phFriNfc_Desfire_HGetUIDDetails(phFriNfc_NdefMap_t *NdefMap); 114 static NFCSTATUS phFriNfc_Desfire_HUpdateVersionDetails(const phFriNfc_NdefMap_t *NdefMap); 115 116 #endif /* #ifdef PH_HAL4_ENABLE */ 117 118 #ifdef PH_HAL4_ENABLE 119 120 #else 121 122 static NFCSTATUS phFriNfc_Desfire_HGetHWVersion(phFriNfc_NdefMap_t *NdefMap) 123 { 124 125 NFCSTATUS status = NFCSTATUS_PENDING; 126 127 /*set the state*/ 128 NdefMap->State = PH_FRINFC_DESF_STATE_GET_HW_VERSION; 129 130 /* Helper routine to wrap the native desfire cmds*/ 131 PH_FRINFC_DESF_ISO_NATIVE_WRAPPER(); 132 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE); 133 134 return (status); 135 } 136 137 static NFCSTATUS phFriNfc_Desfire_HGetSWVersion(phFriNfc_NdefMap_t *NdefMap) 138 { 139 140 NFCSTATUS status = NFCSTATUS_PENDING; 141 if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == PH_FRINFC_DESF_NATIVE_GETVER_RESP) ) 142 { 143 /*set the state*/ 144 NdefMap->State = PH_FRINFC_DESF_STATE_GET_SW_VERSION; 145 146 /* Helper routine to wrap the native desfire commands*/ 147 PH_FRINFC_DESF_ISO_NATIVE_WRAPPER(); 148 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE); 149 } 150 #ifdef PH_HAL4_ENABLE 151 else 152 { 153 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 154 NFCSTATUS_INVALID_PARAMETER); 155 } 156 #endif /* #ifdef PH_HAL4_ENABLE */ 157 return status; 158 } 159 160 static NFCSTATUS phFriNfc_Desfire_HGetUIDDetails(phFriNfc_NdefMap_t *NdefMap) 161 { 162 163 NFCSTATUS status = NFCSTATUS_PENDING; 164 165 if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == PH_FRINFC_DESF_NATIVE_GETVER_RESP) ) 166 { 167 /*set the state*/ 168 NdefMap->State = PH_FRINFC_DESF_STATE_GET_UID; 169 170 /* Helper routine to wrap the native desfire commands*/ 171 PH_FRINFC_DESF_ISO_NATIVE_WRAPPER(); 172 173 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE); 174 } 175 #ifdef PH_HAL4_ENABLE 176 else 177 { 178 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 179 NFCSTATUS_INVALID_PARAMETER); 180 } 181 #endif /* #ifdef PH_HAL4_ENABLE */ 182 return status; 183 184 } 185 186 static NFCSTATUS phFriNfc_Desfire_HUpdateVersionDetails(const phFriNfc_NdefMap_t *NdefMap) 187 { 188 NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 189 NFCSTATUS_INVALID_PARAMETER); 190 191 if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == 0xAF) ) 192 { 193 194 status = NFCSTATUS_SUCCESS; 195 196 /* We do not need the following details presently.Retained for future use*/ 197 #if 0 198 NdefMap->AddInfo.Type4Info.MajorVersion = NdefSmtCrdFmt->SendRecvBuf[3]; 199 NdefMap->AddInfo.Type4Info.MinorVersion = NdefSmtCrdFmt->SendRecvBuf[4]; 200 if ( ( NdefMap->AddInfo.Type4Info.MajorVersion == 0x00 )&& 201 ( NdefMap->AddInfo.Type4Info.MinorVersion == 0x06 )) 202 { 203 /* card size of DESFire4 type */ 204 //NdefMap->AddInfo.Type4Info.CardSize = 0xEDE; 205 206 } 207 else 208 { 209 // need to handle the Desfire8 type cards 210 // need to use get free memory 211 } 212 #endif 213 } 214 return status; 215 } 216 217 218 #endif /* #ifdef PH_HAL4_ENABLE */ 219 220 /*! 221 * \brief Initiates Reading of NDEF information from the Desfire Card. 222 * 223 * The function initiates the reading of NDEF information from a Remote Device. 224 * It performs a reset of the state and starts the action (state machine). 225 * A periodic call of the \ref phFriNfcNdefMap_Process has to be 226 * done once the action has been triggered. 227 */ 228 229 NFCSTATUS phFriNfc_Desfire_RdNdef( phFriNfc_NdefMap_t *NdefMap, 230 uint8_t *PacketData, 231 uint32_t *PacketDataLength, 232 uint8_t Offset) 233 { 234 NFCSTATUS status = NFCSTATUS_PENDING; 235 236 NdefMap->ApduBufferSize = *PacketDataLength; 237 /* To return actual number of bytes read to the caller */ 238 NdefMap->NumOfBytesRead = PacketDataLength ; 239 *NdefMap->NumOfBytesRead = 0; 240 241 /* store the offset in to map context*/ 242 NdefMap->Offset = Offset; 243 244 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && 245 (*NdefMap->DataCount == NdefMap->DesfireCapContainer.NdefDataLen)) 246 { 247 /* No space on card for Reading : we have already 248 reached the end of file ! 249 Offset is set to Continue Operation */ 250 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 251 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 252 } 253 else 254 { 255 256 /* reset the inter flag*/ 257 NdefMap->DesfireCapContainer.IsNlenPresentFlag = 0; 258 NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 0; 259 260 /* Set the desfire read operation */ 261 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_READ_OP; 262 263 /* Save the packet data buffer address in the context */ 264 NdefMap->ApduBuffer = PacketData; 265 266 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE; 267 268 /* Select smart tag operation. First step for the read operation. */ 269 status = phFriNfc_Desfire_SelectSmartTag(NdefMap); 270 } 271 272 return status; 273 } 274 275 /*! 276 * \brief Initiates Writing of NDEF information to the Remote Device. 277 * 278 * The function initiates the writing of NDEF information to a Remote Device. 279 * It performs a reset of the state and starts the action (state machine). 280 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action 281 * has been triggered. 282 */ 283 284 NFCSTATUS phFriNfc_Desfire_WrNdef( phFriNfc_NdefMap_t *NdefMap, 285 uint8_t *PacketData, 286 uint32_t *PacketDataLength, 287 uint8_t Offset) 288 { 289 NFCSTATUS status = NFCSTATUS_PENDING; 290 291 NdefMap->ApduBufferSize = *PacketDataLength; 292 NdefMap->WrNdefPacketLength = PacketDataLength; 293 294 /* Now, let's initialize *NdefMap->WrNdefPacketLength to zero. 295 In case we get an error, this will be correctly set to "no byte written". 296 In case there is no error, this will be updated later on, in the _process function. 297 */ 298 *NdefMap->WrNdefPacketLength = 0; 299 300 /* we have write access. */ 301 if( *NdefMap->DataCount >= PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) 302 { 303 /* No space on card for writing : we have already 304 reached the end of file ! 305 Offset is set to Continue Operation */ 306 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 307 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 308 } 309 else 310 { 311 /* Adapt the nb of bytes that the user would like to write */ 312 313 /*set the defire write operation*/ 314 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_WRITE_OP; 315 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE; 316 NdefMap->Offset = Offset; 317 318 /*Store the packet data buffer*/ 319 NdefMap->ApduBuffer = PacketData; 320 321 /* Select smart tag operation. First step for the write operation. */ 322 status = phFriNfc_Desfire_SelectSmartTag (NdefMap); 323 } 324 return status; 325 } 326 327 /*! 328 * \brief Check whether a particular Remote Device is NDEF compliant. 329 * 330 * The function checks whether the peer device is NDEF compliant. 331 * 332 */ 333 334 NFCSTATUS phFriNfc_Desfire_ChkNdef( phFriNfc_NdefMap_t *NdefMap) 335 { 336 NFCSTATUS status = NFCSTATUS_PENDING; 337 338 #ifdef PH_HAL4_ENABLE 339 340 /*Set the desfire operation flag*/ 341 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP; 342 343 /*Call Select Smart tag Functinality*/ 344 status = phFriNfc_Desfire_SelectSmartTag(NdefMap); 345 #else 346 /* Need to get the version details of the card, to 347 identify the the desfire4card type */ 348 status = phFriNfc_Desfire_HGetHWVersion(NdefMap); 349 #endif 350 351 return (status); 352 } 353 354 static NFCSTATUS phFriNfc_Desf_HChkAndParseTLV(phFriNfc_NdefMap_t *NdefMap, uint8_t BuffIndex) 355 { 356 NFCSTATUS status = NFCSTATUS_SUCCESS; 357 358 if((NdefMap->SendRecvBuf[BuffIndex] <= 0x03) || 359 (NdefMap->SendRecvBuf[BuffIndex] >= 0x06) ) 360 { 361 status = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, 362 NFCSTATUS_NO_NDEF_SUPPORT); 363 } 364 else 365 { 366 /* check for the type of TLV*/ 367 NdefMap->TLVFoundFlag = 368 ((NdefMap->SendRecvBuf[BuffIndex] == 0x04)? 369 PH_FRINFC_NDEFMAP_DESF_NDEF_CNTRL_TLV: 370 PH_FRINFC_NDEFMAP_DESF_PROP_CNTRL_TLV); 371 372 status = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, 373 NFCSTATUS_SUCCESS); 374 } 375 return status; 376 } 377 378 static NFCSTATUS phFriNfc_Desfire_HSetGet_NLEN(phFriNfc_NdefMap_t *NdefMap) 379 { 380 381 NFCSTATUS status = NFCSTATUS_PENDING; 382 383 if ( PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP == NdefMap->DespOpFlag) 384 { 385 386 /*Call Select Smart tag Functinality*/ 387 status = phFriNfc_Desfire_SelectSmartTag(NdefMap); 388 } 389 else 390 { 391 392 /* Get the Data Count and set it to NoOfBytesWritten 393 Update the NLEN using Transceive cmd*/ 394 395 /*Form the packet for the update binary command*/ 396 NdefMap->SendRecvBuf[0] = 0x00; 397 NdefMap->SendRecvBuf[1] = 0xD6; 398 399 /* As we need to set the NLEN @ first 2 bytes of NDEF File*/ 400 /* set the p1/p2 offsets */ 401 NdefMap->SendRecvBuf[2] = 0x00; /* p1 */ 402 NdefMap->SendRecvBuf[3] = 0x00; /* p2 */ 403 404 /* Set only two bytes as NLEN*/ 405 NdefMap->SendRecvBuf[4] = 0x02; 406 407 /* update NLEN */ 408 NdefMap->SendRecvBuf[5] = (uint8_t)(*NdefMap->DataCount >> PH_FRINFC_NDEFMAP_DESF_SHL8); 409 NdefMap->SendRecvBuf[6] = (uint8_t)(*NdefMap->DataCount & (0x00ff)); 410 411 NdefMap->SendLength = 0x07 ; 412 413 /* Change the state to Write */ 414 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_END; 415 416 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET); 417 } 418 return status; 419 } 420 421 static void phFriNfc_Desfire_HProcReadData(phFriNfc_NdefMap_t *NdefMap) 422 { 423 NFCSTATUS Result = NFCSTATUS_PENDING; 424 uint32_t BufferSize = 0; 425 uint8_t BufIndex=0; 426 uint16_t SizeToCpy=0; 427 428 /* Need to check the Actual Ndef Length before copying the data to buffer*/ 429 /* Only NDEF data should be copied , rest all the data should be ignored*/ 430 /* Ex : Ndef File Size 50 bytes , but only 5 bytes(NLEN) are relavent to NDEF data*/ 431 /* component should only copy 5 bytes to user buffer*/ 432 433 /* Data has been read successfully in the TRX buffer. */ 434 /* copy it to the user buffer. */ 435 436 /* while copying need check the offset if its begin need to skip the first 2 bytes 437 while copying. If its current no need to skip the first 2 bytes*/ 438 439 if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN ) 440 { 441 BufIndex = (uint8_t)(( NdefMap->DesfireCapContainer.IsNlenPresentFlag == 1 )? 442 0:PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES); 443 444 /* Update the latest NLEN to context*/ 445 NdefMap->DesfireCapContainer.NdefDataLen = ((*NdefMap->DataCount == 0)? 446 ( (((uint16_t)NdefMap->SendRecvBuf[ 447 PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_FIRST_INDEX])<<8)+ \ 448 NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_SECOND_INDEX]): 449 NdefMap->DesfireCapContainer.NdefDataLen); 450 451 /* Decide how many byes to be copied into user buffer: depending upon the actual NDEF 452 size need to copy the content*/ 453 if ( (NdefMap->DesfireCapContainer.NdefDataLen) <= (*NdefMap->SendRecvLength - \ 454 (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET + BufIndex))) 455 { 456 SizeToCpy = NdefMap->DesfireCapContainer.NdefDataLen; 457 458 } 459 else 460 { 461 SizeToCpy = ((*NdefMap->SendRecvLength)-(PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET+BufIndex)); 462 } 463 464 /* Check do we have Ndef Data len > 0 present in the card.If No Ndef Data 465 present in the card , set the card state to Initalised and set an Error*/ 466 if ( NdefMap->DesfireCapContainer.NdefDataLen == 0x00 ) 467 { 468 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED; 469 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED); 470 #ifdef PH_HAL4_ENABLE 471 #else 472 NdefMap->PrevOperation = 0; 473 #endif /* #ifdef PH_HAL4_ENABLE */ 474 phFriNfc_Desfire_HCrHandler(NdefMap,Result); 475 } 476 else 477 { 478 (void)memcpy( (&(NdefMap->ApduBuffer[ 479 NdefMap->ApduBuffIndex])), 480 (&(NdefMap->SendRecvBuf[BufIndex])), 481 (SizeToCpy)); 482 483 /* Increment the Number of Bytes Read, which will be returned to the caller. */ 484 *NdefMap->NumOfBytesRead +=SizeToCpy; 485 486 /*update the data count*/ 487 *NdefMap->DataCount += SizeToCpy; 488 489 /*update the buffer index of the apdu buffer*/ 490 NdefMap->ApduBuffIndex += SizeToCpy; 491 } 492 } 493 else 494 { 495 (void)memcpy( (&(NdefMap->ApduBuffer[ 496 NdefMap->ApduBuffIndex])), 497 (NdefMap->SendRecvBuf),/* to avoid the length of the NDEF File*/ 498 (*(NdefMap->SendRecvLength)-(PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET))); 499 500 /* Increment the Number of Bytes Read, which will be returned to the caller. */ 501 *NdefMap->NumOfBytesRead +=( *NdefMap->SendRecvLength - \ 502 (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET)); 503 504 /*update the data count*/ 505 *NdefMap->DataCount += \ 506 (*NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET)); 507 508 /*update the buffer index of the apdu buffer*/ 509 NdefMap->ApduBuffIndex += \ 510 *NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET ); 511 } 512 513 /* check whether we still have to read some more data. */ 514 if (*NdefMap->DataCount < NdefMap->DesfireCapContainer.NdefDataLen ) 515 { 516 /* we have some bytes to read. */ 517 518 /* Now check, we still have bytes left in the user buffer. */ 519 BufferSize = NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex; 520 if(BufferSize != 0) 521 { 522 /* Before read need to set the flag to intimate the module to 523 dont skip the first 2 bytes as we are in mode reading next 524 continues available bytes, which will not contain the NLEN 525 information in the begining part that is 2 bytes*/ 526 NdefMap->DesfireCapContainer.IsNlenPresentFlag = 1; 527 /* Read Operation is not complete */ 528 Result = phFriNfc_Desfire_ReadBinary( NdefMap ); 529 /* handle the error in Transc function*/ 530 if ( (Result & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER) ) 531 { 532 /* call respective CR */ 533 phFriNfc_Desfire_HCrHandler(NdefMap,Result); 534 } 535 } 536 else 537 { 538 /* There are some more bytes to read, but 539 no space in the user buffer */ 540 Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); 541 NdefMap->ApduBuffIndex =0; 542 /* call respective CR */ 543 phFriNfc_Desfire_HCrHandler(NdefMap,Result); 544 } 545 } 546 else 547 { 548 if (*NdefMap->DataCount == NdefMap->DesfireCapContainer.NdefDataLen ) 549 { 550 /* we have read all the bytes available in the card. */ 551 Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS); 552 #ifdef PH_HAL4_ENABLE 553 /* Do nothing */ 554 #else 555 NdefMap->PrevOperation = 0; 556 #endif /* #ifndef PH_HAL4_ENABLE */ 557 } 558 else 559 { 560 /* The control should not come here. */ 561 /* we have actually read more byte than available in the card. */ 562 NdefMap->PrevOperation = 0; 563 #ifndef PH_HAL4_ENABLE 564 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 565 NFCSTATUS_CMD_ABORTED); 566 #else 567 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 568 NFCSTATUS_FAILED); 569 #endif 570 } 571 572 573 NdefMap->ApduBuffIndex = 0; 574 575 /* call respective CR */ 576 phFriNfc_Desfire_HCrHandler(NdefMap,Result); 577 } 578 } 579 580 581 582 /*! 583 * \brief Completion Routine, Processing function, needed to avoid long blocking. 584 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion 585 * Routine in order to be able to notify the component that an I/O has finished and data are 586 * ready to be processed. 587 * 588 */ 589 590 void phFriNfc_Desfire_Process(void *Context, 591 NFCSTATUS Status) 592 { 593 /*Set the context to Map Module*/ 594 phFriNfc_NdefMap_t *NdefMap = (phFriNfc_NdefMap_t *)Context; 595 uint8_t ErrFlag = 0; 596 uint16_t NLength = 0, 597 SendRecLen=0; 598 uint32_t BytesRead = 0; 599 600 601 /* Sujatha P: Fix for 0000255/0000257:[gk] MAP:Handling HAL Errors */ 602 if ( Status == NFCSTATUS_SUCCESS ) 603 { 604 switch (NdefMap->State) 605 { 606 607 #ifdef PH_HAL4_ENABLE 608 #else 609 610 case PH_FRINFC_DESF_STATE_GET_HW_VERSION : 611 612 /* Check and store the h/w and s/w specific details. 613 Ex: Major/Minor version, memory storage info. */ 614 Status = phFriNfc_Desfire_HGetSWVersion(NdefMap); 615 616 /* handle the error in Transc function*/ 617 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 618 { 619 /* call respective CR */ 620 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 621 } 622 623 break; 624 625 case PH_FRINFC_DESF_STATE_GET_SW_VERSION : 626 627 /* Check and store the h/w and s/w specific details. 628 Ex: Major/Minor version, memory storage info. */ 629 630 Status = phFriNfc_Desfire_HUpdateVersionDetails(NdefMap); 631 if ( Status == NFCSTATUS_SUCCESS ) 632 { 633 Status = phFriNfc_Desfire_HGetUIDDetails(NdefMap); 634 /* handle the error in Transc function*/ 635 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 636 { 637 /* call respective CR */ 638 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 639 } 640 } 641 642 break; 643 644 case PH_FRINFC_DESF_STATE_GET_UID : 645 646 /*Set the desfire operation flag*/ 647 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP; 648 649 /*Call Select Smart tag Functinality*/ 650 Status = phFriNfc_Desfire_SelectSmartTag(NdefMap); 651 652 break; 653 #endif /* #ifdef PH_HAL4_ENABLE */ 654 655 case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG: 656 657 if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) && 658 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE)) 659 { 660 Status = phFriNfc_Desfire_SelectFile(NdefMap); 661 662 /* handle the error in Transc function*/ 663 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 664 { 665 /* call respective CR */ 666 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 667 } 668 } 669 else 670 { 671 /*Error " Smart Tag Functionality Not Supported"*/ 672 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 673 NFCSTATUS_SMART_TAG_FUNC_NOT_SUPPORTED); 674 675 /* call respective CR */ 676 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 677 678 } 679 680 break; 681 682 case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_FILE : 683 684 if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) && 685 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE)) 686 { 687 /*check for the which operation */ 688 if( (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_READ_OP) || 689 (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP) || 690 (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP )) 691 { 692 /* call for read binary operation*/ 693 Status = phFriNfc_Desfire_ReadBinary(NdefMap); 694 695 /* handle the error in Transc function*/ 696 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER) ) 697 { 698 /* call respective CR */ 699 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 700 } 701 } 702 /*its a write Operation*/ 703 else if(NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_WRITE_OP ) 704 { 705 Status = phFriNfc_Desfire_UpdateBinary (NdefMap); 706 /* handle the error in Transc function*/ 707 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 708 { 709 /* call respective CR */ 710 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 711 } 712 } 713 else 714 { 715 /* unknown/invalid desfire operations*/ 716 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 717 NFCSTATUS_INVALID_REMOTE_DEVICE); 718 719 /* call respective CR */ 720 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 721 } 722 } 723 else 724 { 725 /*return Error " Select File Operation Failed"*/ 726 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 727 NFCSTATUS_INVALID_REMOTE_DEVICE); 728 729 /* call respective CR */ 730 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 731 } 732 break; 733 734 case PH_FRINFC_NDEFMAP_DESF_STATE_READ_CAP_CONT: 735 if( (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength)-2)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) && 736 (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength)-1)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE)) 737 { 738 /* Read successful. */ 739 /*Update the smart tag capability container*/ 740 Status = phFriNfc_Desfire_Update_SmartTagCapContainer(NdefMap); 741 742 if ( Status == NFCSTATUS_SUCCESS) 743 { 744 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP; 745 Status = phFriNfc_Desfire_HSetGet_NLEN(NdefMap); 746 /* handle the error in Transc function*/ 747 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER)) 748 { 749 /* call respective CR */ 750 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 751 } 752 } 753 else 754 { 755 /* call respective CR */ 756 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 757 758 } 759 760 } 761 else 762 { 763 /*return Error " Capability Container Not Found"*/ 764 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 765 NFCSTATUS_INVALID_REMOTE_DEVICE); 766 /* call respective CR */ 767 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 768 } 769 break; 770 771 case PH_FRINFC_NDEFMAP_DESF_STATE_READ_BIN: 772 773 /* Check how many bytes have been read/returned from the card*/ 774 BytesRead = phFriNfc_Desfire_HGetLeBytes(NdefMap); 775 776 /* set the send recev len*/ 777 SendRecLen = *NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET ); 778 if ( (NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1) && ((BytesRead == 1) || (BytesRead == 2 ))) 779 { 780 BytesRead += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES; /* to take care of first 2 len bytes*/ 781 782 } 783 else 784 { 785 /* Nothing to process*/ 786 ; 787 } 788 /* Read More Number Of Bytes than Expected*/ 789 if ( ( BytesRead == SendRecLen ) && 790 ((NdefMap->SendRecvBuf[(*NdefMap->SendRecvLength-2)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) && 791 (NdefMap->SendRecvBuf[(*NdefMap->SendRecvLength-1)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))) 792 793 { 794 /* this is to check the card state in first Read Operation*/ 795 if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP ) 796 { 797 /* check the actual length of the ndef data : NLEN*/ 798 NLength = ( (((uint16_t)NdefMap->SendRecvBuf[0])<<PH_FRINFC_NDEFMAP_DESF_SHL8)+ \ 799 NdefMap->SendRecvBuf[1]); 800 if (( NLength > PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE )|| 801 ( NLength == 0xFFFF)) 802 { 803 ErrFlag = 1; 804 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 805 NFCSTATUS_NO_NDEF_SUPPORT); 806 } 807 else 808 { 809 /* Store the NLEN into the context */ 810 NdefMap->DesfireCapContainer.NdefDataLen = NLength; 811 812 Status = phFriNfc_MapTool_SetCardState( NdefMap, 813 NLength); 814 if ( Status == NFCSTATUS_SUCCESS ) 815 { 816 /*Set the card type to Desfire*/ 817 NdefMap->CardType = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD; 818 /*Set the state to specify True for Ndef Compliant*/ 819 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_CHK_NDEF; 820 /*set the data count back to zero*/; 821 *NdefMap->DataCount = 0; 822 /*set the apdu buffer index to zero*/ 823 NdefMap->ApduBuffIndex = 0; 824 /* Set the Operationg flag to Complete check NDEF Operation*/ 825 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP; 826 827 } 828 /* call respective CR */ 829 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 830 }/* End ofNdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP*/ 831 } 832 else if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_READ_OP ) 833 { 834 phFriNfc_Desfire_HProcReadData(NdefMap); 835 } 836 else 837 { 838 /* Invalid Desfire Operation */ 839 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 840 NFCSTATUS_INVALID_REMOTE_DEVICE); 841 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 842 } 843 844 } 845 else 846 { 847 /*handle the Error case*/ 848 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 849 NFCSTATUS_READ_FAILED); 850 ErrFlag =1; 851 } 852 if( ErrFlag == 1) 853 { 854 *NdefMap->DataCount = 0; 855 856 /*set the buffer index back to zero*/ 857 NdefMap->ApduBuffIndex = 0; 858 859 /* call respective CR */ 860 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 861 } 862 863 break; 864 865 case PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_BEGIN: 866 if( (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) && 867 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE)) 868 { 869 /* Write operation was successful. */ 870 /* NdefMap->NumOfBytesWritten have been written on to the card. 871 Update the DataCount and the ApduBufferIndex */ 872 *NdefMap->DataCount += NdefMap->NumOfBytesWritten; 873 NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten; 874 875 /* Update the user-provided buffer size to write */ 876 *NdefMap->WrNdefPacketLength += NdefMap->NumOfBytesWritten; 877 878 /* Call Upadte Binary function to check if some more bytes are to be written. */ 879 Status = phFriNfc_Desfire_UpdateBinary( NdefMap ); 880 } 881 else 882 { 883 /*handle the Error case*/ 884 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 885 NFCSTATUS_WRITE_FAILED); 886 887 /*set the buffer index back to zero*/ 888 NdefMap->ApduBuffIndex = 0; 889 890 /* call respective CR */ 891 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 892 } 893 break; 894 case PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_END : 895 if((NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) && 896 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE)) 897 { 898 /* Updating NLEN operation was successful. */ 899 /* Entire Write Operation is complete*/ 900 /* Reset the relevant parameters. */ 901 Status = PHNFCSTVAL(CID_NFC_NONE,\ 902 NFCSTATUS_SUCCESS); 903 904 /* set the state & Data len into context*/ 905 NdefMap->CardState = ((NdefMap->CardState == 906 PH_NDEFMAP_CARD_STATE_INITIALIZED)? 907 PH_NDEFMAP_CARD_STATE_READ_WRITE: 908 NdefMap->CardState); 909 910 NdefMap->DesfireCapContainer.NdefDataLen = (uint16_t)(*NdefMap->WrNdefPacketLength); 911 #ifdef PH_HAL4_ENABLE 912 /* Do nothing */ 913 #else 914 NdefMap->PrevOperation = 0; 915 #endif /* #ifndef PH_HAL4_ENABLE */ 916 917 } 918 else 919 { 920 NdefMap->PrevOperation = 0; 921 /*handle the Error case*/ 922 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 923 NFCSTATUS_WRITE_FAILED); 924 } 925 926 /*set the buffer index back to zero*/ 927 NdefMap->ApduBuffIndex = 0; 928 929 /* call respective CR */ 930 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 931 break; 932 933 default: 934 /*define the invalid state*/ 935 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\ 936 NFCSTATUS_INVALID_DEVICE_REQUEST); 937 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 938 break; 939 } 940 } 941 else 942 { 943 /* call respective CR */ 944 phFriNfc_Desfire_HCrHandler(NdefMap,Status); 945 } 946 } 947 948 949 950 /*! 951 * \brief this shall select the smart tag functinality of the Desfire card. 952 * 953 * Only when this command returns command completed it is a Smart Tag 954 * compatible product. 955 * 956 */ 957 static 958 NFCSTATUS phFriNfc_Desfire_SelectSmartTag(phFriNfc_NdefMap_t *NdefMap) 959 { 960 961 NFCSTATUS status = NFCSTATUS_PENDING; 962 963 /*form the packet for Select smart tag command*/ 964 NdefMap->SendRecvBuf[0] = 0x00; /* cls */ 965 NdefMap->SendRecvBuf[1] = 0xa4; /* ins */ 966 NdefMap->SendRecvBuf[2] = 0x04; /* p1 */ 967 NdefMap->SendRecvBuf[3] = 0x00; /* p2 */ 968 NdefMap->SendRecvBuf[4] = 0x07; /* lc */ 969 970 /* next 7 bytes specify the DF Name*/ 971 NdefMap->SendRecvBuf[5] = 0xd2; 972 NdefMap->SendRecvBuf[6] = 0x76; 973 NdefMap->SendRecvBuf[7] = 0x00; 974 NdefMap->SendRecvBuf[8] = 0x00; 975 NdefMap->SendRecvBuf[9] = 0x85; 976 NdefMap->SendRecvBuf[10] = 0x01; 977 NdefMap->SendRecvBuf[11] = 0x00; 978 979 /*Set the Send length*/ 980 NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_SMARTTAG_PKT_SIZE; 981 982 /* Change the state to Select Smart Tag */ 983 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG; 984 985 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET); 986 987 return status; 988 } 989 990 /*! 991 * \brief this shall select/access the capability container of the Desfire 992 * card. 993 * 994 * This shall be used to identify, if NDEF data structure do exist on 995 * the smart tag, we receive command completed status. 996 * 997 */ 998 static 999 NFCSTATUS phFriNfc_Desfire_SelectFile (phFriNfc_NdefMap_t *NdefMap) 1000 { 1001 1002 NFCSTATUS status = NFCSTATUS_PENDING; 1003 1004 /* check for the invalid/unknown desfire operations*/ 1005 if ((NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP)&& \ 1006 (NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_READ_OP)&&\ 1007 ( NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_WRITE_OP) && 1008 ( NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP)) 1009 { 1010 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE); 1011 } 1012 else 1013 { 1014 1015 /* Set the command*/ 1016 //NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd; 1017 1018 /* Form the packet for select file command either for the 1019 Check Ndef/Read/Write functionalities*/ 1020 NdefMap->SendRecvBuf[0] = 0x00; /* cls */ 1021 NdefMap->SendRecvBuf[1] = 0xa4; /* ins */ 1022 NdefMap->SendRecvBuf[2] = 0x00; /* p1 */ 1023 NdefMap->SendRecvBuf[3] = 0x00; /* p2 */ 1024 NdefMap->SendRecvBuf[4] = 0x02; /* lc */ 1025 1026 if ( (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP)) 1027 1028 { 1029 /* cap container file identifier*/ 1030 NdefMap->SendRecvBuf[5] = 0xe1; 1031 NdefMap->SendRecvBuf[6] = 0x03; 1032 } 1033 /* Mantis entry 0394 fixed */ 1034 else 1035 { 1036 NdefMap->SendRecvBuf[5] = (uint8_t)((NdefMap->DesfireCapContainer.NdefMsgFid) >> PH_FRINFC_NDEFMAP_DESF_SHL8); 1037 NdefMap->SendRecvBuf[6] = (uint8_t)((NdefMap->DesfireCapContainer.NdefMsgFid) & (0x00ff)); 1038 } 1039 /*Set the Send length*/ 1040 NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_SELECT_FILE_PKT_SIZE; 1041 1042 /* Change the state to Select File */ 1043 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_FILE; 1044 1045 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET); 1046 1047 } 1048 1049 return status; 1050 1051 } 1052 1053 /*! 1054 * \brief this shall read the data from Desfire card. 1055 * 1056 * This is used in two cases namely Reading the Capability container 1057 * data( le == 0 ) and reading the file data.Maximum bytes to be read during 1058 * a single read binary is known after the reading the data from the capability 1059 * conatainer. 1060 * 1061 */ 1062 static 1063 NFCSTATUS phFriNfc_Desfire_ReadBinary(phFriNfc_NdefMap_t *NdefMap) 1064 { 1065 NFCSTATUS status = NFCSTATUS_PENDING; 1066 uint32_t BytesToRead = 0; 1067 uint8_t BufIndex=0,OperFlag=0; 1068 uint16_t DataCnt=0; 1069 1070 /* to read the capability container data*/ 1071 if (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP ) 1072 { 1073 /*specifies capability container shall be read*/ 1074 NdefMap->SendRecvBuf[0] = 0x00; 1075 NdefMap->SendRecvBuf[1] = 0xb0; 1076 NdefMap->SendRecvBuf[2] = 0x00; /* p1 */ 1077 NdefMap->SendRecvBuf[3] = 0x00; /* p2 */ 1078 NdefMap->SendRecvBuf[4] = 0x0F; /* le */ 1079 1080 NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_READ_BIN_PKT_SIZE; 1081 1082 /* Change the state to Cap Container Read */ 1083 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_READ_CAP_CONT; 1084 1085 /* set the send receive buffer length*/ 1086 OperFlag = 1; 1087 } 1088 /*desfire file read operation*/ 1089 else 1090 { 1091 NdefMap->SendRecvBuf[0] = 0x00; 1092 NdefMap->SendRecvBuf[1] = 0xb0; 1093 1094 /*TBD the NLEN bytes*/ 1095 if( *NdefMap->DataCount == 0 ) 1096 { 1097 /* first read */ 1098 /* set the offset p1 and p2*/ 1099 NdefMap->SendRecvBuf[2] = 0; 1100 NdefMap->SendRecvBuf[3] = 0; 1101 } 1102 else 1103 { 1104 /* as the p1 of the 8bit is 0, p1 and p2 are used to store the 1105 ofset value*/ 1106 DataCnt = *NdefMap->DataCount; 1107 DataCnt += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES; 1108 NdefMap->SendRecvBuf[2] = (uint8_t)((DataCnt)>> PH_FRINFC_NDEFMAP_DESF_SHL8); 1109 NdefMap->SendRecvBuf[3] = (uint8_t)((DataCnt)& (0x00ff)); 1110 } 1111 /* calculate the Le Byte*/ 1112 BytesToRead = phFriNfc_Desfire_HGetLeBytes(NdefMap); 1113 1114 if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN ) 1115 { 1116 /* BufIndex represents the 2 NLEN bytes and decides about the presence of 1117 2 bytes NLEN data*/ 1118 1119 BufIndex = (uint8_t)(( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1 ) ? 1120 PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES:0); 1121 1122 if( ((BytesToRead == 1) || (BytesToRead == 2)) && (NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1)) 1123 { 1124 BytesToRead += BufIndex; 1125 } 1126 } 1127 1128 /* set the Le byte*/ 1129 /* This following code is true for get nlen and current offset set*/ 1130 NdefMap->SendRecvBuf[4]=(uint8_t) BytesToRead ; 1131 1132 /* Change the state to Read */ 1133 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_READ_BIN; 1134 1135 /*set the send length*/ 1136 NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_READ_BIN_PKT_SIZE; 1137 OperFlag = 2; 1138 } 1139 1140 if (OperFlag == 1 ) 1141 { 1142 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE); 1143 } 1144 else 1145 { 1146 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,(uint8_t)(BytesToRead +PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET)); 1147 } 1148 return (status); 1149 } 1150 1151 /*! 1152 * \brief this shall write the data to Desfire card. 1153 * Maximum bytes to be written during a single update binary 1154 * is known after the reading the data from the capability 1155 * conatainer. 1156 * 1157 * le filed specifes , how many bytes of data to be written to the 1158 * Card. 1159 * 1160 */ 1161 static 1162 NFCSTATUS phFriNfc_Desfire_UpdateBinary(phFriNfc_NdefMap_t *NdefMap) 1163 { 1164 1165 NFCSTATUS status = NFCSTATUS_PENDING; 1166 uint16_t noOfBytesToWrite = 0, DataCnt=0, 1167 index=0; 1168 1169 /* Do we have space in the file to write? */ 1170 if ( (*NdefMap->DataCount < PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) && 1171 (NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize)) 1172 { 1173 /* Yes, we have some bytes to write */ 1174 /* Check and set the card memory size , if user sent bytes are more than the 1175 card memory size*/ 1176 if( (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >\ 1177 (uint16_t)(PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE - *NdefMap->DataCount)) 1178 { 1179 NdefMap->ApduBufferSize =( (PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) - (*NdefMap->DataCount + NdefMap->ApduBuffIndex)); 1180 } 1181 1182 /* Now, we have space in the card to write the data, */ 1183 /*Form the packet for the update binary command*/ 1184 NdefMap->SendRecvBuf[0] = 0x00; 1185 NdefMap->SendRecvBuf[1] = 0xD6; 1186 1187 if( *NdefMap->DataCount == 0) 1188 { 1189 /* set the p1/p2 offsets */ 1190 NdefMap->SendRecvBuf[2] = 0x00; /* p1 */ 1191 NdefMap->SendRecvBuf[3] = 0x00; /* p2 */ 1192 NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 0; 1193 } 1194 else 1195 { 1196 /* as the p1 of the 8bit is 0, p1 and p2 are used to store the 1197 ofset value*/ 1198 /* This sets card offset in a card for a write operation. + 2 is 1199 added as first 2 offsets represents the size of the NDEF Len present 1200 in the file*/ 1201 1202 DataCnt = *NdefMap->DataCount; 1203 DataCnt += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES; 1204 NdefMap->SendRecvBuf[2] = (uint8_t)((DataCnt)>> PH_FRINFC_NDEFMAP_DESF_SHL8); 1205 NdefMap->SendRecvBuf[3] = (uint8_t)((DataCnt)& (0x00ff)); 1206 /* No need to attach 2 NLEN bytes at the begining. 1207 as we have already attached in the first write operation.*/ 1208 NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 1; 1209 1210 } 1211 1212 /* Calculate the bytes to write */ 1213 if( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)( NdefMap->DesfireCapContainer.MaxCmdSize )) 1214 1215 { 1216 noOfBytesToWrite = ( ( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1) ? 1217 NdefMap->DesfireCapContainer.MaxCmdSize : 1218 (NdefMap->DesfireCapContainer.MaxCmdSize - PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES)); 1219 } 1220 else 1221 { 1222 /* Read only till the available buffer space */ 1223 noOfBytesToWrite = (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 1224 } 1225 1226 if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN ) 1227 { 1228 if ( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1 ) 1229 { 1230 index = 5; 1231 /* To Specify the NDEF data len written : updated at the of write cycle*/ 1232 NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite; 1233 } 1234 else 1235 { 1236 /* Leave space to update NLEN */ 1237 NdefMap->SendRecvBuf[5] = 0x00; 1238 NdefMap->SendRecvBuf[6] = 0x00; 1239 index =7; 1240 /* To Specify the NDEF data len written : updated at the of write cycle*/ 1241 NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite + PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES; 1242 } 1243 1244 /* copy the data to SendRecvBuf from the apdu buffer*/ 1245 (void)memcpy( &NdefMap->SendRecvBuf[index], 1246 &NdefMap->ApduBuffer[NdefMap->ApduBuffIndex], 1247 noOfBytesToWrite); 1248 NdefMap->SendLength = (noOfBytesToWrite + index); 1249 } 1250 else 1251 { 1252 NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite; 1253 1254 /* copy the data to SendRecvBuf from the apdu buffer*/ 1255 (void)memcpy( &NdefMap->SendRecvBuf[5], 1256 &NdefMap->ApduBuffer[NdefMap->ApduBuffIndex], 1257 noOfBytesToWrite); 1258 NdefMap->SendLength = (noOfBytesToWrite + 5); 1259 } 1260 1261 /* Store the number of bytes being written in the context structure, so that 1262 the parameters can be updated, after a successful write operation. */ 1263 NdefMap->NumOfBytesWritten = noOfBytesToWrite; 1264 1265 /* Change the state to Write */ 1266 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_BEGIN; 1267 1268 status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET); 1269 1270 } /* if(NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize) */ 1271 else 1272 { 1273 if ( (*NdefMap->DataCount == PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) || 1274 (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize)) 1275 { 1276 /* The NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_SET_LEN_OP is not 1277 required, because the DespOpFlag shall be WRITE_OP 1278 */ 1279 /* Update the NLEN Bytes*/ 1280 #ifdef PH_HAL4_ENABLE 1281 /* Do nothing */ 1282 #else 1283 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_SET_LEN_OP; 1284 #endif /* #ifdef PH_HAL4_ENABLE */ 1285 status = phFriNfc_Desfire_HSetGet_NLEN(NdefMap); 1286 } 1287 else 1288 { 1289 /* The control should not come here. 1290 wrong internal calculation. 1291 we have actually written more than the space available 1292 in the card ! */ 1293 #ifndef PH_HAL4_ENABLE 1294 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1295 NFCSTATUS_CMD_ABORTED); 1296 #else 1297 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1298 NFCSTATUS_FAILED); 1299 #endif 1300 /* Reset the relevant parameters. */ 1301 NdefMap->ApduBuffIndex = 0; 1302 NdefMap->PrevOperation = 0; 1303 1304 /* call respective CR */ 1305 phFriNfc_Desfire_HCrHandler(NdefMap,status); 1306 } 1307 1308 } 1309 /* if(*NdefMap->DataCount < PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) */ 1310 1311 return status; 1312 } 1313 1314 1315 static void phFriNfc_Desfire_HChkNDEFFileAccessRights(phFriNfc_NdefMap_t *NdefMap) 1316 { 1317 if ( (NdefMap->DesfireCapContainer.ReadAccess == 0x00) && 1318 (NdefMap->DesfireCapContainer.WriteAccess == 0x00 )) 1319 { 1320 /* Set the card state to Read/write State*/ 1321 /* This state can be either INITIALISED or READWRITE. but default 1322 is INITIALISED */ 1323 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE; 1324 1325 } 1326 else if((NdefMap->DesfireCapContainer.ReadAccess == 0x00) && 1327 (NdefMap->DesfireCapContainer.WriteAccess == 0xFF )) 1328 { 1329 /* Set the card state to Read Only State*/ 1330 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY; 1331 } 1332 else 1333 { 1334 /* Set the card state to invalid State*/ 1335 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID; 1336 } 1337 } 1338 1339 /*! 1340 * \brief this shall update the Desfire capability container structure. 1341 * 1342 * This function shall store version,maximum Ndef data structure size, 1343 * Read Access permissions, Write Access permissions , Maximum data size 1344 * that can be sent using a single Update Binary, maximum data size that 1345 * can be read from the Desfire using a singlr read binary. 1346 * These vaues shall be stored and used during the read/update binary 1347 * operations. 1348 * 1349 */ 1350 static 1351 NFCSTATUS phFriNfc_Desfire_Update_SmartTagCapContainer(phFriNfc_NdefMap_t *NdefMap) 1352 { 1353 uint16_t CapContSize = 0, 1354 /* this is initalised 2 because CCLEN includes the field size bytes i.e 2bytes*/ 1355 CCLen= 0; 1356 uint8_t ErrFlag = 0; 1357 1358 NFCSTATUS status= NFCSTATUS_SUCCESS; 1359 1360 /*Check the Size of Cap Container */ 1361 CapContSize = ( (((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_FIRST_INDEX])<<8)+ \ 1362 NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_SECOND_INDEX]); 1363 1364 CCLen += 2; 1365 1366 if ( (CapContSize < 0x0f) || (CapContSize == 0xffff)) 1367 { 1368 ErrFlag =1; 1369 } 1370 else 1371 { 1372 /*Version : Smart Tag Spec version */ 1373 /* check for the validity of Major and Minor Version numbers*/ 1374 status = phFriNfc_MapTool_ChkSpcVer ( NdefMap, 1375 PH_FRINFC_NDEFMAP_DESF_VER_INDEX); 1376 if ( status != NFCSTATUS_SUCCESS ) 1377 { 1378 ErrFlag =1; 1379 } 1380 else 1381 { 1382 CCLen += 1; 1383 1384 /*Get Response APDU data size 1385 to check the integration s/w response size*/ 1386 #ifdef PH_HAL4_ENABLE 1387 { 1388 uint16_t max_rsp_size = 1389 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_FIRST_INDEX]) << 8)\ 1390 + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_SECOND_INDEX]); 1391 NdefMap->DesfireCapContainer.MaxRespSize = 1392 ((max_rsp_size > PHHAL_MAX_DATASIZE)? 1393 (PHHAL_MAX_DATASIZE) : max_rsp_size); 1394 } 1395 #else 1396 NdefMap->DesfireCapContainer.MaxRespSize = 1397 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_FIRST_INDEX]) << 8)\ 1398 +NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_SECOND_INDEX]); 1399 #endif /* #ifdef PH_HAL4_ENABLE */ 1400 1401 /*Get Command APDU data size*/ 1402 #ifdef PH_HAL4_ENABLE 1403 { 1404 uint16_t max_cmd_size = 1405 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_FIRST_INDEX])<<8)\ 1406 + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_SECOND_INDEX]); 1407 1408 NdefMap->DesfireCapContainer.MaxCmdSize = 1409 ((max_cmd_size > PHHAL_MAX_DATASIZE)? 1410 (PHHAL_MAX_DATASIZE): max_cmd_size); 1411 } 1412 #else 1413 NdefMap->DesfireCapContainer.MaxCmdSize = 1414 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_FIRST_INDEX])<<8)\ 1415 +NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_SECOND_INDEX]); 1416 #endif /* #ifdef PH_HAL4_ENABLE */ 1417 /* Check for the Validity of Cmd & Resp Size*/ 1418 /* check the Validity of the Cmd Size*/ 1419 if( (NdefMap->DesfireCapContainer.MaxRespSize < 0x0f) || 1420 ( NdefMap->DesfireCapContainer.MaxCmdSize == 0x00)) 1421 { 1422 ErrFlag=1; 1423 1424 } 1425 else 1426 { 1427 CCLen += 4; 1428 1429 /* Check and Parse the TLV structure */ 1430 /* In future this chk can be extended to Propritery TLV */ 1431 //status = phFriNfc_ChkAndParseTLV(NdefMap); 1432 status = phFriNfc_Desf_HChkAndParseTLV(NdefMap,PH_FRINFC_NDEFMAP_DESF_TLV_INDEX); 1433 if ( (status == NFCSTATUS_SUCCESS) && (NdefMap->TLVFoundFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CNTRL_TLV)) 1434 { 1435 CCLen += 1; 1436 1437 /* check the TLV length*/ 1438 if ( (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) > 0x00 ) && 1439 (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) <= 0xFE )&& 1440 (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) == 0x06 )) 1441 { 1442 CCLen +=1; 1443 /* store the contents in to the container structure*/ 1444 NdefMap->DesfireCapContainer.NdefMsgFid = ( (((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_FIRST_INDEX])<<PH_FRINFC_NDEFMAP_DESF_SHL8)+ \ 1445 NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_SECOND_INDEX]); 1446 1447 CCLen +=2; 1448 1449 /* Invalid Msg File Id : User Can't Have read/write Opeartion*/ 1450 if ( (NdefMap->DesfireCapContainer.NdefMsgFid == 0xFFFF) || 1451 (NdefMap->DesfireCapContainer.NdefMsgFid == 0xE102) || 1452 (NdefMap->DesfireCapContainer.NdefMsgFid == 0xE103) || 1453 (NdefMap->DesfireCapContainer.NdefMsgFid == 0x3F00) || 1454 (NdefMap->DesfireCapContainer.NdefMsgFid == 0x3FFF ) ) 1455 { 1456 1457 ErrFlag=1; 1458 } 1459 else 1460 { 1461 /*Get Ndef Size*/ 1462 NdefMap->DesfireCapContainer.NdefFileSize = 1463 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_FIRST_INDEX])<<8) 1464 | (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_SECOND_INDEX] & 0x00ff)); 1465 1466 1467 /*Check Ndef Size*/ 1468 /* TBD : Do we need to minus 2 bytes of size it self?*/ 1469 if ( ((NdefMap->DesfireCapContainer.NdefFileSize -2) <= 0x0004 ) || 1470 ((NdefMap->DesfireCapContainer.NdefFileSize -2) == 0xFFFD ) ) 1471 { 1472 ErrFlag=1; 1473 } 1474 else 1475 { 1476 CCLen +=2; 1477 1478 /*Ndef File Read Access*/ 1479 NdefMap->DesfireCapContainer.ReadAccess = NdefMap->\ 1480 SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILERD_ACCESS_INDEX] ; 1481 1482 /*Ndef File Write Access*/ 1483 NdefMap->DesfireCapContainer.WriteAccess = NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEWR_ACCESS_INDEX]; 1484 1485 CCLen +=2; 1486 1487 phFriNfc_Desfire_HChkNDEFFileAccessRights(NdefMap); 1488 } 1489 } 1490 } 1491 else 1492 { 1493 1494 /* TLV Lenth is of two byte value 1495 TBD: As the length of TLV is fixed for 6 bytes. We need not 1496 handle the 2 byte value*/ 1497 1498 1499 } 1500 } 1501 else 1502 { 1503 if ( NdefMap->TLVFoundFlag == PH_FRINFC_NDEFMAP_DESF_PROP_CNTRL_TLV ) 1504 { 1505 /*TBD: To Handle The Proprietery TLV*/ 1506 } 1507 else 1508 { 1509 /*Invalid T found case*/ 1510 ErrFlag =1; 1511 } 1512 } 1513 /* check for the entire LENGTH Validity 1514 CCLEN + TLV L value == CCLEN*/ 1515 if ( CapContSize != CCLen ) 1516 { 1517 ErrFlag=1; 1518 } 1519 1520 }/* if NdefMap->DesfireCapContainer.MaxRespSize < 0x0f */ 1521 }/* Chkeck Map Version*/ 1522 }/* CC size invalid*/ 1523 if( ErrFlag == 1 ) 1524 { 1525 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 1526 NFCSTATUS_NO_NDEF_SUPPORT); 1527 } 1528 return ( status ); 1529 } 1530 1531 static uint32_t phFriNfc_Desfire_HGetLeBytes(phFriNfc_NdefMap_t *NdefMap) 1532 { 1533 /*Represents the LE byte*/ 1534 uint16_t BytesToRead =0; 1535 1536 if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP ) 1537 { 1538 BytesToRead = PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES; 1539 NdefMap->DesfireCapContainer.SkipNlenBytesFlag =0; 1540 } 1541 else 1542 { 1543 1544 /* Calculate Le bytes : No of bytes to read*/ 1545 /* Check for User Apdu Buffer Size and Msg Size of Desfire Capability container */ 1546 if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= NdefMap->DesfireCapContainer.MaxRespSize) 1547 { 1548 /* We have enough buffer space to read the whole capability container 1549 size bytes 1550 Now, check do we have NdefMap->DesfireCapContainer.MaxRespSize to read ? */ 1551 1552 BytesToRead = (((NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount) >= 1553 NdefMap->DesfireCapContainer.MaxRespSize) ? 1554 NdefMap->DesfireCapContainer.MaxRespSize : 1555 (NdefMap->DesfireCapContainer.NdefDataLen - 1556 *NdefMap->DataCount)); 1557 } 1558 else 1559 { 1560 /* Read only till the available buffer space */ 1561 BytesToRead = (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex); 1562 if(BytesToRead >= (uint16_t)(NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount)) 1563 { 1564 BytesToRead = (NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount); 1565 } 1566 } 1567 1568 NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 1569 (uint8_t)(((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )&&( *NdefMap->DataCount == 0 )) ? 1570 1 : 0); 1571 1572 } 1573 return (BytesToRead); 1574 } 1575 1576 1577 1578 /*! 1579 * \brief this shall notify the integration software with respective 1580 * success/error status along with the completion routines. 1581 * 1582 * This routine is called from the desfire process function. 1583 * 1584 */ 1585 1586 static void phFriNfc_Desfire_HCrHandler( phFriNfc_NdefMap_t *NdefMap, 1587 NFCSTATUS Status) 1588 { 1589 /* set the state back to the Reset_Init state*/ 1590 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT; 1591 1592 switch(NdefMap->DespOpFlag) 1593 { 1594 /* check which routine has the problem and set the CR*/ 1595 case PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP : 1596 /* set the completion routine*/ 1597 NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_CHK_NDEF].\ 1598 CompletionRoutine(NdefMap->CompletionRoutine->Context,\ 1599 Status); 1600 break; 1601 1602 case PH_FRINFC_NDEFMAP_DESF_READ_OP : 1603 /* set the completion routine*/ 1604 NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_RD_NDEF].\ 1605 CompletionRoutine(NdefMap->CompletionRoutine->Context,\ 1606 Status); 1607 break; 1608 1609 case PH_FRINFC_NDEFMAP_DESF_WRITE_OP : 1610 /* set the completion routine*/ 1611 NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_WR_NDEF].\ 1612 CompletionRoutine(NdefMap->CompletionRoutine->Context,\ 1613 Status); 1614 break; 1615 1616 default : 1617 /* set the completion routine*/ 1618 NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_INVALID_OPE].\ 1619 CompletionRoutine(NdefMap->CompletionRoutine->Context,\ 1620 Status); 1621 break; 1622 1623 } 1624 } 1625 1626 static NFCSTATUS phFriNfc_Desfire_HSendTransCmd(phFriNfc_NdefMap_t *NdefMap,uint8_t SendRecvLen) 1627 { 1628 1629 NFCSTATUS status = NFCSTATUS_SUCCESS; 1630 1631 /* set the command type*/ 1632 #ifndef PH_HAL4_ENABLE 1633 NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd; 1634 #else 1635 NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_Raw; 1636 #endif 1637 1638 /* set the Additional Info*/ 1639 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 1640 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; 1641 1642 /*set the completion routines for the desfire card operations*/ 1643 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Desfire_Process; 1644 NdefMap->MapCompletionInfo.Context = NdefMap; 1645 1646 /* set the receive length */ 1647 *NdefMap->SendRecvLength = ((uint16_t)(SendRecvLen)); 1648 1649 1650 /*Call the Overlapped HAL Transceive function */ 1651 status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice, 1652 &NdefMap->MapCompletionInfo, 1653 NdefMap->psRemoteDevInfo, 1654 NdefMap->Cmd, 1655 &NdefMap->psDepAdditionalInfo, 1656 NdefMap->SendRecvBuf, 1657 NdefMap->SendLength, 1658 NdefMap->SendRecvBuf, 1659 NdefMap->SendRecvLength); 1660 1661 return (status); 1662 1663 1664 } 1665 1666 1667 #ifdef UNIT_TEST 1668 #include <phUnitTestNfc_Desfire_static.c> 1669 #endif 1670 1671 #endif /* PH_FRINFC_MAP_DESFIRE_DISABLED */ 1672