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