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