1 /* 2 * Copyright (C) 2010 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 /*! 17 * \file phHal4Nfc_ADD.c 18 * \brief Hal4Nfc_ADD source. 19 * 20 * Project: NFC-FRI 1.1 21 * 22 * $Date: Mon May 31 11:43:42 2010 $ 23 * $Author: ing07385 $ 24 * $Revision: 1.151 $ 25 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $ 26 * 27 */ 28 29 /* ---------------------------Include files ----------------------------------*/ 30 #include <phHciNfc.h> 31 #include <phHal4Nfc.h> 32 #include <phHal4Nfc_Internal.h> 33 #include <phOsalNfc.h> 34 35 /* ------------------------------- Macros ------------------------------------*/ 36 #define NFCIP_ACTIVE_SHIFT 0x03U 37 #define NXP_UID 0x04U 38 #define NXP_MIN_UID_LEN 0x07U 39 /* --------------------Structures and enumerations --------------------------*/ 40 41 NFCSTATUS phHal4Nfc_ConfigParameters( 42 phHal_sHwReference_t *psHwReference, 43 phHal_eConfigType_t CfgType, 44 phHal_uConfig_t *puConfig, 45 pphHal4Nfc_GenCallback_t pConfigCallback, 46 void *pContext 47 ) 48 { 49 NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS; 50 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 51 /*NULL checks*/ 52 if(NULL == psHwReference 53 || NULL == pConfigCallback 54 || NULL == puConfig 55 ) 56 { 57 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 58 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); 59 } 60 /*Check if initialised*/ 61 else if((NULL == psHwReference->hal_context) 62 || (((phHal4Nfc_Hal4Ctxt_t *) 63 psHwReference->hal_context)->Hal4CurrentState 64 < eHal4StateOpenAndReady) 65 || (((phHal4Nfc_Hal4Ctxt_t *) 66 psHwReference->hal_context)->Hal4NextState 67 == eHal4StateClosed)) 68 { 69 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 70 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 71 } 72 else 73 { 74 Hal4Ctxt = psHwReference->hal_context; 75 /*If previous Configuration request has not completed,do not allow new 76 configuration*/ 77 if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring) 78 { 79 PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy"); 80 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY); 81 } 82 else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady) 83 { 84 /*Allocate ADD context*/ 85 if (NULL == Hal4Ctxt->psADDCtxtInfo) 86 { 87 Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t) 88 phOsalNfc_GetMemory((uint32_t) 89 (sizeof(phHal4Nfc_ADDCtxtInfo_t))); 90 if(NULL != Hal4Ctxt->psADDCtxtInfo) 91 { 92 (void)memset(Hal4Ctxt->psADDCtxtInfo,0, 93 sizeof(phHal4Nfc_ADDCtxtInfo_t) 94 ); 95 } 96 } 97 if(NULL == Hal4Ctxt->psADDCtxtInfo) 98 { 99 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 100 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , 101 NFCSTATUS_INSUFFICIENT_RESOURCES); 102 } 103 else 104 { 105 /*Register Upper layer context*/ 106 #ifdef LLCP_DISCON_CHANGES 107 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext; 108 #else /* #ifdef LLCP_DISCON_CHANGES */ 109 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 110 #endif /* #ifdef LLCP_DISCON_CHANGES */ 111 switch(CfgType) 112 { 113 /*NFC_EMULATION_CONFIG*/ 114 case NFC_EMULATION_CONFIG: 115 { 116 (void)memcpy((void *)&Hal4Ctxt->uConfig, 117 (void *)puConfig, 118 sizeof(phHal_uConfig_t) 119 ); 120 break; 121 } 122 /*P2P Configuration*/ 123 case NFC_P2P_CONFIG: 124 { 125 /*If general bytes are not provided by above layer copy zeros 126 in general bytes*/ 127 if(puConfig->nfcIPConfig.generalBytesLength == 0) 128 { 129 Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength = 0x00; 130 (void)memset(Hal4Ctxt->uConfig.nfcIPConfig.generalBytes, 131 0,Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength 132 ); 133 } 134 else 135 { 136 (void)memcpy((void *)&Hal4Ctxt->uConfig, 137 (void *)puConfig, 138 sizeof(phHal_uConfig_t) 139 ); 140 } 141 break; 142 } 143 /*Protection config*/ 144 case NFC_SE_PROTECTION_CONFIG: 145 { 146 #ifdef IGNORE_EVT_PROTECTED 147 Hal4Ctxt->Ignore_Event_Protected = FALSE; 148 #endif/*#ifdef IGNORE_EVT_PROTECTED*/ 149 (void)memcpy((void *)&Hal4Ctxt->uConfig, 150 (void *)puConfig, 151 sizeof(phHal_uConfig_t) 152 ); 153 break; 154 } 155 default: 156 CfgStatus = NFCSTATUS_FAILED; 157 break; 158 } 159 if ( NFCSTATUS_SUCCESS == CfgStatus ) 160 { 161 /*Issue configure with given configuration*/ 162 CfgStatus = phHciNfc_Configure( 163 (void *)Hal4Ctxt->psHciHandle, 164 (void *)psHwReference, 165 CfgType, 166 &Hal4Ctxt->uConfig 167 ); 168 /* Change the State of the HAL only if status is Pending */ 169 if ( NFCSTATUS_PENDING == CfgStatus ) 170 { 171 Hal4Ctxt->Hal4NextState = eHal4StateConfiguring; 172 Hal4Ctxt->sUpperLayerInfo.pConfigCallback 173 = pConfigCallback; 174 } 175 } 176 } 177 } 178 else 179 { 180 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 181 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 182 } 183 } 184 return CfgStatus; 185 } 186 187 188 /**Configure the discovery*/ 189 NFCSTATUS phHal4Nfc_ConfigureDiscovery( 190 phHal_sHwReference_t *psHwReference, 191 phHal_eDiscoveryConfigMode_t discoveryMode, 192 phHal_sADD_Cfg_t *discoveryCfg, 193 pphHal4Nfc_GenCallback_t pConfigCallback, 194 void *pContext 195 ) 196 { 197 NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS; 198 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 199 if(NULL == psHwReference 200 || NULL == pConfigCallback 201 || NULL == discoveryCfg 202 ) 203 { 204 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 205 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); 206 } 207 else if((NULL == psHwReference->hal_context) 208 || (((phHal4Nfc_Hal4Ctxt_t *) 209 psHwReference->hal_context)->Hal4CurrentState 210 < eHal4StateOpenAndReady) 211 || (((phHal4Nfc_Hal4Ctxt_t *) 212 psHwReference->hal_context)->Hal4NextState 213 == eHal4StateClosed)) 214 { 215 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 216 CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 217 } 218 else 219 { 220 Hal4Ctxt = psHwReference->hal_context; 221 /*If previous Configuration request has not completed ,do not allow 222 new configuration*/ 223 if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring) 224 { 225 PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy"); 226 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY); 227 } 228 else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady) 229 { 230 if (NULL == Hal4Ctxt->psADDCtxtInfo) 231 { 232 Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t) 233 phOsalNfc_GetMemory((uint32_t) 234 (sizeof(phHal4Nfc_ADDCtxtInfo_t))); 235 if(NULL != Hal4Ctxt->psADDCtxtInfo) 236 { 237 (void)memset(Hal4Ctxt->psADDCtxtInfo,0, 238 sizeof(phHal4Nfc_ADDCtxtInfo_t) 239 ); 240 } 241 } 242 if(NULL == Hal4Ctxt->psADDCtxtInfo) 243 { 244 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 245 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , 246 NFCSTATUS_INSUFFICIENT_RESOURCES); 247 } 248 else 249 { 250 /*Register Upper layer context*/ 251 #ifdef LLCP_DISCON_CHANGES 252 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext; 253 #else /* #ifdef LLCP_DISCON_CHANGES */ 254 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 255 #endif /* #ifdef LLCP_DISCON_CHANGES */ 256 switch(discoveryMode) 257 { 258 case NFC_DISCOVERY_START: 259 PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_START"); 260 break; 261 case NFC_DISCOVERY_CONFIG: 262 PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_CONFIG"); 263 /*Since sADDCfg is allocated in stack ,copy the ADD 264 configuration structure to HAL4 context*/ 265 (void)memcpy((void *) 266 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg), 267 (void *)discoveryCfg, 268 sizeof(phHal_sADD_Cfg_t) 269 ); 270 PHDBG_INFO("Hal4:Finished copying sADDCfg"); 271 Hal4Ctxt->psADDCtxtInfo->smx_discovery = FALSE; 272 #ifdef UPDATE_NFC_ACTIVE 273 Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo.EnableNfcActive 274 = ( 0 == Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode? 275 Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode: 276 NXP_NFCIP_ACTIVE_DEFAULT); 277 Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode = (( 278 Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode << 279 (NXP_NFCIP_ACTIVE_DEFAULT * NFCIP_ACTIVE_SHIFT)) 280 | Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode); 281 #endif/*#ifdef UPDATE_NFC_ACTIVE*/ 282 /* information system_code(Felica) and 283 AFI(ReaderB) to be populated later */ 284 285 CfgStatus = phHciNfc_Config_Discovery( 286 (void *)Hal4Ctxt->psHciHandle, 287 (void *)psHwReference, 288 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg) 289 );/*Configure HCI Discovery*/ 290 break; 291 case NFC_DISCOVERY_STOP: 292 break; 293 /*Restart Discovery wheel*/ 294 case NFC_DISCOVERY_RESUME: 295 PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_RESUME"); 296 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 297 CfgStatus = phHciNfc_Restart_Discovery ( 298 (void *)Hal4Ctxt->psHciHandle, 299 (void *)psHwReference, 300 FALSE 301 ); 302 break; 303 default: 304 break; 305 } 306 /* Change the State of the HAL only if HCI Configure 307 Returns status as Pending */ 308 if ( NFCSTATUS_PENDING == CfgStatus ) 309 { 310 (void)memcpy((void *) 311 &(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig), 312 (void *)&(discoveryCfg->PollDevInfo.PollCfgInfo), 313 sizeof(phHal_sPollDevInfo_t) 314 ); 315 PHDBG_INFO("Hal4:Finished copying PollCfgInfo"); 316 PHDBG_INFO("Hal4:Configure returned NFCSTATUS_PENDING"); 317 Hal4Ctxt->Hal4NextState = eHal4StateConfiguring; 318 Hal4Ctxt->sUpperLayerInfo.pConfigCallback 319 = pConfigCallback; 320 } 321 else/*Configure failed.Restore old poll dev info*/ 322 { 323 (void)memcpy((void *) 324 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo), 325 (void *)&(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig), 326 sizeof(phHal_sPollDevInfo_t) 327 ); 328 } 329 } 330 } 331 else 332 { 333 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 334 CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 335 } 336 } 337 return CfgStatus; 338 } 339 340 341 /*Configuration completion handler*/ 342 void phHal4Nfc_ConfigureComplete(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 343 void *pInfo, 344 uint8_t type 345 ) 346 { 347 pphHal4Nfc_GenCallback_t pConfigCallback 348 = Hal4Ctxt->sUpperLayerInfo.pConfigCallback; 349 pphHal4Nfc_ConnectCallback_t pUpperConnectCb 350 = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb; 351 NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status; 352 if((type == NFC_NOTIFY_POLL_ENABLED) ||(type == NFC_NOTIFY_POLL_RESTARTED)) 353 { 354 Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = TRUE; 355 PHDBG_INFO("Hal4:Poll Config Complete"); 356 } 357 else 358 { 359 Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = FALSE; 360 PHDBG_WARNING("Hal4:Poll disabled,config success or config error"); 361 } 362 if(NULL != Hal4Ctxt->sUpperLayerInfo.pConfigCallback) 363 { 364 #ifdef MERGE_SAK_SW2 365 if((NFC_UICC_EMULATION == Hal4Ctxt->uConfig.emuConfig.emuType)&& 366 (FALSE == 367 Hal4Ctxt->uConfig.emuConfig.config.uiccEmuCfg.enableUicc)) 368 { 369 Status = phHciNfc_System_Configure ( 370 Hal4Ctxt->psHciHandle, 371 (void *)gpphHal4Nfc_Hwref, 372 PH_HAL4NFC_TGT_MERGE_ADDRESS, 373 PH_HAL4NFC_TGT_MERGE_SAK /*config value*/ 374 ); 375 } 376 if(NFCSTATUS_PENDING != Status) 377 { 378 #endif/*#ifdef MERGE_SAK_SW2*/ 379 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 380 Hal4Ctxt->sUpperLayerInfo.pConfigCallback = NULL; 381 (*pConfigCallback)( 382 #ifdef LLCP_DISCON_CHANGES 383 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt, 384 #else /* #ifdef LLCP_DISCON_CHANGES */ 385 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 386 #endif /* #ifdef LLCP_DISCON_CHANGES */ 387 Status 388 ); 389 #ifdef MERGE_SAK_SW2 390 } 391 #endif/*#ifdef MERGE_SAK_SW2*/ 392 } 393 /**if connect failed and discovery wheel was restarted*/ 394 else if(Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb) 395 { 396 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 397 Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; 398 /*Notify to the upper layer*/ 399 (*pUpperConnectCb)( 400 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 401 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 402 NFCSTATUS_FAILED 403 ); 404 } 405 else 406 { 407 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 408 /**if disconnect failed and discovery wheel was restarted*/ 409 if ( NULL != Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb) 410 { 411 ((phNfc_sCompletionInfo_t *)pInfo)->status = NFCSTATUS_SUCCESS; 412 phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo); 413 } 414 } 415 } 416 417 418 /**Handler for Target discovery completion for all remote device types*/ 419 void phHal4Nfc_TargetDiscoveryComplete( 420 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 421 void *pInfo 422 ) 423 { 424 static phHal4Nfc_DiscoveryInfo_t sDiscoveryInfo; 425 NFCSTATUS status = NFCSTATUS_SUCCESS; 426 /**SAK byte*/ 427 uint8_t Sak = 0; 428 /*Union type to encapsulate and return the discovery info*/ 429 phHal4Nfc_NotificationInfo_t uNotificationInfo; 430 /*All the following types will be discovered as type A ,and differentiation 431 will have to be done within this module based on SAK byte and UID info*/ 432 phHal_eRemDevType_t aRemoteDevTypes[3] = { 433 phHal_eISO14443_A_PICC, 434 phHal_eNfcIP1_Target, 435 phHal_eMifare_PICC 436 }; 437 /*Count is used to add multiple info into remote dvice list for devices that 438 support multiple protocols*/ 439 uint8_t Count = 0, 440 NfcIpDeviceCount = 0;/**<Number of NfcIp devices discovered*/ 441 uint16_t nfc_id = 0; 442 /*remote device info*/ 443 phHal_sRemoteDevInformation_t *psRemoteDevInfo = NULL; 444 status = ((phNfc_sCompletionInfo_t *)pInfo)->status; 445 /*Update Hal4 state*/ 446 Hal4Ctxt->Hal4CurrentState = eHal4StateTargetDiscovered; 447 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 448 PHDBG_INFO("Hal4:Remotedevice Discovered"); 449 if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info) 450 { 451 /*Extract Remote device Info*/ 452 psRemoteDevInfo = (phHal_sRemoteDevInformation_t *) 453 ((phNfc_sCompletionInfo_t *)pInfo)->info; 454 455 switch(psRemoteDevInfo->RemDevType) 456 { 457 case phHal_eISO14443_A_PICC:/*for TYPE A*/ 458 { 459 Sak = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; 460 if((Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A) 461 || (TRUE == Hal4Ctxt->psADDCtxtInfo->smx_discovery)) 462 { 463 /*Check if Iso is Supported*/ 464 if(Sak & ISO_14443_BITMASK) 465 { 466 Count++; 467 } 468 /*Check for Mifare Supported*/ 469 switch( Sak ) 470 { 471 case 0x09: // Mini 472 case 0x08: // 1K 473 case 0x18: // 4K 474 case 0x88: // Infineon 1K 475 case 0x98: // Pro 4K 476 case 0xB8: // Pro 4K 477 case 0x28: // 1K emulation 478 case 0x38: // 4K emulation 479 aRemoteDevTypes[Count] = phHal_eMifare_PICC; 480 Count++; 481 break; 482 } 483 if((0 == Sak)&& (0 == Count)) 484 { 485 /*Mifare check*/ 486 if((NXP_UID == 487 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0]) 488 &&(NXP_MIN_UID_LEN <= 489 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength)) 490 { 491 aRemoteDevTypes[Count] = phHal_eMifare_PICC; 492 Count++; 493 } 494 } 495 if ( !(Sak & NFCIP_BITMASK) ) 496 { 497 // Always add a separate 3A target on a separate 498 // handle, so the upper layers can connect to it. 499 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; 500 Count++; 501 } 502 } 503 /*Check for P2P target passive*/ 504 if((Sak & NFCIP_BITMASK) && 505 (NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)&& 506 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode 507 & phHal_ePassive106)) 508 { 509 if( Sak == 0x53 // Fudan card incompatible to ISO18092 510 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0] == 0x04 511 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[1] == 0x00 512 ) 513 { 514 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; 515 Count++; 516 } 517 else 518 { 519 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; 520 Count++; 521 } 522 } 523 }/*case phHal_eISO14443_A_PICC:*/ 524 break; 525 case phHal_eNfcIP1_Target:/*P2P target detected*/ 526 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; 527 Count++; 528 break; 529 case phHal_eISO14443_B_PICC: /*TYPE_B*/ 530 #ifdef TYPE_B 531 aRemoteDevTypes[Count] = phHal_eISO14443_B_PICC; 532 Count++; 533 break; 534 #endif 535 case phHal_eFelica_PICC: /*Felica*/ 536 #ifdef TYPE_FELICA 537 { 538 /*nfc_id is used to differentiate between Felica and NfcIp target 539 discovered in Type F*/ 540 nfc_id = (((uint16_t)psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[0]) 541 << BYTE_SIZE) | 542 psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[1]; 543 /*check for NfcIp target*/ 544 if(NXP_NFCIP_NFCID2_ID == nfc_id) 545 { 546 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) 547 &&((Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode 548 & phHal_ePassive212) || 549 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode 550 & phHal_ePassive424))) 551 { 552 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; 553 Count++; 554 } 555 } 556 else/*Felica*/ 557 { 558 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica212 559 || Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica424) 560 { 561 aRemoteDevTypes[Count] = phHal_eFelica_PICC; 562 Count++; 563 } 564 } 565 break; 566 } 567 #endif 568 case phHal_eJewel_PICC: /*Jewel*/ 569 #ifdef TYPE_JEWEL 570 { 571 /*Report Jewel tags only if TYPE A is enabled*/ 572 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A) 573 { 574 aRemoteDevTypes[Count] = phHal_eJewel_PICC; 575 Count++; 576 } 577 break; 578 } 579 #endif 580 #ifdef TYPE_ISO15693 581 case phHal_eISO15693_PICC: /*ISO15693*/ 582 { 583 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso15693) 584 { 585 aRemoteDevTypes[Count] = phHal_eISO15693_PICC; 586 Count++; 587 } 588 break; 589 } 590 #endif /* #ifdef TYPE_ISO15693 */ 591 /*Types currently not supported*/ 592 case phHal_eISO14443_BPrime_PICC: 593 default: 594 PHDBG_WARNING("Hal4:Notification for Not supported types"); 595 break; 596 }/*End of switch*/ 597 /*Update status code to success if atleast one device info is available*/ 598 status = (((NFCSTATUS_SUCCESS != status) 599 && (NFCSTATUS_MULTIPLE_TAGS != status)) 600 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))? 601 NFCSTATUS_SUCCESS:status; 602 603 /*Update status to NFCSTATUS_MULTIPLE_PROTOCOLS if count > 1 ,and this 604 is first discovery notification from Hci*/ 605 status = ((NFCSTATUS_SUCCESS == status) 606 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0) 607 &&(Count > 1)?NFCSTATUS_MULTIPLE_PROTOCOLS:status); 608 /*If multiple protocols are supported ,allocate separate remote device 609 information for each protocol supported*/ 610 /*Allocate and copy Remote device info into Hal4 Context*/ 611 while(Count) 612 { 613 PHDBG_INFO("Hal4:Count is not zero"); 614 --Count; 615 /*Allocate memory for each of Count number of 616 devices*/ 617 if(NULL == Hal4Ctxt->rem_dev_list[ 618 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) 619 { 620 Hal4Ctxt->rem_dev_list[ 621 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] 622 = (phHal_sRemoteDevInformation_t *) 623 phOsalNfc_GetMemory( 624 (uint32_t)( 625 sizeof(phHal_sRemoteDevInformation_t)) 626 ); 627 } 628 if(NULL == Hal4Ctxt->rem_dev_list[ 629 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) 630 { 631 status = PHNFCSTVAL(CID_NFC_HAL, 632 NFCSTATUS_INSUFFICIENT_RESOURCES); 633 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 634 break; 635 } 636 else 637 { 638 (void)memcpy( 639 (void *)Hal4Ctxt->rem_dev_list[ 640 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices], 641 (void *)psRemoteDevInfo, 642 sizeof(phHal_sRemoteDevInformation_t) 643 ); 644 /*Now copy appropriate device type from aRemoteDevTypes array*/ 645 Hal4Ctxt->rem_dev_list[ 646 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]->RemDevType 647 = aRemoteDevTypes[Count]; 648 /*Increment number of devices*/ 649 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices++; 650 }/*End of else*/ 651 }/*End of while*/ 652 653 /*If Upper layer is interested only in P2P notifications*/ 654 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) 655 &&(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1) 656 &&(phHal_eNfcIP1_Target == Hal4Ctxt->rem_dev_list[0]->RemDevType)) 657 ||(NULL == Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)) 658 ) 659 { 660 PHDBG_INFO("Hal4:Trying to notify P2P Listener"); 661 /*NFCSTATUS_SUCCESS or NFCSTATUS_MULTIPLE_PROTOCOLS*/ 662 if((NFCSTATUS_SUCCESS == status) 663 ||(NFCSTATUS_MULTIPLE_PROTOCOLS == status)) 664 { 665 /*Pick only the P2P target device info from the list*/ 666 for(Count = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 667 Count > 0;--Count) 668 { 669 /*Only one P2P target can be detected in one discovery*/ 670 if(phHal_eNfcIP1_Target == 671 Hal4Ctxt->rem_dev_list[Count-1]->RemDevType) 672 { 673 (void)memcpy( 674 (void *)Hal4Ctxt->rem_dev_list[0], 675 (void *)Hal4Ctxt->rem_dev_list[Count-1], 676 sizeof(phHal_sRemoteDevInformation_t) 677 ); 678 NfcIpDeviceCount = 1; 679 break; 680 } 681 } 682 /*If any P2p devices are discovered free other device info*/ 683 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > NfcIpDeviceCount) 684 { 685 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[ 686 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]); 687 Hal4Ctxt->rem_dev_list[ 688 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; 689 } 690 /*Issue P2P notification*/ 691 if(NfcIpDeviceCount == 1) 692 { 693 sDiscoveryInfo.NumberOfDevices 694 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 695 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; 696 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 697 PHDBG_INFO("Hal4:Calling P2P listener"); 698 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)( 699 (void *)(Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt), 700 NFC_DISCOVERY_NOTIFICATION, 701 uNotificationInfo, 702 NFCSTATUS_SUCCESS 703 ); 704 } 705 else/*Restart Discovery wheel*/ 706 { 707 PHDBG_INFO("Hal4:No P2P device in list"); 708 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 709 PHDBG_INFO("Hal4:Restart discovery1"); 710 status = phHciNfc_Restart_Discovery ( 711 (void *)Hal4Ctxt->psHciHandle, 712 (void *)gpphHal4Nfc_Hwref, 713 FALSE 714 ); 715 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 716 eHal4StateConfiguring: 717 Hal4Ctxt->Hal4NextState); 718 } 719 } 720 /*More discovery info available ,get next info from HCI*/ 721 else if((NFCSTATUS_MULTIPLE_TAGS == status) 722 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices 723 < MAX_REMOTE_DEVICES)) 724 { 725 status = phHciNfc_Select_Next_Target ( 726 Hal4Ctxt->psHciHandle, 727 (void *)gpphHal4Nfc_Hwref 728 ); 729 } 730 else/*Failed discovery ,restart discovery*/ 731 { 732 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 733 PHDBG_INFO("Hal4:Restart discovery2"); 734 status = phHciNfc_Restart_Discovery ( 735 (void *)Hal4Ctxt->psHciHandle, 736 (void *)gpphHal4Nfc_Hwref, 737 FALSE 738 );/*Restart Discovery wheel*/ 739 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 740 eHal4StateConfiguring: 741 Hal4Ctxt->Hal4NextState); 742 } 743 }/*if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)...*/ 744 /*Notify if Upper layer is interested in tag notifications,also notify 745 P2p if its in the list with other tags*/ 746 else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification) 747 { 748 PHDBG_INFO("Hal4:Trying to notify Tag notification"); 749 /*Multiple tags in field, get discovery info a second time for the 750 other devices*/ 751 if((NFCSTATUS_MULTIPLE_TAGS == status) 752 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices < MAX_REMOTE_DEVICES)) 753 { 754 PHDBG_INFO("Hal4:select next target1"); 755 status = phHciNfc_Select_Next_Target ( 756 Hal4Ctxt->psHciHandle, 757 (void *)gpphHal4Nfc_Hwref 758 ); 759 } 760 /*Single tag multiple protocols scenario,Notify Multiple Protocols 761 status to upper layer*/ 762 else if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) 763 { 764 PHDBG_INFO("Hal4:Multiple Tags or protocols"); 765 sDiscoveryInfo.NumberOfDevices 766 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 767 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; 768 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 769 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( 770 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), 771 NFC_DISCOVERY_NOTIFICATION, 772 uNotificationInfo, 773 status 774 ); 775 } 776 else /*NFCSTATUS_SUCCESS*/ 777 { 778 if(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1) 779 &&(phHal_eNfcIP1_Target 780 == Hal4Ctxt->rem_dev_list[0]->RemDevType)) 781 ||(NFCSTATUS_SUCCESS != status) 782 || (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0) 783 )/*device detected but upper layer is not interested 784 in the type(P2P) or activate next failed*/ 785 { 786 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 0) 787 { 788 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[ 789 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]); 790 Hal4Ctxt->rem_dev_list[ 791 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; 792 } 793 PHDBG_INFO("Hal4:Restart discovery3"); 794 status = phHciNfc_Restart_Discovery ( 795 (void *)Hal4Ctxt->psHciHandle, 796 (void *)gpphHal4Nfc_Hwref, 797 FALSE 798 );/*Restart Discovery wheel*/ 799 Hal4Ctxt->Hal4NextState = ( 800 NFCSTATUS_PENDING == status?eHal4StateConfiguring 801 :Hal4Ctxt->Hal4NextState 802 ); 803 } 804 else/*All remote device info available.Notify to upper layer*/ 805 { 806 /*Update status for MULTIPLE_TAGS here*/ 807 status = (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 1? 808 NFCSTATUS_MULTIPLE_TAGS:status); 809 /*If listener is registered ,call it*/ 810 sDiscoveryInfo.NumberOfDevices 811 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 812 sDiscoveryInfo.ppRemoteDevInfo 813 = Hal4Ctxt->rem_dev_list; 814 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 815 PHDBG_INFO("Hal4:Calling Discovery Handler1"); 816 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( 817 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), 818 NFC_DISCOVERY_NOTIFICATION, 819 uNotificationInfo, 820 status 821 ); 822 } 823 } 824 } /*else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)*/ 825 else/*listener not registered ,Restart Discovery wheel*/ 826 { 827 PHDBG_INFO("Hal4:No listener registered.Ignoring Discovery \ 828 Notification"); 829 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 830 PHDBG_INFO("Hal4:Restart discovery4"); 831 status = phHciNfc_Restart_Discovery ( 832 (void *)Hal4Ctxt->psHciHandle, 833 (void *)gpphHal4Nfc_Hwref, 834 FALSE 835 ); 836 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 837 eHal4StateConfiguring: 838 Hal4Ctxt->Hal4NextState); 839 } 840 }/*if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)*/ 841 else/*NULL info received*/ 842 { 843 sDiscoveryInfo.NumberOfDevices 844 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 845 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; 846 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 847 /*If Discovery info is available from previous notifications try to 848 notify that to the upper layer*/ 849 if((NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification) 850 #ifdef NFC_RF_NOISE_SW 851 &&((NFCSTATUS_SUCCESS == status) 852 || (NFCSTATUS_MULTIPLE_TAGS == status)) 853 #endif /* #ifdef NFC_RF_NOISE_SW */ 854 ) 855 { 856 #ifndef NFC_RF_NOISE_SW 857 status = (((NFCSTATUS_SUCCESS != status) 858 && (NFCSTATUS_MULTIPLE_TAGS != status)) 859 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))? 860 NFCSTATUS_SUCCESS:status; 861 #endif/*#ifndef NFC_RF_NOISE_SW*/ 862 PHDBG_INFO("Hal4:Calling Discovery Handler2"); 863 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( 864 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), 865 NFC_DISCOVERY_NOTIFICATION, 866 uNotificationInfo, 867 status 868 ); 869 } 870 else/*Restart Discovery wheel*/ 871 { 872 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 873 PHDBG_INFO("Hal4:Restart discovery5"); 874 status = phHciNfc_Restart_Discovery ( 875 (void *)Hal4Ctxt->psHciHandle, 876 (void *)gpphHal4Nfc_Hwref, 877 FALSE 878 ); 879 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 880 eHal4StateConfiguring:Hal4Ctxt->Hal4NextState); 881 } 882 }/*else*/ 883 return; 884 } 885 886 887 /**Register Notification handlers*/ 888 NFCSTATUS phHal4Nfc_RegisterNotification( 889 phHal_sHwReference_t *psHwReference, 890 phHal4Nfc_RegisterType_t eRegisterType, 891 pphHal4Nfc_Notification_t pNotificationHandler, 892 void *Context 893 ) 894 { 895 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; 896 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 897 if(NULL == pNotificationHandler || NULL == psHwReference) 898 { 899 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 900 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); 901 } 902 else if((NULL == psHwReference->hal_context) 903 || (((phHal4Nfc_Hal4Ctxt_t *) 904 psHwReference->hal_context)->Hal4CurrentState 905 < eHal4StateOpenAndReady) 906 || (((phHal4Nfc_Hal4Ctxt_t *) 907 psHwReference->hal_context)->Hal4NextState 908 == eHal4StateClosed)) 909 { 910 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 911 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 912 } 913 else 914 { 915 /*Extract context from hardware reference*/ 916 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 917 switch(eRegisterType) 918 { 919 case eRegisterTagDiscovery: 920 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = Context; 921 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification 922 = pNotificationHandler; /*Register the tag Notification*/ 923 break; 924 case eRegisterP2PDiscovery: 925 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = Context; 926 Hal4Ctxt->sUpperLayerInfo.pP2PNotification 927 = pNotificationHandler; /*Register the P2P Notification*/ 928 break; 929 case eRegisterHostCardEmulation: 930 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED; 931 break; 932 case eRegisterSecureElement: 933 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = Context; 934 Hal4Ctxt->sUpperLayerInfo.pEventNotification 935 = pNotificationHandler; /*Register the Se Notification*/ 936 break; 937 default: 938 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = Context; 939 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler 940 = pNotificationHandler; /*Register the default Notification*/ 941 break; 942 } 943 PHDBG_INFO("Hal4:listener registered"); 944 } 945 return RetStatus; 946 } 947 948 949 /**Unregister Notification handlers*/ 950 NFCSTATUS phHal4Nfc_UnregisterNotification( 951 phHal_sHwReference_t *psHwReference, 952 phHal4Nfc_RegisterType_t eRegisterType, 953 void *Context 954 ) 955 { 956 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; 957 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 958 if(psHwReference == NULL) 959 { 960 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 961 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); 962 } 963 else if((NULL == psHwReference->hal_context) 964 || (((phHal4Nfc_Hal4Ctxt_t *) 965 psHwReference->hal_context)->Hal4CurrentState 966 < eHal4StateOpenAndReady) 967 || (((phHal4Nfc_Hal4Ctxt_t *) 968 psHwReference->hal_context)->Hal4NextState 969 == eHal4StateClosed)) 970 { 971 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 972 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 973 } 974 else 975 { 976 /*Extract context from hardware reference*/ 977 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 978 switch(eRegisterType) 979 { 980 case eRegisterTagDiscovery: 981 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = Context; 982 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = NULL; 983 /*UnRegister the tag Notification*/ 984 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL; 985 PHDBG_INFO("Hal4:Tag Discovery Listener Unregistered"); 986 break; 987 case eRegisterP2PDiscovery: 988 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = NULL; 989 /*UnRegister the p2p Notification*/ 990 Hal4Ctxt->sUpperLayerInfo.pP2PNotification = NULL; 991 PHDBG_INFO("Hal4:P2P Discovery Listener Unregistered"); 992 break; 993 case eRegisterHostCardEmulation:/*RFU*/ 994 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED; 995 break; 996 /*UnRegister the Se Notification*/ 997 case eRegisterSecureElement: 998 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = NULL; 999 Hal4Ctxt->sUpperLayerInfo.pEventNotification = NULL; 1000 PHDBG_INFO("Hal4:SE Listener Unregistered"); 1001 break; 1002 default: 1003 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = NULL; 1004 /*UnRegister the default Notification*/ 1005 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler = NULL; 1006 PHDBG_INFO("Hal4:Default Listener Unregistered"); 1007 break; 1008 } 1009 } 1010 return RetStatus; 1011 } 1012 1013 1014