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