1 /* 2 * Copyright (C) 2015 The Android Open Source Project 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 #ifdef ESE_NFC_SYNCHRONIZATION 18 #include <linux/ese-nfc-sync.h> 19 #endif 20 #include <fcntl.h> 21 #include <sys/ioctl.h> 22 #include <sys/time.h> 23 24 #include <phNxpExtns_MifareStd.h> 25 #include <phNxpLog.h> 26 #include <phNxpConfig.h> 27 28 phNxpExtns_Context_t gphNxpExtns_Context; 29 extern phFriNfc_NdefMap_t *NdefMap; 30 extern phNci_mfc_auth_cmd_t gAuthCmdBuf; 31 32 static NFCSTATUS phNxpExtns_ProcessSysMessage (phLibNfc_Message_t *msg); 33 static NFCSTATUS phNxpExtns_SendMsg (phLibNfc_Message_t *sysmsg); 34 35 #ifdef ESE_NFC_SYNCHRONIZATION 36 /* timing calculation structure*/ 37 typedef struct time_cal 38 { 39 struct timeval tv1; 40 struct timeval tv2; 41 } TimeCal; 42 static int fd_ese_nfc_sync; /*file descriptor to hold sync driver handle*/ 43 #endif 44 45 /******************************************************************************* 46 ** 47 ** Function EXTNS_Init 48 ** 49 ** Description This function Initializes Mifare Classic Extns. Allocates 50 ** required memory and initializes the Mifare Classic Vars 51 ** 52 ** Returns NFCSTATUS_SUCCESS if successfully initialized 53 ** NFCSTATUS_FAILED otherwise 54 ** 55 *******************************************************************************/ 56 NFCSTATUS EXTNS_Init (tNFA_DM_CBACK *p_nfa_dm_cback, 57 tNFA_CONN_CBACK *p_nfa_conn_cback) 58 { 59 NFCSTATUS status = NFCSTATUS_FAILED; 60 61 /* reset config cache */ 62 resetNxpConfig (); 63 64 /* Initialize Log level */ 65 phNxpLog_InitializeLogLevel (); 66 67 /* Validate parameters */ 68 if ((!p_nfa_dm_cback) || (!p_nfa_conn_cback)) 69 { 70 NXPLOG_EXTNS_E ("EXTNS_Init(): error null callback"); 71 goto clean_and_return; 72 } 73 74 gphNxpExtns_Context.p_dm_cback = p_nfa_dm_cback; 75 gphNxpExtns_Context.p_conn_cback = p_nfa_conn_cback; 76 77 if (NFCSTATUS_SUCCESS != phNxpExtns_MfcModuleInit ()) 78 { 79 NXPLOG_EXTNS_E ("ERROR: MFC Module Init Failed"); 80 goto clean_and_return; 81 } 82 gphNxpExtns_Context.Extns_status = EXTNS_STATUS_OPEN; 83 84 status = NFCSTATUS_SUCCESS; 85 return status; 86 87 clean_and_return: 88 gphNxpExtns_Context.Extns_status = EXTNS_STATUS_CLOSE; 89 return status; 90 } 91 92 /******************************************************************************* 93 ** 94 ** Function EXTNS_Close 95 ** 96 ** Description This function de-initializes Mifare Classic Extns. 97 ** De-allocates memory 98 ** 99 ** Returns None 100 ** 101 *******************************************************************************/ 102 void EXTNS_Close (void) 103 { 104 gphNxpExtns_Context.Extns_status = EXTNS_STATUS_CLOSE; 105 phNxpExtns_MfcModuleDeInit (); 106 return; 107 } 108 109 /******************************************************************************* 110 ** 111 ** Function EXTNS_MfcCallBack 112 ** 113 ** Description Decodes Mifare Classic Tag Response 114 ** This is called from NFA_SendRaw Callback 115 ** 116 ** Returns: 117 ** NFCSTATUS_SUCCESS if successfully initiated 118 ** NFCSTATUS_FAILED otherwise 119 ** 120 *******************************************************************************/ 121 NFCSTATUS EXTNS_MfcCallBack (uint8_t *buf, uint32_t buflen) 122 { 123 NFCSTATUS status = NFCSTATUS_SUCCESS; 124 125 phLibNfc_Message_t msg; 126 127 msg.eMsgType = PH_NXPEXTNS_RX_DATA; 128 msg.pMsgData = buf; 129 msg.Size = buflen; 130 131 status = phNxpExtns_SendMsg (&msg); 132 if (NFCSTATUS_SUCCESS != status) 133 { 134 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 135 } 136 return status; 137 } 138 139 /******************************************************************************* 140 ** 141 ** Function EXTNS_MfcCheckNDef 142 ** 143 ** Description Performs NDEF detection for Mifare Classic Tag 144 ** 145 ** Upon successful completion of NDEF detection, a 146 ** NFA_NDEF_DETECT_EVT will be sent, to notify the application 147 ** of the NDEF attributes (NDEF total memory size, current 148 ** size, etc.). 149 ** 150 ** Returns: 151 ** NFCSTATUS_SUCCESS if successfully initiated 152 ** NFCSTATUS_FAILED otherwise 153 ** 154 *******************************************************************************/ 155 NFCSTATUS EXTNS_MfcCheckNDef (void) 156 { 157 NFCSTATUS status = NFCSTATUS_SUCCESS; 158 phLibNfc_Message_t msg; 159 160 msg.eMsgType = PH_NXPEXTNS_MIFARE_CHECK_NDEF; 161 msg.pMsgData = NULL; 162 msg.Size = 0; 163 164 status = phNxpExtns_SendMsg (&msg); 165 if (NFCSTATUS_SUCCESS != status) 166 { 167 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 168 } 169 170 return status; 171 } 172 173 /******************************************************************************* 174 ** 175 ** Function EXTNS_MfcReadNDef 176 ** 177 ** Description Reads NDEF message from Mifare Classic Tag. 178 ** 179 ** Upon receiving the NDEF message, the message will be sent to 180 ** the handler registered with EXTNS_MfcRegisterNDefTypeHandler. 181 ** 182 ** Returns: 183 ** NFCSTATUS_SUCCESS if successfully initiated 184 ** NFCSTATUS_FAILED otherwise 185 ** 186 *******************************************************************************/ 187 NFCSTATUS EXTNS_MfcReadNDef (void) 188 { 189 NFCSTATUS status = NFCSTATUS_SUCCESS; 190 191 phLibNfc_Message_t msg; 192 193 msg.eMsgType = PH_NXPEXTNS_MIFARE_READ_NDEF; 194 msg.pMsgData = NULL; 195 msg.Size = 0; 196 197 status = phNxpExtns_SendMsg (&msg); 198 if (NFCSTATUS_SUCCESS != status) 199 { 200 NXPLOG_EXTNS_E("Error Sending msg to Extension Thread"); 201 } 202 203 return status; 204 } 205 /******************************************************************************* 206 ** 207 ** Function EXTNS_MfcPresenceCheck 208 ** 209 ** Description Do the check presence for Mifare Classic Tag. 210 ** 211 ** 212 ** Returns: 213 ** NFCSTATUS_SUCCESS if successfully initiated 214 ** NFCSTATUS_FAILED otherwise 215 ** 216 *******************************************************************************/ 217 NFCSTATUS EXTNS_MfcPresenceCheck (void) 218 { 219 NFCSTATUS status = NFCSTATUS_SUCCESS; 220 221 phLibNfc_Message_t msg; 222 223 msg.eMsgType = PH_NXPEXTNS_MIFARE_PRESENCE_CHECK; 224 msg.pMsgData = NULL; 225 msg.Size = 0; 226 227 gAuthCmdBuf.status = NFCSTATUS_FAILED; 228 if (sem_init (&gAuthCmdBuf.semPresenceCheck, 0, 0) == -1) 229 { 230 ALOGE ("%s: semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno); 231 return NFCSTATUS_FAILED; 232 } 233 234 status = phNxpExtns_SendMsg (&msg); 235 if (NFCSTATUS_SUCCESS != status) 236 { 237 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 238 sem_destroy (&gAuthCmdBuf.semPresenceCheck); 239 } 240 241 return status; 242 } 243 244 /******************************************************************************* 245 ** 246 ** Function EXTNS_MfcSetReadOnly 247 ** 248 ** 249 ** Description: 250 ** Sets tag as read only. 251 ** 252 ** When tag is set as read only, or if an error occurs, the app will be 253 ** notified with NFA_SET_TAG_RO_EVT. 254 ** 255 ** Returns: 256 ** NFCSTATUS_SUCCESS if successfully initiated 257 ** NFCSTATUS_FAILED otherwise 258 ** 259 *******************************************************************************/ 260 NFCSTATUS EXTNS_MfcSetReadOnly (uint8_t *key, uint8_t len) 261 { 262 NFCSTATUS status = NFCSTATUS_SUCCESS; 263 264 phLibNfc_Message_t msg; 265 266 msg.eMsgType = PH_NXPEXTNS_MIFARE_READ_ONLY; 267 msg.pMsgData = key; 268 msg.Size = len; 269 270 status = phNxpExtns_SendMsg (&msg); 271 if (NFCSTATUS_SUCCESS != status) 272 { 273 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 274 } 275 276 return status; 277 } 278 279 /******************************************************************************* 280 ** 281 ** Function EXTNS_MfcWriteNDef 282 ** 283 ** Description Writes NDEF data to Mifare Classic Tag. 284 ** 285 ** When the entire message has been written, or if an error 286 ** occurs, the app will be notified with NFA_WRITE_CPLT_EVT. 287 ** 288 ** p_data needs to be persistent until NFA_WRITE_CPLT_EVT 289 ** 290 ** Returns: 291 ** NFCSTATUS_SUCCESS if successfully initiated 292 ** NFCSTATUS_FAILED otherwise 293 ** 294 *******************************************************************************/ 295 NFCSTATUS EXTNS_MfcWriteNDef (uint8_t *p_data, uint32_t len) 296 { 297 NFCSTATUS status = NFCSTATUS_SUCCESS; 298 299 phLibNfc_Message_t msg; 300 301 msg.eMsgType = PH_NXPEXTNS_MIFARE_WRITE_NDEF; 302 msg.pMsgData = p_data; 303 msg.Size = len; 304 305 status = phNxpExtns_SendMsg (&msg); 306 if (NFCSTATUS_SUCCESS != status) 307 { 308 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 309 } 310 311 return status; 312 } 313 314 /***************************************************************************** 315 ** 316 ** Function EXTNS_MfcFormatTag 317 ** 318 ** Description Formats Mifare Classic Tag. 319 ** 320 ** The NFA_RW_FORMAT_CPLT_EVT, status is used to 321 ** indicate if tag is successfully formated or not 322 ** 323 ** Returns 324 ** NFCSTATUS_SUCCESS if successfully initiated 325 ** NFCSTATUS_FAILED otherwise 326 ** 327 *****************************************************************************/ 328 NFCSTATUS EXTNS_MfcFormatTag (uint8_t *key, uint8_t len) 329 { 330 NFCSTATUS status = NFCSTATUS_SUCCESS; 331 332 phLibNfc_Message_t msg; 333 334 msg.eMsgType = PH_NXPEXTNS_MIFARE_FORMAT_NDEF; 335 msg.pMsgData = key; 336 msg.Size = len; 337 338 status = phNxpExtns_SendMsg (&msg); 339 if (NFCSTATUS_SUCCESS != status) 340 { 341 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 342 } 343 344 return status; 345 } 346 347 /***************************************************************************** 348 ** 349 ** Function EXTNS_MfcDisconnect 350 ** 351 ** Description Disconnects Mifare Classic Tag. 352 ** 353 ** Returns 354 ** NFCSTATUS_SUCCESS if successfully initiated 355 ** NFCSTATUS_FAILED otherwise 356 ** 357 *****************************************************************************/ 358 NFCSTATUS EXTNS_MfcDisconnect (void) 359 { 360 NFCSTATUS status = NFCSTATUS_SUCCESS; 361 362 phLibNfc_Message_t msg; 363 364 msg.eMsgType = PH_NXPEXTNS_DISCONNECT; 365 msg.pMsgData = NULL; 366 msg.Size = 0; 367 368 status = phNxpExtns_SendMsg (&msg); 369 if (NFCSTATUS_SUCCESS != status) 370 { 371 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 372 } 373 374 return status; 375 } 376 377 /***************************************************************************** 378 ** 379 ** Function EXTNS_MfcActivated 380 ** 381 ** Description Activates Mifare Classic Tag. 382 ** 383 ** Returns 384 ** NFCSTATUS_SUCCESS if successfully initiated 385 ** NFCSTATUS_FAILED otherwise 386 ** 387 *****************************************************************************/ 388 NFCSTATUS EXTNS_MfcActivated (void) 389 { 390 NFCSTATUS status = NFCSTATUS_SUCCESS; 391 phLibNfc_Message_t msg; 392 393 msg.eMsgType = PH_NXPEXTNS_ACTIVATED; 394 msg.pMsgData = NULL; 395 msg.Size = 0; 396 397 status = phNxpExtns_SendMsg (&msg); 398 if (NFCSTATUS_SUCCESS != status) 399 { 400 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 401 } 402 403 return status; 404 } 405 406 /******************************************************************************* 407 ** 408 ** Function EXTNS_MfcTransceive 409 ** 410 ** Description Sends raw frame to Mifare Classic Tag. 411 ** 412 ** Returns NFCSTATUS_SUCCESS if successfully initiated 413 ** NFCSTATUS_FAILED otherwise 414 ** 415 *******************************************************************************/ 416 NFCSTATUS EXTNS_MfcTransceive (uint8_t *p_data, uint32_t len) 417 { 418 NFCSTATUS status = NFCSTATUS_SUCCESS; 419 420 phLibNfc_Message_t msg; 421 422 msg.eMsgType = PH_NXPEXTNS_MIFARE_TRANSCEIVE; 423 msg.pMsgData = p_data; 424 msg.Size = len; 425 426 status = phNxpExtns_SendMsg (&msg); 427 if (NFCSTATUS_SUCCESS != status) 428 { 429 NXPLOG_EXTNS_E ("Error Sending msg to Extension Thread"); 430 } 431 432 return status; 433 } 434 435 /******************************************************************************* 436 ** 437 ** Function EXTNS_MfcInit 438 ** 439 ** Description This function is used to Init Mifare Classic Extns. 440 ** This function should be called when the tag detected is 441 ** Mifare Classic. 442 ** 443 ** Returns NFCSTATUS_SUCCESS 444 ** 445 *******************************************************************************/ 446 NFCSTATUS EXTNS_MfcInit (tNFA_ACTIVATED activationData) 447 { 448 tNFC_ACTIVATE_DEVT rfDetail = activationData.activate_ntf; 449 450 NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak = rfDetail.rf_tech_param.param.pa.sel_rsp; 451 NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA [0] = rfDetail.rf_tech_param.param.pa.sens_res[0]; 452 NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA [1] = rfDetail.rf_tech_param.param.pa.sens_res[1]; 453 454 return NFCSTATUS_SUCCESS; 455 } 456 457 /******************************************************************************* 458 ** 459 ** Function phNxpExtns_ProcessSysMessage 460 ** 461 ** Description Internal function to route the request from JNI and Callback 462 ** from NFA_SendRawFrame to right function 463 ** 464 ** Returns NFCSTATUS_SUCCESS if valid request 465 ** NFCSTATUS_FAILED otherwise 466 ** 467 *******************************************************************************/ 468 static NFCSTATUS phNxpExtns_ProcessSysMessage (phLibNfc_Message_t *msg) 469 { 470 NFCSTATUS status = NFCSTATUS_SUCCESS; 471 472 if (gphNxpExtns_Context.Extns_status == EXTNS_STATUS_CLOSE) 473 { 474 return NFCSTATUS_FAILED; 475 } 476 477 switch (msg->eMsgType) 478 { 479 case PH_NXPEXTNS_RX_DATA: 480 status = Mfc_RecvPacket (msg->pMsgData, msg->Size); 481 break; 482 483 case PH_NXPEXTNS_MIFARE_CHECK_NDEF: 484 pthread_mutex_init (&gAuthCmdBuf.syncmutex, NULL); 485 pthread_mutex_lock (&gAuthCmdBuf.syncmutex); 486 status = Mfc_CheckNdef (); 487 pthread_mutex_unlock (&gAuthCmdBuf.syncmutex); 488 pthread_mutex_destroy (&gAuthCmdBuf.syncmutex); 489 break; 490 491 case PH_NXPEXTNS_MIFARE_READ_NDEF: 492 status = Mfc_ReadNdef (); 493 break; 494 495 case PH_NXPEXTNS_MIFARE_WRITE_NDEF: 496 status = Mfc_WriteNdef (msg->pMsgData, msg->Size); 497 break; 498 499 case PH_NXPEXTNS_MIFARE_FORMAT_NDEF: 500 status = Mfc_FormatNdef (msg->pMsgData, msg->Size); 501 break; 502 503 case PH_NXPEXTNS_DISCONNECT: 504 Mfc_DeactivateCbackSelect (); 505 break; 506 507 case PH_NXPEXTNS_ACTIVATED: 508 Mfc_ActivateCback (); 509 break; 510 511 case PH_NXPEXTNS_MIFARE_TRANSCEIVE: 512 status = Mfc_Transceive (msg->pMsgData, msg->Size); 513 break; 514 515 case PH_NXPEXTNS_MIFARE_READ_ONLY: 516 status = Mfc_SetReadOnly (msg->pMsgData, msg->Size); 517 break; 518 case PH_NXPEXTNS_MIFARE_PRESENCE_CHECK: 519 pthread_mutex_init (&gAuthCmdBuf.syncmutex, NULL); 520 pthread_mutex_lock (&gAuthCmdBuf.syncmutex); 521 status = Mfc_PresenceCheck (); 522 pthread_mutex_unlock (&gAuthCmdBuf.syncmutex); 523 pthread_mutex_destroy (&gAuthCmdBuf.syncmutex); 524 break; 525 default: 526 status = NFCSTATUS_FAILED; 527 NXPLOG_EXTNS_E ("Illegal Command for Extension"); 528 break; 529 } 530 531 return status; 532 } 533 534 /******************************************************************************* 535 ** 536 ** Function phNxpExtns_SendMsg 537 ** 538 ** Description unlocks phNxpExtns_ProcessSysMessage with a valid message 539 ** 540 ** Returns NFCSTATUS_SUCCESS if successfully initiated 541 ** NFCSTATUS_FAILED otherwise 542 ** 543 *******************************************************************************/ 544 static NFCSTATUS phNxpExtns_SendMsg (phLibNfc_Message_t *sysmsg) 545 { 546 NFCSTATUS status = NFCSTATUS_SUCCESS; 547 548 status = phNxpExtns_ProcessSysMessage (sysmsg); 549 550 return status; 551 } 552 553 /******************************************************************************* 554 ** 555 ** Function EXTNS_MfcRegisterNDefTypeHandler 556 ** 557 ** Description This function allows the applications to register for 558 ** specific types of NDEF records. 559 ** 560 ** For records types which were not registered, the record will 561 ** be sent to the default handler. 562 ** 563 ** Returns NFCSTATUS_SUCCESS 564 ** 565 *******************************************************************************/ 566 NFCSTATUS EXTNS_MfcRegisterNDefTypeHandler (tNFA_NDEF_CBACK *ndefHandlerCallback) 567 { 568 569 NFCSTATUS status = NFCSTATUS_FAILED; 570 if (NULL != ndefHandlerCallback) 571 { 572 gphNxpExtns_Context.p_ndef_cback = ndefHandlerCallback; 573 status = NFCSTATUS_SUCCESS; 574 } 575 576 return status; 577 } 578 579 /******************************************************************************* 580 ** Synchronizing Functions ** 581 ** Synchronizes Callback in JNI and MFC Extns ** 582 *******************************************************************************/ 583 584 bool_t EXTNS_GetConnectFlag (void) 585 { 586 return (gphNxpExtns_Context.ExtnsConnect); 587 } 588 589 void EXTNS_SetConnectFlag (bool_t flagval) 590 { 591 gphNxpExtns_Context.ExtnsConnect = flagval; 592 } 593 594 bool_t EXTNS_GetDeactivateFlag (void) 595 { 596 return (gphNxpExtns_Context.ExtnsDeactivate); 597 } 598 599 void EXTNS_SetDeactivateFlag (bool_t flagval) 600 { 601 gphNxpExtns_Context.ExtnsDeactivate = flagval; 602 } 603 604 bool_t EXTNS_GetCallBackFlag (void) 605 { 606 return (gphNxpExtns_Context.ExtnsCallBack); 607 } 608 609 void EXTNS_SetCallBackFlag (bool_t flagval) 610 { 611 gphNxpExtns_Context.ExtnsCallBack = flagval; 612 613 } 614 NFCSTATUS EXTNS_GetPresenceCheckStatus (void) 615 { 616 struct timespec ts; 617 618 clock_gettime (CLOCK_REALTIME, &ts); 619 ts.tv_sec += 0; 620 ts.tv_nsec += 100*1000*1000; // 100 milisec 621 if (ts.tv_nsec >= 1000 * 1000 * 1000) 622 { 623 ts.tv_sec += 1; 624 ts.tv_nsec = ts.tv_nsec - (1000 * 1000 * 1000); 625 } 626 627 if (sem_timedwait (&gAuthCmdBuf.semPresenceCheck, &ts)) 628 { 629 ALOGE ("%s: failed to wait (errno=0x%08x)", __FUNCTION__, errno); 630 sem_destroy (&gAuthCmdBuf.semPresenceCheck); 631 gAuthCmdBuf.auth_sent = FALSE; 632 return NFCSTATUS_FAILED; 633 } 634 if (sem_destroy (&gAuthCmdBuf.semPresenceCheck)) 635 { 636 ALOGE ("Failed to destroy check Presence semaphore (errno=0x%08x)", errno); 637 } 638 return gAuthCmdBuf.status; 639 } 640 641 void MfcPresenceCheckResult (NFCSTATUS status) 642 { 643 gAuthCmdBuf.status = status; 644 EXTNS_SetCallBackFlag (TRUE); 645 sem_post (&gAuthCmdBuf.semPresenceCheck); 646 } 647 void MfcResetPresenceCheckStatus (void) 648 { 649 gAuthCmdBuf.auth_sent = FALSE; 650 } 651 /******************************************************************************* 652 ** 653 ** Function EXTNS_CheckMfcResponse 654 ** 655 ** Description This function is called from JNI Transceive for Mifare 656 ** Classic Tag status interpretation and to send the required 657 ** status to application 658 ** 659 ** Returns NFCSTATUS_SUCCESS 660 ** NFCSTATUS_FAILED 661 ** 662 *******************************************************************************/ 663 NFCSTATUS EXTNS_CheckMfcResponse (uint8_t** sTransceiveData, uint32_t *sTransceiveDataLen) 664 { 665 NFCSTATUS status = NFCSTATUS_SUCCESS; 666 667 if (*sTransceiveDataLen == 3) 668 { 669 if((*sTransceiveData) [0] == 0x10 && (*sTransceiveData) [1] != 0x0A) 670 { 671 NXPLOG_EXTNS_E ("Mifare Error in payload response"); 672 *sTransceiveDataLen = 0x1; 673 *sTransceiveData += 1; 674 return NFCSTATUS_FAILED; 675 } 676 } 677 if ((*sTransceiveData) [0] == 0x40) 678 { 679 *sTransceiveData += 1; 680 *sTransceiveDataLen = 0x01; 681 if((*sTransceiveData) [0] == 0x03) 682 { 683 *sTransceiveDataLen = 0x00; 684 status = NFCSTATUS_FAILED; 685 } 686 } 687 else if ((*sTransceiveData) [0] == 0x10) 688 { 689 *sTransceiveData += 1; 690 *sTransceiveDataLen = 0x10; 691 } 692 693 return status; 694 } 695 696