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 *****************************************/ 30extern phNxpNciHal_Control_t nxpncihal_ctrl; 31extern phNxpNciProfile_Control_t nxpprofile_ctrl; 32 33extern uint32_t cleanup_timer; 34uint8_t icode_detected = 0x00; 35uint8_t icode_send_eof = 0x00; 36#if (NFC_NXP_CHIP_TYPE == PN548C2) 37uint8_t nfcdep_detected = 0x00; 38#endif 39static uint8_t ee_disc_done = 0x00; 40uint8_t EnableP2P_PrioLogic = false; 41static uint32_t RfDiscID = 1; 42static uint32_t RfProtocolType = 4; 43/* NFCEE Set mode */ 44static uint8_t setEEModeDone = 0x00; 45static uint8_t cmd_nfcee_setmode_enable[] = {0x22, 0x01, 0x02, 0x01, 0x01}; 46 47/* External global variable to get FW version from NCI response*/ 48extern uint32_t wFwVerRsp; 49/* External global variable to get FW version from FW file*/ 50extern uint16_t wFwVer; 51 52uint16_t fw_maj_ver; 53uint16_t rom_version; 54/* local buffer to store CORE_INIT response */ 55static uint32_t bCoreInitRsp[40]; 56static uint32_t iCoreInitRspLen; 57 58extern uint32_t timeoutTimerId; 59 60extern NFCSTATUS read_retry(); 61 62/************** HAL extension functions ***************************************/ 63static 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 73static uint8_t gFelicaReaderMode; 74 75static 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*******************************************************************************/ 84void 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*******************************************************************************/ 100NFCSTATUS 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 *******************************************************************************/ 407static 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 ******************************************************************************/ 481static 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 567clean_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 585NFCSTATUS 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 ******************************************************************************/ 905NFCSTATUS 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 ******************************************************************************/ 926static 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