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 0x01: // 1K Classic 472 case 0x09: // Mini 473 case 0x08: // 1K 474 case 0x18: // 4K 475 case 0x88: // Infineon 1K 476 case 0x98: // Pro 4K 477 case 0xB8: // Pro 4K 478 case 0x28: // 1K emulation 479 case 0x38: // 4K emulation 480 aRemoteDevTypes[Count] = phHal_eMifare_PICC; 481 Count++; 482 break; 483 } 484 if((0 == Sak)&& (0 == Count)) 485 { 486 /*Mifare check*/ 487 if((NXP_UID == 488 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0]) 489 &&(NXP_MIN_UID_LEN <= 490 psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength)) 491 { 492 aRemoteDevTypes[Count] = phHal_eMifare_PICC; 493 Count++; 494 } 495 } 496 if ( !(Sak & NFCIP_BITMASK) ) 497 { 498 // Always add a separate 3A target on a separate 499 // handle, so the upper layers can connect to it. 500 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; 501 Count++; 502 } 503 } 504 /*Check for P2P target passive*/ 505 if((Sak & NFCIP_BITMASK) && 506 (NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)&& 507 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode 508 & phHal_ePassive106)) 509 { 510 if( Sak == 0x53 // Fudan card incompatible to ISO18092 511 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0] == 0x04 512 && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[1] == 0x00 513 ) 514 { 515 aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; 516 Count++; 517 } 518 else 519 { 520 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; 521 Count++; 522 } 523 } 524 }/*case phHal_eISO14443_A_PICC:*/ 525 break; 526 case phHal_eNfcIP1_Target:/*P2P target detected*/ 527 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; 528 Count++; 529 break; 530 case phHal_eISO14443_B_PICC: /*TYPE_B*/ 531 #ifdef TYPE_B 532 aRemoteDevTypes[Count] = phHal_eISO14443_B_PICC; 533 Count++; 534 break; 535 #endif 536 case phHal_eFelica_PICC: /*Felica*/ 537 #ifdef TYPE_FELICA 538 { 539 /*nfc_id is used to differentiate between Felica and NfcIp target 540 discovered in Type F*/ 541 nfc_id = (((uint16_t)psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[0]) 542 << BYTE_SIZE) | 543 psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[1]; 544 /*check for NfcIp target*/ 545 if(NXP_NFCIP_NFCID2_ID == nfc_id) 546 { 547 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) 548 &&((Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode 549 & phHal_ePassive212) || 550 (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode 551 & phHal_ePassive424))) 552 { 553 aRemoteDevTypes[Count] = phHal_eNfcIP1_Target; 554 Count++; 555 } 556 } 557 else/*Felica*/ 558 { 559 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica212 560 || Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica424) 561 { 562 aRemoteDevTypes[Count] = phHal_eFelica_PICC; 563 Count++; 564 } 565 } 566 break; 567 } 568 #endif 569 case phHal_eJewel_PICC: /*Jewel*/ 570 #ifdef TYPE_JEWEL 571 { 572 /*Report Jewel tags only if TYPE A is enabled*/ 573 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A) 574 { 575 aRemoteDevTypes[Count] = phHal_eJewel_PICC; 576 Count++; 577 } 578 break; 579 } 580 #endif 581 #ifdef TYPE_ISO15693 582 case phHal_eISO15693_PICC: /*ISO15693*/ 583 { 584 if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso15693) 585 { 586 aRemoteDevTypes[Count] = phHal_eISO15693_PICC; 587 Count++; 588 } 589 break; 590 } 591 #endif /* #ifdef TYPE_ISO15693 */ 592 /*Types currently not supported*/ 593 case phHal_eISO14443_BPrime_PICC: 594 default: 595 PHDBG_WARNING("Hal4:Notification for Not supported types"); 596 break; 597 }/*End of switch*/ 598 /*Update status code to success if atleast one device info is available*/ 599 status = (((NFCSTATUS_SUCCESS != status) 600 && (NFCSTATUS_MULTIPLE_TAGS != status)) 601 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))? 602 NFCSTATUS_SUCCESS:status; 603 604 /*Update status to NFCSTATUS_MULTIPLE_PROTOCOLS if count > 1 ,and this 605 is first discovery notification from Hci*/ 606 status = ((NFCSTATUS_SUCCESS == status) 607 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0) 608 &&(Count > 1)?NFCSTATUS_MULTIPLE_PROTOCOLS:status); 609 /*If multiple protocols are supported ,allocate separate remote device 610 information for each protocol supported*/ 611 /*Allocate and copy Remote device info into Hal4 Context*/ 612 while(Count) 613 { 614 PHDBG_INFO("Hal4:Count is not zero"); 615 --Count; 616 /*Allocate memory for each of Count number of 617 devices*/ 618 if(NULL == Hal4Ctxt->rem_dev_list[ 619 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) 620 { 621 Hal4Ctxt->rem_dev_list[ 622 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] 623 = (phHal_sRemoteDevInformation_t *) 624 phOsalNfc_GetMemory( 625 (uint32_t)( 626 sizeof(phHal_sRemoteDevInformation_t)) 627 ); 628 } 629 if(NULL == Hal4Ctxt->rem_dev_list[ 630 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) 631 { 632 status = PHNFCSTVAL(CID_NFC_HAL, 633 NFCSTATUS_INSUFFICIENT_RESOURCES); 634 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 635 break; 636 } 637 else 638 { 639 (void)memcpy( 640 (void *)Hal4Ctxt->rem_dev_list[ 641 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices], 642 (void *)psRemoteDevInfo, 643 sizeof(phHal_sRemoteDevInformation_t) 644 ); 645 /*Now copy appropriate device type from aRemoteDevTypes array*/ 646 Hal4Ctxt->rem_dev_list[ 647 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]->RemDevType 648 = aRemoteDevTypes[Count]; 649 /*Increment number of devices*/ 650 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices++; 651 }/*End of else*/ 652 }/*End of while*/ 653 654 /*If Upper layer is interested only in P2P notifications*/ 655 if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) 656 &&(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1) 657 &&(phHal_eNfcIP1_Target == Hal4Ctxt->rem_dev_list[0]->RemDevType)) 658 ||(NULL == Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)) 659 ) 660 { 661 PHDBG_INFO("Hal4:Trying to notify P2P Listener"); 662 /*NFCSTATUS_SUCCESS or NFCSTATUS_MULTIPLE_PROTOCOLS*/ 663 if((NFCSTATUS_SUCCESS == status) 664 ||(NFCSTATUS_MULTIPLE_PROTOCOLS == status)) 665 { 666 /*Pick only the P2P target device info from the list*/ 667 for(Count = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 668 Count > 0;--Count) 669 { 670 /*Only one P2P target can be detected in one discovery*/ 671 if(phHal_eNfcIP1_Target == 672 Hal4Ctxt->rem_dev_list[Count-1]->RemDevType) 673 { 674 if (Count != 1) 675 { 676 (void)memcpy( 677 (void *)Hal4Ctxt->rem_dev_list[0], 678 (void *)Hal4Ctxt->rem_dev_list[Count-1], 679 sizeof(phHal_sRemoteDevInformation_t) 680 ); 681 } 682 NfcIpDeviceCount = 1; 683 break; 684 } 685 } 686 /*If any P2p devices are discovered free other device info*/ 687 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > NfcIpDeviceCount) 688 { 689 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[ 690 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]); 691 Hal4Ctxt->rem_dev_list[ 692 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; 693 } 694 /*Issue P2P notification*/ 695 if(NfcIpDeviceCount == 1) 696 { 697 sDiscoveryInfo.NumberOfDevices 698 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 699 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; 700 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 701 PHDBG_INFO("Hal4:Calling P2P listener"); 702 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)( 703 (void *)(Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt), 704 NFC_DISCOVERY_NOTIFICATION, 705 uNotificationInfo, 706 NFCSTATUS_SUCCESS 707 ); 708 } 709 else/*Restart Discovery wheel*/ 710 { 711 PHDBG_INFO("Hal4:No P2P device in list"); 712 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 713 PHDBG_INFO("Hal4:Restart discovery1"); 714 status = phHciNfc_Restart_Discovery ( 715 (void *)Hal4Ctxt->psHciHandle, 716 (void *)gpphHal4Nfc_Hwref, 717 FALSE 718 ); 719 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 720 eHal4StateConfiguring: 721 Hal4Ctxt->Hal4NextState); 722 } 723 } 724 /*More discovery info available ,get next info from HCI*/ 725 else if((NFCSTATUS_MULTIPLE_TAGS == status) 726 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices 727 < MAX_REMOTE_DEVICES)) 728 { 729 status = phHciNfc_Select_Next_Target ( 730 Hal4Ctxt->psHciHandle, 731 (void *)gpphHal4Nfc_Hwref 732 ); 733 } 734 else/*Failed discovery ,restart discovery*/ 735 { 736 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 737 PHDBG_INFO("Hal4:Restart discovery2"); 738 status = phHciNfc_Restart_Discovery ( 739 (void *)Hal4Ctxt->psHciHandle, 740 (void *)gpphHal4Nfc_Hwref, 741 FALSE 742 );/*Restart Discovery wheel*/ 743 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 744 eHal4StateConfiguring: 745 Hal4Ctxt->Hal4NextState); 746 } 747 }/*if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)...*/ 748 /*Notify if Upper layer is interested in tag notifications,also notify 749 P2p if its in the list with other tags*/ 750 else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification) 751 { 752 PHDBG_INFO("Hal4:Trying to notify Tag notification"); 753 /*Multiple tags in field, get discovery info a second time for the 754 other devices*/ 755 if((NFCSTATUS_MULTIPLE_TAGS == status) 756 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices < MAX_REMOTE_DEVICES)) 757 { 758 PHDBG_INFO("Hal4:select next target1"); 759 status = phHciNfc_Select_Next_Target ( 760 Hal4Ctxt->psHciHandle, 761 (void *)gpphHal4Nfc_Hwref 762 ); 763 } 764 /*Single tag multiple protocols scenario,Notify Multiple Protocols 765 status to upper layer*/ 766 else if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) 767 { 768 PHDBG_INFO("Hal4:Multiple Tags or protocols"); 769 sDiscoveryInfo.NumberOfDevices 770 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 771 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; 772 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 773 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( 774 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), 775 NFC_DISCOVERY_NOTIFICATION, 776 uNotificationInfo, 777 status 778 ); 779 } 780 else /*NFCSTATUS_SUCCESS*/ 781 { 782 if(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1) 783 &&(phHal_eNfcIP1_Target 784 == Hal4Ctxt->rem_dev_list[0]->RemDevType)) 785 ||(NFCSTATUS_SUCCESS != status) 786 || (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0) 787 )/*device detected but upper layer is not interested 788 in the type(P2P) or activate next failed*/ 789 { 790 while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 0) 791 { 792 phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[ 793 --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]); 794 Hal4Ctxt->rem_dev_list[ 795 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; 796 } 797 PHDBG_INFO("Hal4:Restart discovery3"); 798 status = phHciNfc_Restart_Discovery ( 799 (void *)Hal4Ctxt->psHciHandle, 800 (void *)gpphHal4Nfc_Hwref, 801 FALSE 802 );/*Restart Discovery wheel*/ 803 Hal4Ctxt->Hal4NextState = ( 804 NFCSTATUS_PENDING == status?eHal4StateConfiguring 805 :Hal4Ctxt->Hal4NextState 806 ); 807 } 808 else/*All remote device info available.Notify to upper layer*/ 809 { 810 /*Update status for MULTIPLE_TAGS here*/ 811 status = (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 1? 812 NFCSTATUS_MULTIPLE_TAGS:status); 813 /*If listener is registered ,call it*/ 814 sDiscoveryInfo.NumberOfDevices 815 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 816 sDiscoveryInfo.ppRemoteDevInfo 817 = Hal4Ctxt->rem_dev_list; 818 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 819 PHDBG_INFO("Hal4:Calling Discovery Handler1"); 820 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( 821 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), 822 NFC_DISCOVERY_NOTIFICATION, 823 uNotificationInfo, 824 status 825 ); 826 } 827 } 828 } /*else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)*/ 829 else/*listener not registered ,Restart Discovery wheel*/ 830 { 831 PHDBG_INFO("Hal4:No listener registered.Ignoring Discovery \ 832 Notification"); 833 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 834 PHDBG_INFO("Hal4:Restart discovery4"); 835 status = phHciNfc_Restart_Discovery ( 836 (void *)Hal4Ctxt->psHciHandle, 837 (void *)gpphHal4Nfc_Hwref, 838 FALSE 839 ); 840 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 841 eHal4StateConfiguring: 842 Hal4Ctxt->Hal4NextState); 843 } 844 }/*if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)*/ 845 else/*NULL info received*/ 846 { 847 sDiscoveryInfo.NumberOfDevices 848 = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 849 sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list; 850 uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo; 851 /*If Discovery info is available from previous notifications try to 852 notify that to the upper layer*/ 853 if((NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification) 854 #ifdef NFC_RF_NOISE_SW 855 &&((NFCSTATUS_SUCCESS == status) 856 || (NFCSTATUS_MULTIPLE_TAGS == status)) 857 #endif /* #ifdef NFC_RF_NOISE_SW */ 858 ) 859 { 860 #ifndef NFC_RF_NOISE_SW 861 status = (((NFCSTATUS_SUCCESS != status) 862 && (NFCSTATUS_MULTIPLE_TAGS != status)) 863 &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))? 864 NFCSTATUS_SUCCESS:status; 865 #endif/*#ifndef NFC_RF_NOISE_SW*/ 866 PHDBG_INFO("Hal4:Calling Discovery Handler2"); 867 (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)( 868 (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt), 869 NFC_DISCOVERY_NOTIFICATION, 870 uNotificationInfo, 871 status 872 ); 873 } 874 else/*Restart Discovery wheel*/ 875 { 876 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 877 PHDBG_INFO("Hal4:Restart discovery5"); 878 status = phHciNfc_Restart_Discovery ( 879 (void *)Hal4Ctxt->psHciHandle, 880 (void *)gpphHal4Nfc_Hwref, 881 FALSE 882 ); 883 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status? 884 eHal4StateConfiguring:Hal4Ctxt->Hal4NextState); 885 } 886 }/*else*/ 887 return; 888 } 889 890 891 /**Register Notification handlers*/ 892 NFCSTATUS phHal4Nfc_RegisterNotification( 893 phHal_sHwReference_t *psHwReference, 894 phHal4Nfc_RegisterType_t eRegisterType, 895 pphHal4Nfc_Notification_t pNotificationHandler, 896 void *Context 897 ) 898 { 899 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; 900 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 901 if(NULL == pNotificationHandler || NULL == psHwReference) 902 { 903 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 904 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); 905 } 906 else if((NULL == psHwReference->hal_context) 907 || (((phHal4Nfc_Hal4Ctxt_t *) 908 psHwReference->hal_context)->Hal4CurrentState 909 < eHal4StateOpenAndReady) 910 || (((phHal4Nfc_Hal4Ctxt_t *) 911 psHwReference->hal_context)->Hal4NextState 912 == eHal4StateClosed)) 913 { 914 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 915 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 916 } 917 else 918 { 919 /*Extract context from hardware reference*/ 920 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 921 switch(eRegisterType) 922 { 923 case eRegisterTagDiscovery: 924 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = Context; 925 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification 926 = pNotificationHandler; /*Register the tag Notification*/ 927 break; 928 case eRegisterP2PDiscovery: 929 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = Context; 930 Hal4Ctxt->sUpperLayerInfo.pP2PNotification 931 = pNotificationHandler; /*Register the P2P Notification*/ 932 break; 933 case eRegisterHostCardEmulation: 934 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED; 935 break; 936 case eRegisterSecureElement: 937 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = Context; 938 Hal4Ctxt->sUpperLayerInfo.pEventNotification 939 = pNotificationHandler; /*Register the Se Notification*/ 940 break; 941 default: 942 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = Context; 943 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler 944 = pNotificationHandler; /*Register the default Notification*/ 945 break; 946 } 947 PHDBG_INFO("Hal4:listener registered"); 948 } 949 return RetStatus; 950 } 951 952 953 /**Unregister Notification handlers*/ 954 NFCSTATUS phHal4Nfc_UnregisterNotification( 955 phHal_sHwReference_t *psHwReference, 956 phHal4Nfc_RegisterType_t eRegisterType, 957 void *Context 958 ) 959 { 960 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; 961 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 962 if(psHwReference == NULL) 963 { 964 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 965 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER); 966 } 967 else if((NULL == psHwReference->hal_context) 968 || (((phHal4Nfc_Hal4Ctxt_t *) 969 psHwReference->hal_context)->Hal4CurrentState 970 < eHal4StateOpenAndReady) 971 || (((phHal4Nfc_Hal4Ctxt_t *) 972 psHwReference->hal_context)->Hal4NextState 973 == eHal4StateClosed)) 974 { 975 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 976 RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED); 977 } 978 else 979 { 980 /*Extract context from hardware reference*/ 981 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 982 switch(eRegisterType) 983 { 984 case eRegisterTagDiscovery: 985 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = Context; 986 Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = NULL; 987 /*UnRegister the tag Notification*/ 988 Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL; 989 PHDBG_INFO("Hal4:Tag Discovery Listener Unregistered"); 990 break; 991 case eRegisterP2PDiscovery: 992 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = NULL; 993 /*UnRegister the p2p Notification*/ 994 Hal4Ctxt->sUpperLayerInfo.pP2PNotification = NULL; 995 PHDBG_INFO("Hal4:P2P Discovery Listener Unregistered"); 996 break; 997 case eRegisterHostCardEmulation:/*RFU*/ 998 RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED; 999 break; 1000 /*UnRegister the Se Notification*/ 1001 case eRegisterSecureElement: 1002 Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = NULL; 1003 Hal4Ctxt->sUpperLayerInfo.pEventNotification = NULL; 1004 PHDBG_INFO("Hal4:SE Listener Unregistered"); 1005 break; 1006 default: 1007 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = NULL; 1008 /*UnRegister the default Notification*/ 1009 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler = NULL; 1010 PHDBG_INFO("Hal4:Default Listener Unregistered"); 1011 break; 1012 } 1013 } 1014 return RetStatus; 1015 } 1016 1017 1018