Home | History | Annotate | Download | only in hal
      1 /*
      2  * Copyright (C) 2012-2014 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 #include <phDal4Nfc_messageQueueLib.h>
     17 #include <phNxpConfig.h>
     18 #include <phNxpLog.h>
     19 #include <phNxpNciHal.h>
     20 #include <phNxpNciHal_NfcDepSWPrio.h>
     21 #include <phNxpNciHal_ext.h>
     22 #include <phTmlNfc.h>
     23 
     24 /* Timeout value to wait for response from PN548AD */
     25 #define HAL_EXTNS_WRITE_RSP_TIMEOUT (1000)
     26 
     27 #undef P2P_PRIO_LOGIC_HAL_IMP
     28 
     29 /******************* Global variables *****************************************/
     30 extern phNxpNciHal_Control_t nxpncihal_ctrl;
     31 extern phNxpNciProfile_Control_t nxpprofile_ctrl;
     32 
     33 extern uint32_t cleanup_timer;
     34 uint8_t icode_detected = 0x00;
     35 uint8_t icode_send_eof = 0x00;
     36 #if (NFC_NXP_CHIP_TYPE == PN548C2)
     37 uint8_t nfcdep_detected = 0x00;
     38 #endif
     39 static uint8_t ee_disc_done = 0x00;
     40 uint8_t EnableP2P_PrioLogic = false;
     41 static uint32_t RfDiscID = 1;
     42 static uint32_t RfProtocolType = 4;
     43 /* NFCEE Set mode */
     44 static uint8_t setEEModeDone = 0x00;
     45 static uint8_t cmd_nfcee_setmode_enable[] = {0x22, 0x01, 0x02, 0x01, 0x01};
     46 
     47 /* External global variable to get FW version from NCI response*/
     48 extern uint32_t wFwVerRsp;
     49 /* External global variable to get FW version from FW file*/
     50 extern uint16_t wFwVer;
     51 
     52 uint16_t fw_maj_ver;
     53 uint16_t rom_version;
     54 /* local buffer to store CORE_INIT response */
     55 static uint32_t bCoreInitRsp[40];
     56 static uint32_t iCoreInitRspLen;
     57 
     58 extern uint32_t timeoutTimerId;
     59 
     60 extern NFCSTATUS read_retry();
     61 
     62 /************** HAL extension functions ***************************************/
     63 static void hal_extns_write_rsp_timeout_cb(uint32_t TimerId, void* pContext);
     64 
     65 /*Proprietary cmd sent to HAL to send reader mode flag
     66  * Last byte of 4 byte proprietary cmd data contains ReaderMode flag
     67  * If this flag is enabled, NFC-DEP protocol is modified to T3T protocol
     68  * if FrameRF interface is selected. This needs to be done as the FW
     69  * always sends Ntf for FrameRF with NFC-DEP even though FrameRF with T3T is
     70  * previously selected with DISCOVER_SELECT_CMD
     71  */
     72 #define PROPRIETARY_CMD_FELICA_READER_MODE 0xFE
     73 static uint8_t gFelicaReaderMode;
     74 
     75 static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf,
     76                                                       uint16_t* p_len);
     77 /*******************************************************************************
     78 **
     79 ** Function         phNxpNciHal_ext_init
     80 **
     81 ** Description      initialize extension function
     82 **
     83 *******************************************************************************/
     84 void phNxpNciHal_ext_init(void) {
     85   icode_detected = 0x00;
     86   icode_send_eof = 0x00;
     87   setEEModeDone = 0x00;
     88   EnableP2P_PrioLogic = false;
     89 }
     90 
     91 /*******************************************************************************
     92 **
     93 ** Function         phNxpNciHal_process_ext_rsp
     94 **
     95 ** Description      Process extension function response
     96 **
     97 ** Returns          NFCSTATUS_SUCCESS if success
     98 **
     99 *******************************************************************************/
    100 NFCSTATUS phNxpNciHal_process_ext_rsp(uint8_t* p_ntf, uint16_t* p_len) {
    101   NFCSTATUS status = NFCSTATUS_SUCCESS;
    102   uint16_t rf_technology_length_param = 0;
    103 
    104   if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x03 &&
    105       p_ntf[5] == 0x05 && nxpprofile_ctrl.profile_type == EMV_CO_PROFILE) {
    106     p_ntf[4] = 0xFF;
    107     p_ntf[5] = 0xFF;
    108     p_ntf[6] = 0xFF;
    109     NXPLOG_NCIHAL_D("Nfc-Dep Detect in EmvCo profile - Restart polling");
    110   }
    111 
    112   if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 &&
    113       p_ntf[5] == 0x05 && p_ntf[6] == 0x02 && gFelicaReaderMode) {
    114     /*If FelicaReaderMode is enabled,Change Protocol to T3T from NFC-DEP
    115          * when FrameRF interface is selected*/
    116     p_ntf[5] = 0x03;
    117     NXPLOG_NCIHAL_D("FelicaReaderMode:Activity 1.1");
    118   }
    119 
    120 #ifdef P2P_PRIO_LOGIC_HAL_IMP
    121   if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x02 &&
    122       p_ntf[5] == 0x04 && nxpprofile_ctrl.profile_type == NFC_FORUM_PROFILE) {
    123     EnableP2P_PrioLogic = true;
    124   }
    125 
    126   NXPLOG_NCIHAL_D("Is EnableP2P_PrioLogic: 0x0%X", EnableP2P_PrioLogic);
    127   if (phNxpDta_IsEnable() == false) {
    128     if ((icode_detected != 1) && (EnableP2P_PrioLogic == true)) {
    129       if (phNxpNciHal_NfcDep_comapre_ntf(p_ntf, *p_len) == NFCSTATUS_FAILED) {
    130         status = phNxpNciHal_NfcDep_rsp_ext(p_ntf, p_len);
    131         if (status != NFCSTATUS_INVALID_PARAMETER) {
    132           return status;
    133         }
    134       }
    135     }
    136   }
    137 #endif
    138 
    139   status = NFCSTATUS_SUCCESS;
    140 
    141   if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05) {
    142 #if (NFC_NXP_CHIP_TYPE == PN548C2)
    143     if (nfcdep_detected) {
    144       nfcdep_detected = 0x00;
    145     }
    146 #endif
    147 
    148     switch (p_ntf[4]) {
    149       case 0x00:
    150         NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFCEE Direct RF");
    151         break;
    152       case 0x01:
    153         NXPLOG_NCIHAL_D("NxpNci: RF Interface = Frame RF");
    154         break;
    155       case 0x02:
    156         NXPLOG_NCIHAL_D("NxpNci: RF Interface = ISO-DEP");
    157         break;
    158       case 0x03:
    159         NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFC-DEP");
    160 #if (NFC_NXP_CHIP_TYPE == PN548C2)
    161         nfcdep_detected = 0x01;
    162 #endif
    163         break;
    164       case 0x80:
    165         NXPLOG_NCIHAL_D("NxpNci: RF Interface = MIFARE");
    166         break;
    167       default:
    168         NXPLOG_NCIHAL_D("NxpNci: RF Interface = Unknown");
    169         break;
    170     }
    171 
    172     switch (p_ntf[5]) {
    173       case 0x01:
    174         NXPLOG_NCIHAL_D("NxpNci: Protocol = T1T");
    175         phNxpDta_T1TEnable();
    176         break;
    177       case 0x02:
    178         NXPLOG_NCIHAL_D("NxpNci: Protocol = T2T");
    179         break;
    180       case 0x03:
    181         NXPLOG_NCIHAL_D("NxpNci: Protocol = T3T");
    182         break;
    183       case 0x04:
    184         NXPLOG_NCIHAL_D("NxpNci: Protocol = ISO-DEP");
    185         break;
    186       case 0x05:
    187         NXPLOG_NCIHAL_D("NxpNci: Protocol = NFC-DEP");
    188         break;
    189       case 0x06:
    190         NXPLOG_NCIHAL_D("NxpNci: Protocol = 15693");
    191         break;
    192       case 0x80:
    193         NXPLOG_NCIHAL_D("NxpNci: Protocol = MIFARE");
    194         break;
    195 #if (NFC_NXP_CHIP_TYPE != PN547C2)
    196       case 0x81:
    197 #else
    198       case 0x8A:
    199 #endif
    200         NXPLOG_NCIHAL_D("NxpNci: Protocol = Kovio");
    201         break;
    202       default:
    203         NXPLOG_NCIHAL_D("NxpNci: Protocol = Unknown");
    204         break;
    205     }
    206 
    207     switch (p_ntf[6]) {
    208       case 0x00:
    209         NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Poll");
    210         break;
    211       case 0x01:
    212         NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Poll");
    213         break;
    214       case 0x02:
    215         NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Poll");
    216         break;
    217       case 0x03:
    218         NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Poll");
    219         break;
    220       case 0x05:
    221         NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Poll");
    222         break;
    223       case 0x06:
    224         NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Poll");
    225         break;
    226 #if (NFC_NXP_CHIP_TYPE != PN547C2)
    227       case 0x70:
    228 #else
    229       case 0x77:
    230 #endif
    231         NXPLOG_NCIHAL_D("NxpNci: Mode = Kovio");
    232         break;
    233       case 0x80:
    234         NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Listen");
    235         break;
    236       case 0x81:
    237         NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Listen");
    238         break;
    239       case 0x82:
    240         NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Listen");
    241         break;
    242       case 0x83:
    243         NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Listen");
    244         break;
    245       case 0x85:
    246         NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Listen");
    247         break;
    248       case 0x86:
    249         NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Listen");
    250         break;
    251       default:
    252         NXPLOG_NCIHAL_D("NxpNci: Mode = Unknown");
    253         break;
    254     }
    255   }
    256   phNxpNciHal_ext_process_nfc_init_rsp(p_ntf, p_len);
    257 
    258   if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[2] == 0x15 &&
    259       p_ntf[4] == 0x01 && p_ntf[5] == 0x06 && p_ntf[6] == 0x06) {
    260     NXPLOG_NCIHAL_D("> Going through workaround - notification of ISO 15693");
    261     icode_detected = 0x01;
    262     p_ntf[21] = 0x01;
    263     p_ntf[22] = 0x01;
    264   } else if (icode_detected == 1 && icode_send_eof == 2) {
    265     icode_send_eof = 3;
    266   } else if (p_ntf[0] == 0x00 && p_ntf[1] == 0x00 && icode_detected == 1) {
    267     if (icode_send_eof == 3) {
    268       icode_send_eof = 0;
    269     }
    270     if (nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0) {
    271       if (p_ntf[p_ntf[2] + 2] == 0x00) {
    272         NXPLOG_NCIHAL_D("> Going through workaround - data of ISO 15693");
    273         p_ntf[2]--;
    274         (*p_len)--;
    275       } else {
    276         p_ntf[p_ntf[2] + 2] |= 0x01;
    277       }
    278     }
    279   } else if (p_ntf[2] == 0x02 && p_ntf[1] == 0x00 && icode_detected == 1) {
    280     NXPLOG_NCIHAL_D("> ICODE EOF response do not send to upper layer");
    281   } else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x06 && icode_detected == 1) {
    282     NXPLOG_NCIHAL_D("> Polling Loop Re-Started");
    283     icode_detected = 0;
    284     icode_send_eof = 0;
    285   } else if (*p_len == 4 && p_ntf[0] == 0x40 && p_ntf[1] == 0x02 &&
    286              p_ntf[2] == 0x01 && p_ntf[3] == 0x06) {
    287     NXPLOG_NCIHAL_D("> Deinit workaround for LLCP set_config 0x%x 0x%x 0x%x",
    288                     p_ntf[21], p_ntf[22], p_ntf[23]);
    289     p_ntf[0] = 0x40;
    290     p_ntf[1] = 0x02;
    291     p_ntf[2] = 0x02;
    292     p_ntf[3] = 0x00;
    293     p_ntf[4] = 0x00;
    294     *p_len = 5;
    295   }
    296   // 4200 02 00 01
    297   else if (p_ntf[0] == 0x42 && p_ntf[1] == 0x00 && ee_disc_done == 0x01) {
    298     NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP");
    299     if (p_ntf[4] == 0x01) {
    300       p_ntf[4] = 0x00;
    301 
    302       ee_disc_done = 0x00;
    303     }
    304     NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP - END");
    305 
    306   } else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x03 /*&& cleanup_timer!=0*/) {
    307     if (cleanup_timer != 0) {
    308       /* if RF Notification Type of RF_DISCOVER_NTF is Last Notification */
    309       if (0 == (*(p_ntf + 2 + (*(p_ntf + 2))))) {
    310         phNxpNciHal_select_RF_Discovery(RfDiscID, RfProtocolType);
    311         status = NFCSTATUS_FAILED;
    312         return status;
    313       } else {
    314         RfDiscID = p_ntf[3];
    315         RfProtocolType = p_ntf[4];
    316       }
    317       status = NFCSTATUS_FAILED;
    318       return status;
    319     }
    320   } else if (p_ntf[0] == 0x41 && p_ntf[1] == 0x04 && cleanup_timer != 0) {
    321     status = NFCSTATUS_FAILED;
    322     return status;
    323   }
    324 #if (NFC_NXP_CHIP_TYPE == PN547C2)
    325   else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x02 &&
    326            p_ntf[5] == 0x80 && p_ntf[6] == 0x00) {
    327     NXPLOG_NCIHAL_D(
    328         "Going through workaround - iso-dep  interface  mifare protocol with "
    329         "sak value not equal to 0x20");
    330     rf_technology_length_param = p_ntf[9];
    331     if ((p_ntf[9 + rf_technology_length_param] & 0x20) != 0x20) {
    332       p_ntf[4] = 0x80;
    333     }
    334   }
    335 #endif
    336   else if (*p_len == 4 && p_ntf[0] == 0x4F && p_ntf[1] == 0x11 &&
    337            p_ntf[2] == 0x01) {
    338     if (p_ntf[3] == 0x00) {
    339       NXPLOG_NCIHAL_D(
    340           ">  Workaround for ISO-DEP Presence Check, ignore response and wait "
    341           "for notification");
    342       p_ntf[0] = 0x60;
    343       p_ntf[1] = 0x06;
    344       p_ntf[2] = 0x03;
    345       p_ntf[3] = 0x01;
    346       p_ntf[4] = 0x00;
    347       p_ntf[5] = 0x01;
    348       *p_len = 6;
    349     } else {
    350       NXPLOG_NCIHAL_D(
    351           ">  Workaround for ISO-DEP Presence Check, presence check return "
    352           "failed");
    353       p_ntf[0] = 0x60;
    354       p_ntf[1] = 0x08;
    355       p_ntf[2] = 0x02;
    356       p_ntf[3] = 0xB2;
    357       p_ntf[4] = 0x00;
    358       *p_len = 5;
    359     }
    360   } else if (*p_len == 4 && p_ntf[0] == 0x6F && p_ntf[1] == 0x11 &&
    361              p_ntf[2] == 0x01) {
    362     if (p_ntf[3] == 0x01) {
    363       NXPLOG_NCIHAL_D(
    364           ">  Workaround for ISO-DEP Presence Check - Card still in field");
    365       p_ntf[0] = 0x00;
    366       p_ntf[1] = 0x00;
    367       p_ntf[2] = 0x01;
    368       p_ntf[3] = 0x7E;
    369     } else {
    370       NXPLOG_NCIHAL_D(
    371           ">  Workaround for ISO-DEP Presence Check - Card not in field");
    372       p_ntf[0] = 0x60;
    373       p_ntf[1] = 0x08;
    374       p_ntf[2] = 0x02;
    375       p_ntf[3] = 0xB2;
    376       p_ntf[4] = 0x00;
    377       *p_len = 5;
    378     }
    379   }
    380   /*
    381   else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 && p_ntf[5]
    382   == 0x00 && p_ntf[6] == 0x01)
    383   {
    384       NXPLOG_NCIHAL_D("Picopass type 3-B with undefined protocol is not
    385   supported, disabling");
    386       p_ntf[4] = 0xFF;
    387       p_ntf[5] = 0xFF;
    388       p_ntf[6] = 0xFF;
    389   }*/
    390 
    391   return status;
    392 }
    393 
    394 /******************************************************************************
    395  * Function         phNxpNciHal_ext_process_nfc_init_rsp
    396  *
    397  * Description      This function is used to process the HAL NFC core reset rsp
    398  *                  and ntf and core init rsp of NCI 1.0 or NCI2.0 and update
    399  *                  NCI version.
    400  *                  It also handles error response such as core_reset_ntf with
    401  *                  error status in both NCI2.0 and NCI1.0.
    402  *
    403  * Returns          Returns NFCSTATUS_SUCCESS if parsing response is successful
    404  *                  or returns failure.
    405  *
    406  *******************************************************************************/
    407 static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf,
    408                                                       uint16_t* p_len) {
    409   NFCSTATUS status = NFCSTATUS_SUCCESS;
    410   /* Parsing CORE_RESET_RSP and CORE_RESET_NTF to update NCI version.*/
    411   if (p_ntf == NULL || *p_len == 0x00) {
    412     return NFCSTATUS_FAILED;
    413   }
    414   if (p_ntf[0] == NCI_MT_RSP &&
    415       ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) {
    416     if (p_ntf[2] == 0x01 && p_ntf[3] == 0x00) {
    417       NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI2.0");
    418       if (nxpncihal_ctrl.hal_ext_enabled == TRUE) {
    419         nxpncihal_ctrl.nci_info.wait_for_ntf = TRUE;
    420       }
    421     } else if (p_ntf[2] == 0x03 && p_ntf[3] == 0x00) {
    422       NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI1.0");
    423       nxpncihal_ctrl.nci_info.nci_version = p_ntf[4];
    424     }
    425   } else if (p_ntf[0] == NCI_MT_NTF &&
    426              ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) {
    427     if (p_ntf[3] == CORE_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED ||
    428         p_ntf[3] == CORE_RESET_TRIGGER_TYPE_POWERED_ON) {
    429       NXPLOG_NCIHAL_D("CORE_RESET_NTF NCI2.0 reason CORE_RESET_CMD received !");
    430       nxpncihal_ctrl.nci_info.nci_version = p_ntf[5];
    431       int len = p_ntf[2] + 2; /*include 2 byte header*/
    432       wFwVerRsp = (((uint32_t)p_ntf[len - 2]) << 16U) |
    433                   (((uint32_t)p_ntf[len - 1]) << 8U) | p_ntf[len];
    434       NXPLOG_NCIHAL_D("NxpNci> FW Version: %x.%x.%x", p_ntf[len - 2],
    435                       p_ntf[len - 1], p_ntf[len]);
    436     } else {
    437 #if (NFC_NXP_CHIP_TYPE == PN548C2)
    438       if (nfcdep_detected &&
    439           !(p_ntf[2] == 0x06 && p_ntf[3] == 0xA0 && p_ntf[4] == 0x00 &&
    440             ((p_ntf[5] == 0xC9 && p_ntf[6] == 0x95 && p_ntf[7] == 0x00 &&
    441               p_ntf[8] == 0x00) ||
    442              (p_ntf[5] == 0x07 && p_ntf[6] == 0x39 && p_ntf[7] == 0xF2 &&
    443               p_ntf[8] == 0x00)))) {
    444         nfcdep_detected = 0x00;
    445       }
    446 #endif
    447       phNxpNciHal_emergency_recovery();
    448       status = NFCSTATUS_FAILED;
    449     } /* Parsing CORE_INIT_RSP*/
    450   } else if (p_ntf[0] == NCI_MT_RSP &&
    451              ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_INIT)) {
    452     if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
    453       NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI2.0 received !");
    454     } else {
    455       NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI1.0 received !");
    456       int len = p_ntf[2] + 2; /*include 2 byte header*/
    457       wFwVerRsp = (((uint32_t)p_ntf[len - 2]) << 16U) |
    458                   (((uint32_t)p_ntf[len - 1]) << 8U) | p_ntf[len];
    459       if (wFwVerRsp == 0) status = NFCSTATUS_FAILED;
    460       iCoreInitRspLen = *p_len;
    461       memcpy(bCoreInitRsp, p_ntf, *p_len);
    462       NXPLOG_NCIHAL_D("NxpNci> FW Version: %x.%x.%x", p_ntf[len - 2],
    463                       p_ntf[len - 1], p_ntf[len]);
    464       fw_maj_ver = p_ntf[len - 1];
    465       rom_version = p_ntf[len - 2];
    466     }
    467   }
    468   return status;
    469 }
    470 
    471 /******************************************************************************
    472  * Function         phNxpNciHal_process_ext_cmd_rsp
    473  *
    474  * Description      This function process the extension command response. It
    475  *                  also checks the received response to expected response.
    476  *
    477  * Returns          returns NFCSTATUS_SUCCESS if response is as expected else
    478  *                  returns failure.
    479  *
    480  ******************************************************************************/
    481 static NFCSTATUS phNxpNciHal_process_ext_cmd_rsp(uint16_t cmd_len,
    482                                                  uint8_t* p_cmd) {
    483   NFCSTATUS status = NFCSTATUS_FAILED;
    484   uint16_t data_written = 0;
    485 
    486   /* Create the local semaphore */
    487   if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL) !=
    488       NFCSTATUS_SUCCESS) {
    489     NXPLOG_NCIHAL_D("Create ext_cb_data failed");
    490     return NFCSTATUS_FAILED;
    491   }
    492 
    493   nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_SUCCESS;
    494 
    495   /* Send ext command */
    496   data_written = phNxpNciHal_write_unlocked(cmd_len, p_cmd);
    497   if (data_written != cmd_len) {
    498     NXPLOG_NCIHAL_D("phNxpNciHal_write failed for hal ext");
    499     goto clean_and_return;
    500   }
    501 
    502   /* Start timer */
    503   status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_EXTNS_WRITE_RSP_TIMEOUT,
    504                                  &hal_extns_write_rsp_timeout_cb, NULL);
    505   if (NFCSTATUS_SUCCESS == status) {
    506     NXPLOG_NCIHAL_D("Response timer started");
    507   } else {
    508     NXPLOG_NCIHAL_E("Response timer not started!!!");
    509     status = NFCSTATUS_FAILED;
    510     goto clean_and_return;
    511   }
    512 
    513   /* Wait for rsp */
    514   NXPLOG_NCIHAL_D("Waiting after ext cmd sent");
    515   if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data)) {
    516     NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error");
    517     goto clean_and_return;
    518   }
    519 
    520   /* Stop Timer */
    521   status = phOsalNfc_Timer_Stop(timeoutTimerId);
    522   if (NFCSTATUS_SUCCESS == status) {
    523     NXPLOG_NCIHAL_D("Response timer stopped");
    524   } else {
    525     NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
    526     status = NFCSTATUS_FAILED;
    527     goto clean_and_return;
    528   }
    529   /* Start timer to wait for NTF*/
    530   if (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE) {
    531     status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_EXTNS_WRITE_RSP_TIMEOUT,
    532                                    &hal_extns_write_rsp_timeout_cb, NULL);
    533     if (NFCSTATUS_SUCCESS == status) {
    534       NXPLOG_NCIHAL_D("Response timer started");
    535     } else {
    536       NXPLOG_NCIHAL_E("Response timer not started!!!");
    537       status = NFCSTATUS_FAILED;
    538       goto clean_and_return;
    539     }
    540     if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data)) {
    541       NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error");
    542       /* Stop Timer */
    543       status = phOsalNfc_Timer_Stop(timeoutTimerId);
    544       goto clean_and_return;
    545     }
    546     status = phOsalNfc_Timer_Stop(timeoutTimerId);
    547     if (NFCSTATUS_SUCCESS == status) {
    548       NXPLOG_NCIHAL_D("Response timer stopped");
    549     } else {
    550       NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
    551       status = NFCSTATUS_FAILED;
    552       goto clean_and_return;
    553     }
    554   }
    555 
    556   if (nxpncihal_ctrl.ext_cb_data.status != NFCSTATUS_SUCCESS) {
    557     NXPLOG_NCIHAL_E(
    558         "Callback Status is failed!! Timer Expired!! Couldn't read it! 0x%x",
    559         nxpncihal_ctrl.ext_cb_data.status);
    560     status = NFCSTATUS_FAILED;
    561     goto clean_and_return;
    562   }
    563 
    564   NXPLOG_NCIHAL_D("Checking response");
    565   status = NFCSTATUS_SUCCESS;
    566 
    567 clean_and_return:
    568   phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
    569   nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
    570   return status;
    571 }
    572 
    573 /******************************************************************************
    574  * Function         phNxpNciHal_write_ext
    575  *
    576  * Description      This function inform the status of phNxpNciHal_open
    577  *                  function to libnfc-nci.
    578  *
    579  * Returns          It return NFCSTATUS_SUCCESS then continue with send else
    580  *                  sends NFCSTATUS_FAILED direct response is prepared and
    581  *                  do not send anything to NFCC.
    582  *
    583  ******************************************************************************/
    584 
    585 NFCSTATUS phNxpNciHal_write_ext(uint16_t* cmd_len, uint8_t* p_cmd_data,
    586                                 uint16_t* rsp_len, uint8_t* p_rsp_data) {
    587   NFCSTATUS status = NFCSTATUS_SUCCESS;
    588 
    589   unsigned long retval = 0;
    590   int isfound =
    591       GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &retval, sizeof(unsigned long));
    592 
    593   phNxpNciHal_NfcDep_cmd_ext(p_cmd_data, cmd_len);
    594 
    595   if (phNxpDta_IsEnable() == true) {
    596     status = phNxpNHal_DtaUpdate(cmd_len, p_cmd_data, rsp_len, p_rsp_data);
    597   }
    598 
    599   if (p_cmd_data[0] == PROPRIETARY_CMD_FELICA_READER_MODE &&
    600       p_cmd_data[1] == PROPRIETARY_CMD_FELICA_READER_MODE &&
    601       p_cmd_data[2] == PROPRIETARY_CMD_FELICA_READER_MODE) {
    602     NXPLOG_NCIHAL_D("Received proprietary command to set Felica Reader mode:%d",
    603                     p_cmd_data[3]);
    604     gFelicaReaderMode = p_cmd_data[3];
    605     /* frame the dummy response */
    606     *rsp_len = 4;
    607     p_rsp_data[0] = 0x00;
    608     p_rsp_data[1] = 0x00;
    609     p_rsp_data[2] = 0x00;
    610     p_rsp_data[3] = 0x00;
    611     status = NFCSTATUS_FAILED;
    612   } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
    613              p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x01 &&
    614              p_cmd_data[4] == 0xA0 && p_cmd_data[5] == 0x44 &&
    615              p_cmd_data[6] == 0x01 && p_cmd_data[7] == 0x01) {
    616     nxpprofile_ctrl.profile_type = EMV_CO_PROFILE;
    617     NXPLOG_NCIHAL_D("EMV_CO_PROFILE mode - Enabled");
    618     status = NFCSTATUS_SUCCESS;
    619   } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
    620              p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x01 &&
    621              p_cmd_data[4] == 0xA0 && p_cmd_data[5] == 0x44 &&
    622              p_cmd_data[6] == 0x01 && p_cmd_data[7] == 0x00) {
    623     NXPLOG_NCIHAL_D("NFC_FORUM_PROFILE mode - Enabled");
    624     nxpprofile_ctrl.profile_type = NFC_FORUM_PROFILE;
    625     status = NFCSTATUS_SUCCESS;
    626   }
    627 
    628   if (nxpprofile_ctrl.profile_type == EMV_CO_PROFILE) {
    629     if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x06 &&
    630         p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x03) {
    631 #if 0
    632             //Needs clarification whether to keep it or not
    633             NXPLOG_NCIHAL_D ("EmvCo Poll mode - RF Deactivate discard");
    634             phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
    635             *rsp_len = 4;
    636             p_rsp_data[0] = 0x41;
    637             p_rsp_data[1] = 0x06;
    638             p_rsp_data[2] = 0x01;
    639             p_rsp_data[3] = 0x00;
    640             phNxpNciHal_print_packet("RECV", p_rsp_data, 4);
    641             status = NFCSTATUS_FAILED;
    642 #endif
    643     } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) {
    644       NXPLOG_NCIHAL_D("EmvCo Poll mode - Discover map only for A and B");
    645       p_cmd_data[2] = 0x05;
    646       p_cmd_data[3] = 0x02;
    647       p_cmd_data[4] = 0x00;
    648       p_cmd_data[5] = 0x01;
    649       p_cmd_data[6] = 0x01;
    650       p_cmd_data[7] = 0x01;
    651       *cmd_len = 8;
    652     }
    653   }
    654 
    655   if (retval == 0x01 && p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x00) {
    656     NXPLOG_NCIHAL_D("Going through extns - Adding Mifare in RF Discovery");
    657     p_cmd_data[2] += 3;
    658     p_cmd_data[3] += 1;
    659     p_cmd_data[*cmd_len] = 0x80;
    660     p_cmd_data[*cmd_len + 1] = 0x01;
    661     p_cmd_data[*cmd_len + 2] = 0x80;
    662     *cmd_len += 3;
    663     status = NFCSTATUS_SUCCESS;
    664     NXPLOG_NCIHAL_D(
    665         "Going through extns - Adding Mifare in RF Discovery - END");
    666   } else if (p_cmd_data[3] == 0x81 && p_cmd_data[4] == 0x01 &&
    667              p_cmd_data[5] == 0x03) {
    668     NXPLOG_NCIHAL_D("> Going through workaround - set host list");
    669 
    670 #if (NFC_NXP_CHIP_TYPE != PN547C2)
    671     *cmd_len = 8;
    672 
    673     p_cmd_data[2] = 0x05;
    674     p_cmd_data[6] = 0x02;
    675     p_cmd_data[7] = 0xC0;
    676 #else
    677     *cmd_len = 7;
    678 
    679     p_cmd_data[2] = 0x04;
    680     p_cmd_data[6] = 0xC0;
    681 #endif
    682 
    683     NXPLOG_NCIHAL_D("> Going through workaround - set host list - END");
    684     status = NFCSTATUS_SUCCESS;
    685   } else if (icode_detected) {
    686     if ((p_cmd_data[3] & 0x40) == 0x40 &&
    687         (p_cmd_data[4] == 0x21 || p_cmd_data[4] == 0x22 ||
    688          p_cmd_data[4] == 0x24 || p_cmd_data[4] == 0x27 ||
    689          p_cmd_data[4] == 0x28 || p_cmd_data[4] == 0x29 ||
    690          p_cmd_data[4] == 0x2a)) {
    691       NXPLOG_NCIHAL_D("> Send EOF set");
    692       icode_send_eof = 1;
    693     }
    694 
    695     if (p_cmd_data[3] == 0x20 || p_cmd_data[3] == 0x24 ||
    696         p_cmd_data[3] == 0x60) {
    697       NXPLOG_NCIHAL_D("> NFC ISO_15693 Proprietary CMD ");
    698       p_cmd_data[3] += 0x02;
    699     }
    700   } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) {
    701     NXPLOG_NCIHAL_D("> Polling Loop Started");
    702     icode_detected = 0;
    703     icode_send_eof = 0;
    704 #if (NFC_NXP_CHIP_TYPE == PN548C2)
    705     // Cache discovery cmd for recovery
    706     phNxpNciHal_discovery_cmd_ext(p_cmd_data, *cmd_len);
    707 #endif
    708   }
    709   // 22000100
    710   else if (p_cmd_data[0] == 0x22 && p_cmd_data[1] == 0x00 &&
    711            p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x00) {
    712     // ee_disc_done = 0x01;//Reader Over SWP event getting
    713     *rsp_len = 0x05;
    714     p_rsp_data[0] = 0x42;
    715     p_rsp_data[1] = 0x00;
    716     p_rsp_data[2] = 0x02;
    717     p_rsp_data[3] = 0x00;
    718     p_rsp_data[4] = 0x00;
    719     phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
    720     status = NFCSTATUS_FAILED;
    721   }
    722   // 2002 0904 3000 3100 3200 5000
    723   else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
    724            ((p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) /*||
    725             (p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/
    726             )) {
    727     *cmd_len += 0x01;
    728     p_cmd_data[2] += 0x01;
    729     p_cmd_data[9] = 0x01;
    730     p_cmd_data[10] = 0x40;
    731     p_cmd_data[11] = 0x50;
    732     p_cmd_data[12] = 0x00;
    733 
    734     NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config ");
    735     //        phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
    736     NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End ");
    737   }
    738   //    20020703300031003200
    739   //    2002 0301 3200
    740   else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
    741            ((p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x03) ||
    742             (p_cmd_data[2] == 0x03 && p_cmd_data[3] == 0x01 &&
    743              p_cmd_data[4] == 0x32))) {
    744     NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config ");
    745     phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
    746     *rsp_len = 5;
    747     p_rsp_data[0] = 0x40;
    748     p_rsp_data[1] = 0x02;
    749     p_rsp_data[2] = 0x02;
    750     p_rsp_data[3] = 0x00;
    751     p_rsp_data[4] = 0x00;
    752 
    753     phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
    754     status = NFCSTATUS_FAILED;
    755     NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End ");
    756   }
    757 
    758   // 2002 0D04 300104 310100 320100 500100
    759   // 2002 0401 320100
    760   else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
    761            (
    762                /*(p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/
    763                (p_cmd_data[2] == 0x04 && p_cmd_data[3] == 0x01 &&
    764                 p_cmd_data[4] == 0x32 && p_cmd_data[5] == 0x00))) {
    765     //        p_cmd_data[12] = 0x40;
    766 
    767     NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config ");
    768     phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
    769     p_cmd_data[6] = 0x60;
    770 
    771     phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
    772     //        status = NFCSTATUS_FAILED;
    773     NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End ");
    774   } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x00) {
    775     NXPLOG_NCIHAL_D(
    776         "> Going through workaround - Add Mifare Classic in Discovery Map");
    777     p_cmd_data[*cmd_len] = 0x80;
    778     p_cmd_data[*cmd_len + 1] = 0x01;
    779     p_cmd_data[*cmd_len + 2] = 0x80;
    780     p_cmd_data[5] = 0x01;
    781     p_cmd_data[6] = 0x01;
    782     p_cmd_data[2] += 3;
    783     p_cmd_data[3] += 1;
    784     *cmd_len += 3;
    785   } else if (*cmd_len == 3 && p_cmd_data[0] == 0x00 && p_cmd_data[1] == 0x00 &&
    786              p_cmd_data[2] == 0x00) {
    787     NXPLOG_NCIHAL_D("> Going through workaround - ISO-DEP Presence Check ");
    788     p_cmd_data[0] = 0x2F;
    789     p_cmd_data[1] = 0x11;
    790     p_cmd_data[2] = 0x00;
    791     status = NFCSTATUS_SUCCESS;
    792     NXPLOG_NCIHAL_D(
    793         "> Going through workaround - ISO-DEP Presence Check - End");
    794   }
    795 #if 0
    796     else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) &&
    797                  ((p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) ||
    798                      (p_cmd_data[2] == 0x0B && p_cmd_data[3] == 0x05) ||
    799                      (p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x02) ||
    800                      (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x03) ||
    801                      (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x04) ||
    802                      (p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x02))
    803              )
    804     {
    805         NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
    806         phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
    807         *rsp_len = 5;
    808         p_rsp_data[0] = 0x40;
    809         p_rsp_data[1] = 0x02;
    810         p_rsp_data[2] = 0x02;
    811         p_rsp_data[3] = 0x00;
    812         p_rsp_data[4] = 0x00;
    813 
    814         phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
    815         status = NFCSTATUS_FAILED;
    816         NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
    817     }
    818 
    819     else if((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
    820            ((p_cmd_data[3] == 0x00) ||
    821            ((*cmd_len >= 0x06) && (p_cmd_data[5] == 0x00)))) /*If the length of the first param id is zero don't allow*/
    822     {
    823         NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
    824         phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
    825         *rsp_len = 5;
    826         p_rsp_data[0] = 0x40;
    827         p_rsp_data[1] = 0x02;
    828         p_rsp_data[2] = 0x02;
    829         p_rsp_data[3] = 0x00;
    830         p_rsp_data[4] = 0x00;
    831 
    832         phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
    833         status = NFCSTATUS_FAILED;
    834         NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
    835     }
    836 #endif
    837   else if ((wFwVerRsp & 0x0000FFFF) == wFwVer) {
    838     /* skip CORE_RESET and CORE_INIT from Brcm */
    839     if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x00 &&
    840         p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x01) {
    841       //            *rsp_len = 6;
    842       //
    843       //            NXPLOG_NCIHAL_D("> Going - core reset optimization");
    844       //
    845       //            p_rsp_data[0] = 0x40;
    846       //            p_rsp_data[1] = 0x00;
    847       //            p_rsp_data[2] = 0x03;
    848       //            p_rsp_data[3] = 0x00;
    849       //            p_rsp_data[4] = 0x10;
    850       //            p_rsp_data[5] = 0x01;
    851       //
    852       //            status = NFCSTATUS_FAILED;
    853       //            NXPLOG_NCIHAL_D("> Going - core reset optimization - END");
    854     }
    855     /* CORE_INIT */
    856     else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x01 &&
    857              p_cmd_data[2] == 0x00) {
    858       //            NXPLOG_NCIHAL_D("> Going - core init optimization");
    859       //            *rsp_len = iCoreInitRspLen;
    860       //            memcpy(p_rsp_data, bCoreInitRsp, iCoreInitRspLen);
    861       //            status = NFCSTATUS_FAILED;
    862       //            NXPLOG_NCIHAL_D("> Going - core init optimization - END");
    863     }
    864   }
    865 
    866 #if (NFC_NXP_CHIP_TYPE == PN548C2)
    867   if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) {
    868     uint8_t temp;
    869     uint8_t* p = p_cmd_data + 4;
    870     uint8_t* end = p_cmd_data + *cmd_len;
    871     while (p < end) {
    872       if (*p == 0x53)  // LF_T3T_FLAGS
    873       {
    874         NXPLOG_NCIHAL_D("> Going through workaround - LF_T3T_FLAGS swap");
    875         temp = *(p + 3);
    876         *(p + 3) = *(p + 2);
    877         *(p + 2) = temp;
    878         NXPLOG_NCIHAL_D("> Going through workaround - LF_T3T_FLAGS - End");
    879         status = NFCSTATUS_SUCCESS;
    880         break;
    881       }
    882       if (*p == 0xA0) {
    883         p += *(p + 2) + 3;
    884       } else {
    885         p += *(p + 1) + 2;
    886       }
    887     }
    888   }
    889 #endif
    890 
    891   return status;
    892 }
    893 
    894 /******************************************************************************
    895  * Function         phNxpNciHal_send_ext_cmd
    896  *
    897  * Description      This function send the extension command to NFCC. No
    898  *                  response is checked by this function but it waits for
    899  *                  the response to come.
    900  *
    901  * Returns          Returns NFCSTATUS_SUCCESS if sending cmd is successful and
    902  *                  response is received.
    903  *
    904  ******************************************************************************/
    905 NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t* p_cmd) {
    906   NFCSTATUS status = NFCSTATUS_FAILED;
    907 
    908   HAL_ENABLE_EXT();
    909   nxpncihal_ctrl.cmd_len = cmd_len;
    910   memcpy(nxpncihal_ctrl.p_cmd_data, p_cmd, cmd_len);
    911   status = phNxpNciHal_process_ext_cmd_rsp(nxpncihal_ctrl.cmd_len,
    912                                            nxpncihal_ctrl.p_cmd_data);
    913   HAL_DISABLE_EXT();
    914 
    915   return status;
    916 }
    917 
    918 /******************************************************************************
    919  * Function         hal_extns_write_rsp_timeout_cb
    920  *
    921  * Description      Timer call back function
    922  *
    923  * Returns          None
    924  *
    925  ******************************************************************************/
    926 static void hal_extns_write_rsp_timeout_cb(uint32_t timerId, void* pContext) {
    927   UNUSED(timerId);
    928   UNUSED(pContext);
    929   NXPLOG_NCIHAL_E("hal_extns_write_rsp_timeout_cb - write timeout!!!");
    930   nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
    931   usleep(1);
    932   SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
    933 
    934   return;
    935 }
    936