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