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