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