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 /*! 18 * \file phLibNfc_initiator.c 19 20 * Project: NFC FRI 1.1 21 * 22 * $Date: Fri Apr 23 14:34:08 2010 $ 23 * $Author: ing07385 $ 24 * $Revision: 1.53 $ 25 * $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $ 26 * 27 */ 28 29 /* 30 ************************* Header Files **************************************** 31 */ 32 33 #include <phLibNfcStatus.h> 34 #include <phLibNfc.h> 35 #include <phHal4Nfc.h> 36 #include <phOsalNfc.h> 37 #include <phLibNfc_Internal.h> 38 #include <phLibNfc_SE.h> 39 #include <phLibNfc_ndef_raw.h> 40 #include <phLibNfc_initiator.h> 41 #include <phLibNfc_discovery.h> 42 43 44 /* 45 *************************** Macro's **************************************** 46 */ 47 48 #ifndef STATIC_DISABLE 49 #define STATIC static 50 #else 51 #define STATIC 52 #endif 53 54 /* 55 *************************** Global Variables ********************************** 56 */ 57 58 #define PN544_IO_TIMEOUT_RESPONSE 0x89 59 60 /* 61 *************************** Static Function Declaration *********************** 62 */ 63 64 /* Target discvovery notification callback */ 65 STATIC void phLibNfc_NotificationRegister_Resp_Cb ( 66 void *context, 67 phHal_eNotificationType_t type, 68 phHal4Nfc_NotificationInfo_t info, 69 NFCSTATUS status 70 ); 71 72 /*Remote device connect response callback*/ 73 STATIC void phLibNfc_RemoteDev_Connect_Cb( 74 void *pContext, 75 phHal_sRemoteDevInformation_t *pRmtdev_info, 76 NFCSTATUS status 77 ); 78 79 #ifdef RECONNECT_SUPPORT 80 STATIC 81 void 82 phLibNfc_config_discovery_con_failure_cb ( 83 void *context, 84 NFCSTATUS status); 85 #endif /* #ifdef RECONNECT_SUPPORT */ 86 87 /*Remote device disconnect response callback*/ 88 STATIC void phLibNfc_RemoteDev_Disconnect_cb( 89 void *context, 90 phHal_sRemoteDevInformation_t *reg_handle, 91 NFCSTATUS status 92 ); 93 /*Remote device Transceive response callback*/ 94 STATIC void phLibNfc_RemoteDev_Transceive_Cb(void *context, 95 phHal_sRemoteDevInformation_t *pRmtdev_info, 96 phNfc_sData_t *response, 97 NFCSTATUS status 98 ); 99 /*Set P2P config paramater response callback*/ 100 STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb( 101 void *context, 102 NFCSTATUS status 103 ); 104 105 106 /* 107 *************************** Function Definitions ****************************** 108 */ 109 110 /** 111 * Response to target discovery. 112 */ 113 STATIC 114 void phLibNfc_NotificationRegister_Resp_Cb ( 115 void *context, 116 phHal_eNotificationType_t type, 117 phHal4Nfc_NotificationInfo_t info, 118 NFCSTATUS status 119 ) 120 { 121 NFCSTATUS RetVal = NFCSTATUS_SUCCESS, 122 Status = NFCSTATUS_SUCCESS; 123 uint16_t DeviceIndx, DeviceIndx1; 124 uint8_t sak_byte=0; 125 uint8_t tag_disc_flg = 0; 126 phLibNfc_NtfRegister_RspCb_t pClientCb=NULL; 127 pClientCb =gpphLibContext->CBInfo.pClientNtfRegRespCB; 128 PHNFC_UNUSED_VARIABLE(context); 129 130 131 if(( type != NFC_DISCOVERY_NOTIFICATION ) 132 &&(PHNFCSTATUS(status)!=NFCSTATUS_DESELECTED)) 133 { 134 Status = NFCSTATUS_FAILED; 135 } 136 else if (PHNFCSTATUS(status) == NFCSTATUS_DESELECTED) 137 { 138 return; 139 } 140 else 141 { 142 DeviceIndx=0;DeviceIndx1=0; 143 while(DeviceIndx < info.psDiscoveryInfo->NumberOfDevices) 144 { 145 switch(info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]->RemDevType) 146 { 147 case phHal_eMifare_PICC: 148 { 149 /*Mifare Tag discovered*/ 150 sak_byte = info.psDiscoveryInfo-> 151 ppRemoteDevInfo[DeviceIndx]->RemoteDevInfo.Iso14443A_Info.Sak; 152 if((TRUE == gpphLibContext->RegNtfType.MifareUL)&& (sak_byte==0x00)) 153 { 154 /*Copy the tag related info*/ 155 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 156 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 157 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 158 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 159 gpphLibContext->Discov_handle[DeviceIndx1] = 160 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 161 DeviceIndx1++; 162 tag_disc_flg++; 163 } 164 165 if((TRUE == gpphLibContext->RegNtfType.MifareStd)&& 166 (((sak_byte & 0x18)==0x08)||((sak_byte & 0x18)==0x18) || 167 (sak_byte == 0x01))) 168 { 169 /*Copy the tag related info*/ 170 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 171 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 172 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 173 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 174 gpphLibContext->Discov_handle[DeviceIndx1]= 175 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 176 DeviceIndx1++; 177 tag_disc_flg++; 178 } 179 180 }break; 181 case phHal_eISO14443_A_PICC: 182 { 183 /*ISO 14443-A type tag discovered*/ 184 if(TRUE == gpphLibContext->RegNtfType.ISO14443_4A) 185 { 186 /*Copy the ISO type A tag info*/ 187 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 188 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 189 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 190 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 191 gpphLibContext->Discov_handle[DeviceIndx1] = 192 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 193 DeviceIndx1++; 194 tag_disc_flg++; 195 } 196 }break; 197 case phHal_eISO14443_3A_PICC: 198 { 199 /*ISO 14443-A type tag discovered*/ 200 if(TRUE == gpphLibContext->RegNtfType.MifareUL) 201 { 202 /*Copy the ISO type A tag info*/ 203 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 204 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 205 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 206 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 207 gpphLibContext->Discov_handle[DeviceIndx1] = 208 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 209 DeviceIndx1++; 210 tag_disc_flg++; 211 } 212 }break; 213 case phHal_eISO14443_B_PICC: 214 { 215 /*ISO 14443-B type tag Discovered */ 216 if(TRUE == gpphLibContext->RegNtfType.ISO14443_4B) 217 { 218 /*Copy the Type B tag info */ 219 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 220 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 221 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 222 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 223 gpphLibContext->Discov_handle[DeviceIndx1] = 224 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 225 DeviceIndx1++; 226 tag_disc_flg++; 227 } 228 }break; 229 case phHal_eFelica_PICC: 230 { 231 /*Felica Type Tag Discovered */ 232 if(TRUE == gpphLibContext->RegNtfType.Felica) 233 { 234 /*Copy the Felica tag info */ 235 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 236 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 237 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 238 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 239 gpphLibContext->Discov_handle[DeviceIndx1] = 240 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 241 DeviceIndx1++; 242 tag_disc_flg++; 243 } 244 }break; 245 case phHal_eJewel_PICC: 246 { 247 /*Jewel Type Tag Discovered */ 248 if(TRUE == gpphLibContext->RegNtfType.Jewel) 249 { 250 /*Copy the Felica tag info */ 251 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 252 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 253 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 254 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 255 gpphLibContext->Discov_handle[DeviceIndx1] = 256 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 257 DeviceIndx1++; 258 tag_disc_flg++; 259 } 260 } 261 break; 262 case phHal_eISO15693_PICC: 263 { 264 /*Jewel Type Tag Discovered */ 265 if(TRUE == gpphLibContext->RegNtfType.ISO15693) 266 { 267 /*Copy the Felica tag info */ 268 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 269 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 270 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 271 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 272 gpphLibContext->Discov_handle[DeviceIndx1] = 273 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 274 DeviceIndx1++; 275 tag_disc_flg++; 276 } 277 } 278 break; 279 case phHal_eNfcIP1_Target: 280 { 281 if(TRUE == gpphLibContext->RegNtfType.NFC) 282 { 283 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 284 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 285 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 286 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo; 287 gpphLibContext->Discov_handle[DeviceIndx1] = 288 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 289 DeviceIndx1++; 290 tag_disc_flg++; 291 } 292 } 293 break; 294 case phHal_eNfcIP1_Initiator: 295 { 296 if(TRUE == gpphLibContext->RegNtfType.NFC) 297 { 298 gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateConnect; 299 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo= 300 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]; 301 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev = 302 (phLibNfc_Handle)gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo; 303 gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle= 304 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev; 305 DeviceIndx1++; 306 tag_disc_flg++; 307 } 308 } 309 break; 310 default : 311 { 312 break; 313 } 314 } 315 DeviceIndx++; 316 } 317 } 318 319 if((tag_disc_flg >0 )&&(status != NFCSTATUS_FAILED)) 320 { 321 gpphLibContext->dev_cnt = tag_disc_flg; 322 /* Check for if the discovered tags are multiple or 323 Multiple protocol tag */ 324 if((gpphLibContext->dev_cnt > 1)&&( 325 (status ==NFCSTATUS_MULTIPLE_PROTOCOLS) || 326 (status ==NFCSTATUS_MULTIPLE_TAGS)) ) 327 { 328 status = status; 329 } 330 else 331 { 332 status =NFCSTATUS_SUCCESS; 333 } 334 /*Notify to upper layer the no of tag discovered and 335 the protocol */ 336 if (NULL != pClientCb) 337 { 338 pClientCb( 339 (void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx, 340 gpphLibContext->psRemoteDevList, 341 gpphLibContext->dev_cnt, 342 status 343 ); 344 } 345 346 } 347 else if(PHNFCSTATUS(status)==NFCSTATUS_DESELECTED) 348 { 349 info.psDiscoveryInfo->NumberOfDevices = 0; 350 if (NULL != pClientCb) 351 { 352 gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateRelease; 353 pClientCb((void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx, 354 NULL, 355 0, 356 status); 357 } 358 359 } 360 else /*Reconfigure the discovery wheel*/ 361 { 362 RetVal = phHal4Nfc_ConfigureDiscovery ( gpphLibContext->psHwReference, 363 NFC_DISCOVERY_RESUME, 364 &(gpphLibContext->sADDconfig), 365 phLibNfc_config_discovery_cb, 366 gpphLibContext); 367 368 if((RetVal!=NFCSTATUS_SUCCESS) &&(RetVal!=NFCSTATUS_PENDING)) 369 { 370 Status = NFCSTATUS_FAILED; 371 } 372 373 } 374 if(Status == NFCSTATUS_FAILED) 375 { 376 if (NULL != pClientCb) 377 { 378 pClientCb(gpphLibContext->CBInfo.pClientNtfRegRespCntx, 379 NULL, 380 0, 381 Status); 382 } 383 } 384 return; 385 } 386 387 /** 388 * This interface registers notification handler for target discovery. 389 */ 390 NFCSTATUS 391 phLibNfc_RemoteDev_NtfRegister( 392 phLibNfc_Registry_Info_t* pRegistryInfo, 393 phLibNfc_NtfRegister_RspCb_t pNotificationHandler, 394 void *pContext 395 ) 396 { 397 NFCSTATUS RetVal = NFCSTATUS_SUCCESS; 398 399 400 /*Check for valid parameters*/ 401 if((NULL == pNotificationHandler) 402 || (NULL == pContext) 403 ||(NULL== pRegistryInfo)) 404 { 405 RetVal= NFCSTATUS_INVALID_PARAMETER; 406 } 407 else if((NULL == gpphLibContext) || 408 (gpphLibContext->LibNfcState.cur_state 409 == eLibNfcHalStateShutdown)) 410 { 411 RetVal = NFCSTATUS_NOT_INITIALISED; 412 } 413 else if(gpphLibContext->LibNfcState.next_state 414 == eLibNfcHalStateShutdown) 415 { 416 /*Next state is shutdown*/ 417 RetVal= NFCSTATUS_SHUTDOWN; 418 } 419 else 420 { 421 422 PHDBG_INFO("LibNfc:Registering Notification Handler"); 423 424 425 (void) memcpy(&(gpphLibContext->RegNtfType),pRegistryInfo, 426 sizeof(phLibNfc_Registry_Info_t)); 427 /* Register Discovery Notification Handler*/ 428 429 /*Register for NFCIP1 target type*/ 430 RetVal = phHal4Nfc_RegisterNotification( 431 gpphLibContext->psHwReference, 432 eRegisterP2PDiscovery, 433 phLibNfc_NotificationRegister_Resp_Cb, 434 (void*)gpphLibContext 435 ); 436 /*Register for Tag discovery*/ 437 RetVal = phHal4Nfc_RegisterNotification( 438 gpphLibContext->psHwReference, 439 eRegisterTagDiscovery, 440 phLibNfc_NotificationRegister_Resp_Cb, 441 (void*)gpphLibContext 442 ); 443 gpphLibContext->CBInfo.pClientNtfRegRespCB = pNotificationHandler; 444 gpphLibContext->CBInfo.pClientNtfRegRespCntx = pContext; 445 /*Register notification handler with below layer*/ 446 447 } 448 return RetVal; 449 } 450 /** 451 * This interface unregisters notification handler for target discovery. 452 */ 453 NFCSTATUS phLibNfc_RemoteDev_NtfUnregister(void) 454 { 455 NFCSTATUS RetVal = NFCSTATUS_SUCCESS; 456 if((NULL == gpphLibContext) || 457 (gpphLibContext->LibNfcState.cur_state 458 == eLibNfcHalStateShutdown)) 459 { 460 /*Lib Nfc not Initialized*/ 461 RetVal = NFCSTATUS_NOT_INITIALISED; 462 } 463 else if(gpphLibContext->LibNfcState.next_state 464 == eLibNfcHalStateShutdown) 465 { 466 /*Lib Nfc Shutdown*/ 467 RetVal= NFCSTATUS_SHUTDOWN; 468 } 469 else 470 { 471 /*Unregister notification handler with lower layer */ 472 RetVal = phHal4Nfc_UnregisterNotification( 473 gpphLibContext->psHwReference, 474 eRegisterP2PDiscovery, 475 gpphLibContext); 476 477 RetVal = phHal4Nfc_UnregisterNotification( 478 gpphLibContext->psHwReference, 479 eRegisterTagDiscovery, 480 gpphLibContext); 481 482 gpphLibContext->CBInfo.pClientNtfRegRespCB = NULL; 483 gpphLibContext->CBInfo.pClientNtfRegRespCntx =NULL; 484 PHDBG_INFO("LibNfc:Unregister Notification Handler"); 485 } 486 return RetVal; 487 } 488 489 #ifdef RECONNECT_SUPPORT 490 491 NFCSTATUS 492 phLibNfc_RemoteDev_ReConnect ( 493 phLibNfc_Handle hRemoteDevice, 494 pphLibNfc_ConnectCallback_t pNotifyReConnect_RspCb, 495 void *pContext) 496 { 497 498 NFCSTATUS ret_val = NFCSTATUS_FAILED; 499 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo = NULL; 500 501 if ((NULL == gpphLibContext) 502 || (eLibNfcHalStateShutdown == 503 gpphLibContext->LibNfcState.cur_state)) 504 { 505 ret_val = NFCSTATUS_NOT_INITIALISED; 506 } 507 else if ((NULL == pContext) 508 || (NULL == pNotifyReConnect_RspCb) 509 || (NULL == (void *)hRemoteDevice)) 510 { 511 /* Check valid parameters */ 512 ret_val = NFCSTATUS_INVALID_PARAMETER; 513 } 514 /* Check valid lib nfc State */ 515 else if (gpphLibContext->LibNfcState.next_state 516 == eLibNfcHalStateShutdown) 517 { 518 ret_val = NFCSTATUS_SHUTDOWN; 519 } 520 else if (0 == gpphLibContext->Connected_handle) 521 { 522 ret_val = NFCSTATUS_TARGET_NOT_CONNECTED; 523 } 524 else if ((gpphLibContext->Discov_handle[0] != hRemoteDevice) 525 && (gpphLibContext->Discov_handle[1] != hRemoteDevice) 526 && (gpphLibContext->Discov_handle[2] != hRemoteDevice) 527 && (gpphLibContext->Discov_handle[3] != hRemoteDevice) 528 && (gpphLibContext->Discov_handle[4] != hRemoteDevice) 529 && (gpphLibContext->Discov_handle[5] != hRemoteDevice) 530 && (gpphLibContext->Discov_handle[6] != hRemoteDevice) 531 && (gpphLibContext->Discov_handle[7] != hRemoteDevice) 532 && (gpphLibContext->Discov_handle[8] != hRemoteDevice) 533 && (gpphLibContext->Discov_handle[9] != hRemoteDevice)) 534 { 535 ret_val = NFCSTATUS_INVALID_HANDLE; 536 } 537 else 538 { 539 psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t *)hRemoteDevice; 540 541 /* Call the HAL connect*/ 542 ret_val = phHal4Nfc_Connect (gpphLibContext->psHwReference, 543 psRemoteDevInfo, 544 phLibNfc_RemoteDev_Connect_Cb, 545 (void *)gpphLibContext); 546 547 if (NFCSTATUS_PENDING == ret_val) 548 { 549 /* If HAL Connect is pending update the LibNFC state machine 550 and store the CB pointer and Context, 551 mark the General CB pending status is TRUE */ 552 gpphLibContext->CBInfo.pClientConnectCb = pNotifyReConnect_RspCb; 553 gpphLibContext->CBInfo.pClientConCntx = pContext; 554 gpphLibContext->status.GenCb_pending_status = TRUE; 555 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect; 556 557 gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle; 558 559 gpphLibContext->Connected_handle = hRemoteDevice; 560 } 561 else if (NFCSTATUS_INVALID_REMOTE_DEVICE == PHNFCSTATUS(ret_val)) 562 { 563 /* The Handle given for connect is invalid*/ 564 ret_val = NFCSTATUS_TARGET_NOT_CONNECTED; 565 } 566 else 567 { 568 /* Lower layer returns internal error code return NFCSTATUS_FAILED*/ 569 ret_val = NFCSTATUS_FAILED; 570 } 571 } 572 573 return ret_val; 574 } 575 #endif /* #ifdef RECONNECT_SUPPORT */ 576 577 578 /** 579 * Connect to a single Remote Device 580 */ 581 NFCSTATUS phLibNfc_RemoteDev_Connect( 582 phLibNfc_Handle hRemoteDevice, 583 pphLibNfc_ConnectCallback_t pNotifyConnect_RspCb, 584 void *pContext 585 ) 586 { 587 588 NFCSTATUS RetVal = NFCSTATUS_FAILED; 589 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo; 590 591 if((NULL == gpphLibContext) || 592 (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) 593 { 594 RetVal = NFCSTATUS_NOT_INITIALISED; 595 }/* Check valid parameters*/ 596 else if((NULL == pContext) 597 || (NULL == pNotifyConnect_RspCb) 598 || (NULL == (void*)hRemoteDevice)) 599 { 600 RetVal= NFCSTATUS_INVALID_PARAMETER; 601 } 602 /* Check valid lib nfc State*/ 603 else if(gpphLibContext->LibNfcState.next_state 604 == eLibNfcHalStateShutdown) 605 { 606 RetVal= NFCSTATUS_SHUTDOWN; 607 } 608 else if((gpphLibContext->Discov_handle[0] != hRemoteDevice)&& 609 (gpphLibContext->Discov_handle[1] != hRemoteDevice)&& 610 (gpphLibContext->Discov_handle[2] != hRemoteDevice)&& 611 (gpphLibContext->Discov_handle[3] != hRemoteDevice)&& 612 (gpphLibContext->Discov_handle[4] != hRemoteDevice)&& 613 (gpphLibContext->Discov_handle[5] != hRemoteDevice)&& 614 (gpphLibContext->Discov_handle[6] != hRemoteDevice)&& 615 (gpphLibContext->Discov_handle[7] != hRemoteDevice)&& 616 (gpphLibContext->Discov_handle[8] != hRemoteDevice)&& 617 (gpphLibContext->Discov_handle[9] != hRemoteDevice)) 618 { 619 RetVal= NFCSTATUS_INVALID_HANDLE; 620 } 621 else if ((hRemoteDevice != gpphLibContext->Connected_handle) 622 && (0 != gpphLibContext->Connected_handle)) 623 { 624 RetVal = NFCSTATUS_FAILED; 625 } 626 else 627 { 628 psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice; 629 630 /* Call the HAL connect*/ 631 RetVal = phHal4Nfc_Connect(gpphLibContext->psHwReference, 632 psRemoteDevInfo, 633 phLibNfc_RemoteDev_Connect_Cb, 634 (void* )gpphLibContext); 635 if(RetVal== NFCSTATUS_PENDING) 636 { 637 /* If HAL Connect is pending update the LibNFC state machine 638 and store the CB pointer and Context, 639 mark the General CB pending status is TRUE*/ 640 gpphLibContext->CBInfo.pClientConnectCb = pNotifyConnect_RspCb; 641 gpphLibContext->CBInfo.pClientConCntx = pContext; 642 gpphLibContext->status.GenCb_pending_status=TRUE; 643 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect; 644 gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle; 645 gpphLibContext->Connected_handle = hRemoteDevice; 646 } 647 else if(PHNFCSTATUS(RetVal) == NFCSTATUS_INVALID_REMOTE_DEVICE) 648 { 649 /* The Handle given for connect is invalid*/ 650 RetVal= NFCSTATUS_TARGET_NOT_CONNECTED; 651 } 652 else 653 { 654 /* Lower layer returns internal error code return NFCSTATUS_FAILED*/ 655 RetVal = NFCSTATUS_FAILED; 656 } 657 } 658 return RetVal; 659 } 660 661 #ifdef RECONNECT_SUPPORT 662 STATIC 663 void 664 phLibNfc_config_discovery_con_failure_cb ( 665 void *context, 666 NFCSTATUS status) 667 { 668 if((phLibNfc_LibContext_t *)context == gpphLibContext) 669 { /*check for same context*/ 670 pphLibNfc_ConnectCallback_t ps_client_con_cb = 671 gpphLibContext->CBInfo.pClientConnectCb; 672 673 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 674 { 675 /*If shutdown called in between allow shutdown to happen*/ 676 phLibNfc_Pending_Shutdown(); 677 status = NFCSTATUS_SHUTDOWN; 678 } 679 else 680 { 681 gpphLibContext->status.GenCb_pending_status = FALSE; 682 gpphLibContext->status.DiscEnbl_status = FALSE; 683 status = NFCSTATUS_TARGET_LOST; 684 685 phLibNfc_UpdateCurState (status,gpphLibContext); 686 #ifdef RESTART_CFG 687 if(gpphLibContext->status.Discovery_pending_status == TRUE) 688 { 689 NFCSTATUS RetStatus = NFCSTATUS_FAILED; 690 /* Application has called discovery before receiving this callback, 691 so NO notification to the upper layer, instead lower layer 692 discovery is called */ 693 gpphLibContext->status.Discovery_pending_status = FALSE; 694 RetStatus = phHal4Nfc_ConfigureDiscovery( 695 gpphLibContext->psHwReference, 696 gpphLibContext->eLibNfcCfgMode, 697 &gpphLibContext->sADDconfig, 698 (pphLibNfc_RspCb_t) 699 phLibNfc_config_discovery_cb, 700 (void *)gpphLibContext); 701 if (NFCSTATUS_PENDING == RetStatus) 702 { 703 (void)phLibNfc_UpdateNextState(gpphLibContext, 704 eLibNfcHalStateConfigReady); 705 gpphLibContext->status.GenCb_pending_status = TRUE; 706 gpphLibContext->status.DiscEnbl_status = TRUE; 707 } 708 } 709 710 #endif /* #ifdef RESTART_CFG */ 711 } 712 713 if (NULL != ps_client_con_cb) 714 { 715 gpphLibContext->CBInfo.pClientConnectCb = NULL; 716 /* Call the upper layer callback*/ 717 ps_client_con_cb (gpphLibContext->CBInfo.pClientConCntx, 718 0, NULL, status); 719 } 720 } /*End of if-context check*/ 721 else 722 { /*exception: wrong context pointer returned*/ 723 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 724 status = NFCSTATUS_FAILED; 725 } 726 727 728 } 729 #endif /* #ifdef RECONNECT_SUPPORT */ 730 /** 731 * Response callback for remote device connect 732 */ 733 STATIC void phLibNfc_RemoteDev_Connect_Cb( 734 void *pContext, 735 phHal_sRemoteDevInformation_t *pRmtdev_info, 736 NFCSTATUS status 737 ) 738 { 739 NFCSTATUS Connect_status = NFCSTATUS_SUCCESS; 740 /*Check valid lib nfc context is returned from lower layer*/ 741 if((phLibNfc_LibContext_t *)pContext == gpphLibContext) 742 { 743 gpphLibContext->LastTrancvSuccess = FALSE; 744 745 /* Mark General Callback pending status as false*/ 746 gpphLibContext->status.GenCb_pending_status = FALSE; 747 748 /* Check the shutdown is called during the lower layer Connect in process, 749 If yes call shutdown call and return NFCSTATUS_SHUTDOWN */ 750 if((eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)) 751 { 752 phLibNfc_Pending_Shutdown(); 753 Connect_status = NFCSTATUS_SHUTDOWN; 754 755 } 756 else if(PHNFCSTATUS(status)==NFCSTATUS_SUCCESS) 757 { 758 /* Copy the Remote device address as connected handle*/ 759 gpphLibContext->Connected_handle = (uintptr_t)pRmtdev_info; 760 /* Update the state to connected and return status as SUCCESS*/ 761 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect; 762 Connect_status = NFCSTATUS_SUCCESS; 763 } 764 else 765 { /* if(PHNFCSTATUS(status)==NFCSTATUS_INVALID_REMOTE_DEVICE) */ 766 /* If remote device is invalid return as TARGET LOST to upper layer*/ 767 /* If error code is other than SUCCESS return NFCSTATUS_TARGET_LOST */ 768 Connect_status = NFCSTATUS_TARGET_LOST; 769 gpphLibContext->Connected_handle = gpphLibContext->Prev_Connected_handle ; 770 } 771 gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE; 772 /* Update the Current Sate*/ 773 phLibNfc_UpdateCurState(Connect_status,(phLibNfc_LibContext_t *)pContext); 774 /* Call the upper layer callback*/ 775 gpphLibContext->CBInfo.pClientConnectCb( 776 gpphLibContext->CBInfo.pClientConCntx, 777 (phLibNfc_Handle)pRmtdev_info, 778 (phLibNfc_sRemoteDevInformation_t*)pRmtdev_info, 779 Connect_status); 780 } 781 else 782 { /*exception: wrong context pointer returned*/ 783 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 784 } 785 return; 786 } 787 788 /** 789 * Allows to disconnect from already connected target. 790 */ 791 NFCSTATUS phLibNfc_RemoteDev_Disconnect( phLibNfc_Handle hRemoteDevice, 792 phLibNfc_eReleaseType_t ReleaseType, 793 pphLibNfc_DisconnectCallback_t pDscntCallback, 794 void* pContext 795 ) 796 { 797 NFCSTATUS RetVal = NFCSTATUS_SUCCESS; 798 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo=NULL; 799 800 /*Check for valid parameter*/ 801 if((NULL == gpphLibContext) || 802 (gpphLibContext->LibNfcState.cur_state 803 == eLibNfcHalStateShutdown)) 804 { 805 RetVal = NFCSTATUS_NOT_INITIALISED; 806 } 807 else if((NULL == pContext) || 808 (NULL == pDscntCallback)||(hRemoteDevice == 0)) 809 { 810 RetVal= NFCSTATUS_INVALID_PARAMETER; 811 } 812 /* Check for valid state,If De initialize is called then 813 return NFCSTATUS_SHUTDOWN */ 814 else if(gpphLibContext->LibNfcState.next_state 815 == eLibNfcHalStateShutdown) 816 { 817 RetVal= NFCSTATUS_SHUTDOWN; 818 } 819 else if(gpphLibContext->Connected_handle==0) 820 { 821 RetVal=NFCSTATUS_TARGET_NOT_CONNECTED; 822 } 823 /* The given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE*/ 824 else if(hRemoteDevice != gpphLibContext->Connected_handle ) 825 { 826 RetVal=NFCSTATUS_INVALID_HANDLE; 827 } 828 else 829 { 830 if((eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) 831 ||((gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)&& 832 (ReleaseType != NFC_SMARTMX_RELEASE)) 833 ||((gpphLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)&& 834 (ReleaseType == NFC_SMARTMX_RELEASE))) 835 { /* Previous disconnect callback is pending */ 836 RetVal = NFCSTATUS_REJECTED; 837 } 838 #ifndef LLCP_CHANGES 839 else if(eLibNfcHalStateTransaction == gpphLibContext->LibNfcState.next_state) 840 { /* Previous Transaction is Pending*/ 841 RetVal = NFCSTATUS_BUSY; 842 PHDBG_INFO("LibNfc:Transaction is Pending"); 843 } 844 #endif /* #ifdef LLCP_CHANGES */ 845 else 846 { 847 gpphLibContext->ReleaseType = ReleaseType; 848 psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice; 849 RetVal = phHal4Nfc_Disconnect(gpphLibContext->psHwReference, 850 (phHal_sRemoteDevInformation_t*)psRemoteDevInfo, 851 gpphLibContext->ReleaseType, 852 (pphHal4Nfc_DiscntCallback_t) 853 phLibNfc_RemoteDev_Disconnect_cb, 854 (void *)gpphLibContext); 855 if( NFCSTATUS_PENDING == PHNFCSTATUS(RetVal)) 856 { 857 /*Copy the upper layer Callback pointer and context*/ 858 gpphLibContext->CBInfo.pClientDisConnectCb = pDscntCallback; 859 gpphLibContext->CBInfo.pClientDConCntx = pContext; 860 /* Mark general callback pending status as TRUE and update the state*/ 861 gpphLibContext->status.GenCb_pending_status=TRUE; 862 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease; 863 864 } 865 else 866 { 867 /*If lower layer returns other than pending 868 (internal error codes) return NFCSTATUS_FAILED */ 869 RetVal = NFCSTATUS_FAILED; 870 } 871 } 872 } 873 return RetVal; 874 } 875 /** 876 * Response callback for Remote device Disconnect. 877 */ 878 STATIC void phLibNfc_RemoteDev_Disconnect_cb( 879 void *context, 880 phHal_sRemoteDevInformation_t *reg_handle, 881 NFCSTATUS status 882 ) 883 { 884 NFCSTATUS DisCnct_status = NFCSTATUS_SUCCESS; 885 pphLibNfc_DisconnectCallback_t pUpper_NtfCb = NULL; 886 void *pUpper_Context = NULL; 887 888 /* Copy the upper layer Callback and context*/ 889 pUpper_NtfCb = gpphLibContext->CBInfo.pClientDisConnectCb; 890 pUpper_Context = gpphLibContext->CBInfo.pClientDConCntx; 891 892 /* Check valid context is returned or not */ 893 if((phLibNfc_LibContext_t *)context != gpphLibContext) 894 { 895 /*exception: wrong context pointer returned*/ 896 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 897 } 898 else 899 { 900 /* Mark the General callback pending status FALSE */ 901 gpphLibContext->status.GenCb_pending_status = FALSE; 902 gpphLibContext->CBInfo.pClientDisConnectCb = NULL; 903 gpphLibContext->CBInfo.pClientDConCntx = NULL; 904 905 gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE; 906 gpphLibContext->LastTrancvSuccess = FALSE; 907 /*Reset Connected handle */ 908 gpphLibContext->Connected_handle=0x0000; 909 /*Reset previous Connected handle */ 910 gpphLibContext->Prev_Connected_handle = 0x0000; 911 912 if(gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired) 913 { 914 gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault; 915 } 916 if(NULL != gpphLibContext->psBufferedAuth) 917 { 918 if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer) 919 { 920 phOsalNfc_FreeMemory( 921 gpphLibContext->psBufferedAuth->sRecvData.buffer); 922 } 923 if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer) 924 { 925 phOsalNfc_FreeMemory( 926 gpphLibContext->psBufferedAuth->sSendData.buffer); 927 } 928 phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth); 929 gpphLibContext->psBufferedAuth = NULL; 930 } 931 } 932 /* Check DeInit is called or not */ 933 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 934 { 935 /*call shutdown and return status as NFCSTATUS_SHUTDOWN */ 936 phLibNfc_Pending_Shutdown(); 937 DisCnct_status = NFCSTATUS_SHUTDOWN; 938 } 939 else if(NFCSTATUS_SUCCESS == status) 940 { 941 DisCnct_status = NFCSTATUS_SUCCESS; 942 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease; 943 } 944 else 945 { 946 DisCnct_status = NFCSTATUS_FAILED; 947 phLibNfc_UpdateCurState(DisCnct_status,(phLibNfc_LibContext_t *)context); 948 } 949 /* Call the upper layer Callback */ 950 (*pUpper_NtfCb)(pUpper_Context, 951 (phLibNfc_Handle)reg_handle, 952 DisCnct_status); 953 return; 954 } 955 956 /** 957 * This interface allows to perform Read/write operation on remote device. 958 */ 959 NFCSTATUS 960 phLibNfc_RemoteDev_Transceive(phLibNfc_Handle hRemoteDevice, 961 phLibNfc_sTransceiveInfo_t* psTransceiveInfo, 962 pphLibNfc_TransceiveCallback_t pTransceive_RspCb, 963 void* pContext 964 ) 965 { 966 NFCSTATUS RetVal = NFCSTATUS_SUCCESS; 967 968 /*Check for valid parameter */ 969 970 if((NULL == gpphLibContext) || 971 (gpphLibContext->LibNfcState.cur_state 972 == eLibNfcHalStateShutdown)) 973 { 974 RetVal = NFCSTATUS_NOT_INITIALISED; 975 } 976 else if((NULL == psTransceiveInfo) 977 || (NULL == pTransceive_RspCb) 978 || (NULL == (void *)hRemoteDevice) 979 || (NULL == psTransceiveInfo->sRecvData.buffer) 980 || (NULL == psTransceiveInfo->sSendData.buffer) 981 || (NULL == pContext)) 982 { 983 RetVal= NFCSTATUS_INVALID_PARAMETER; 984 } 985 /* Check the state for DeInit is called or not,if yes return NFCSTATUS_SHUTDOWN*/ 986 else if(gpphLibContext->LibNfcState.next_state 987 == eLibNfcHalStateShutdown) 988 { 989 RetVal= NFCSTATUS_SHUTDOWN; 990 }/* If there is no handle connected return NFCSTATUS_TARGET_NOT_CONNECTED*/ 991 else if(gpphLibContext->Connected_handle==0) 992 { 993 RetVal=NFCSTATUS_TARGET_NOT_CONNECTED; 994 }/* If the given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE */ 995 else if(gpphLibContext->Connected_handle!= hRemoteDevice ) 996 { 997 RetVal=NFCSTATUS_INVALID_HANDLE; 998 } /*If the transceive is called before finishing the previous transceive function 999 return NFCSTATUS_REJECTED */ 1000 else if((eLibNfcHalStateTransaction == 1001 gpphLibContext->LibNfcState.next_state) 1002 ||(phHal_eNfcIP1_Initiator== 1003 ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType)) 1004 { 1005 RetVal = NFCSTATUS_REJECTED; 1006 } 1007 #ifdef LLCP_TRANSACT_CHANGES 1008 else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state) 1009 && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state)) 1010 { 1011 RetVal= NFCSTATUS_BUSY; 1012 } 1013 #endif /* #ifdef LLCP_TRANSACT_CHANGES */ 1014 else 1015 { 1016 gpphLibContext->ndef_cntx.eLast_Call = RawTrans; 1017 (void)memcpy((void *)(gpphLibContext->psTransInfo), 1018 (void *)psTransceiveInfo, 1019 sizeof(phLibNfc_sTransceiveInfo_t)); 1020 /* Check the given Mifare command is supported or not , 1021 If not return NFCSTATUS_COMMAND_NOT_SUPPORTED */ 1022 if( (((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType == 1023 phHal_eMifare_PICC)&& 1024 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRaw ) && 1025 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentA ) && 1026 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentB ) && 1027 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead16 ) && 1028 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead ) && 1029 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite16 ) && 1030 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite4 ) && 1031 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareDec ) && 1032 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareTransfer ) && 1033 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRestore ) && 1034 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareReadSector ) && 1035 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWriteSector )) 1036 { 1037 RetVal = NFCSTATUS_COMMAND_NOT_SUPPORTED; 1038 } 1039 if(eLibNfcHalStatePresenceChk != 1040 gpphLibContext->LibNfcState.next_state) 1041 { 1042 PHDBG_INFO("LibNfc:Transceive In Progress"); 1043 if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType == 1044 phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*) 1045 hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&& 1046 (phHal_eMifareAuthentA == gpphLibContext->psTransInfo->cmd.MfCmd)) 1047 { 1048 if(NULL != gpphLibContext->psBufferedAuth) 1049 { 1050 if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer) 1051 { 1052 phOsalNfc_FreeMemory( 1053 gpphLibContext->psBufferedAuth->sRecvData.buffer); 1054 } 1055 if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer) 1056 { 1057 phOsalNfc_FreeMemory( 1058 gpphLibContext->psBufferedAuth->sSendData.buffer); 1059 } 1060 phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth); 1061 } 1062 gpphLibContext->psBufferedAuth 1063 =(phLibNfc_sTransceiveInfo_t *) 1064 phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t)); 1065 gpphLibContext->psBufferedAuth->addr = psTransceiveInfo->addr; 1066 gpphLibContext->psBufferedAuth->cmd = psTransceiveInfo->cmd; 1067 gpphLibContext->psBufferedAuth->sSendData.length 1068 = psTransceiveInfo->sSendData.length; 1069 gpphLibContext->psBufferedAuth->sRecvData.length 1070 = psTransceiveInfo->sRecvData.length; 1071 gpphLibContext->psBufferedAuth->sSendData.buffer 1072 = (uint8_t *) 1073 phOsalNfc_GetMemory( 1074 gpphLibContext->psTransInfo->sSendData.length); 1075 1076 (void)memcpy((void *) 1077 (gpphLibContext->psBufferedAuth->sSendData.buffer), 1078 (void *)psTransceiveInfo->sSendData.buffer, 1079 psTransceiveInfo->sSendData.length); 1080 1081 gpphLibContext->psBufferedAuth->sRecvData.buffer 1082 = (uint8_t *) 1083 phOsalNfc_GetMemory( 1084 gpphLibContext->psTransInfo->sRecvData.length); 1085 } 1086 /*Call the lower layer Transceive function */ 1087 RetVal = phHal4Nfc_Transceive( gpphLibContext->psHwReference, 1088 (phHal_sTransceiveInfo_t*)gpphLibContext->psTransInfo, 1089 (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice, 1090 (pphHal4Nfc_TransceiveCallback_t) 1091 phLibNfc_RemoteDev_Transceive_Cb, 1092 (void* )gpphLibContext); 1093 if(PHNFCSTATUS(RetVal) == NFCSTATUS_PENDING) 1094 { 1095 /* Copy the upper layer callback pointer and context */ 1096 gpphLibContext->CBInfo.pClientTransceiveCb = pTransceive_RspCb; 1097 gpphLibContext->CBInfo.pClientTranseCntx = pContext; 1098 /* Mark the General callback pending status is TRUE */ 1099 gpphLibContext->status.GenCb_pending_status = TRUE; 1100 /*Transceive is in Progress-Used in Release API*/ 1101 1102 /*Update the state machine*/ 1103 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; 1104 } 1105 } 1106 else 1107 { 1108 gpphLibContext->status.GenCb_pending_status = FALSE; 1109 RetVal = NFCSTATUS_FAILED; 1110 } 1111 } 1112 return RetVal; 1113 } 1114 /** 1115 * Response for Remote device transceive. 1116 */ 1117 STATIC 1118 void phLibNfc_RemoteDev_Transceive_Cb(void *context, 1119 phHal_sRemoteDevInformation_t *pRmtdev_info, 1120 phNfc_sData_t *response, 1121 NFCSTATUS status 1122 ) 1123 { 1124 NFCSTATUS trans_status = NFCSTATUS_SUCCESS; 1125 phNfc_sData_t *trans_resp= NULL; 1126 void *pUpper_Context = NULL; 1127 pphLibNfc_TransceiveCallback_t pUpper_TagNtfCb = 1128 gpphLibContext->CBInfo.pClientTransceiveCb; 1129 1130 /*Check valid context is returned or not */ 1131 if((phLibNfc_LibContext_t *)context == gpphLibContext) 1132 { 1133 trans_resp = &gpphLibContext->psTransInfo->sRecvData; 1134 1135 pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx; 1136 gpphLibContext->status.GenCb_pending_status = FALSE; 1137 1138 /*If DeInit is called during the transceive, 1139 call the shutdown and return NFCSTATUS_SHUTDOWN*/ 1140 if(gpphLibContext->LibNfcState.next_state 1141 == eLibNfcHalStateShutdown) 1142 { 1143 phLibNfc_Pending_Shutdown(); 1144 trans_status = NFCSTATUS_SHUTDOWN; 1145 } 1146 /* If Disconnect is called return NFCSTATUS_ABORTED */ 1147 else if(eLibNfcHalStateRelease == 1148 gpphLibContext->LibNfcState.next_state) 1149 { 1150 trans_status = NFCSTATUS_ABORTED; 1151 } 1152 /* If the received lower layer status is not SUCCESS return NFCSTATUS_FAILED */ 1153 else if( NFCSTATUS_SUCCESS == status) 1154 { 1155 trans_status = NFCSTATUS_SUCCESS; 1156 } 1157 else if((PHNFCSTATUS(status) != NFCSTATUS_SUCCESS) && 1158 (phHal_eMifare_PICC == pRmtdev_info->RemDevType) && 1159 (0x00 != pRmtdev_info->RemoteDevInfo.Iso14443A_Info.Sak)) 1160 { 1161 gpphLibContext->LastTrancvSuccess = FALSE; 1162 trans_status = NFCSTATUS_FAILED; 1163 /* card type is mifare 1k/4k, then reconnect */ 1164 trans_status = phHal4Nfc_Connect(gpphLibContext->psHwReference, 1165 pRmtdev_info, 1166 (pphHal4Nfc_ConnectCallback_t) 1167 phLibNfc_Reconnect_Mifare_Cb, 1168 (void *)gpphLibContext); 1169 } 1170 else if ((PHNFCSTATUS(status) == PN544_IO_TIMEOUT_RESPONSE) || 1171 (PHNFCSTATUS(status) == NFCSTATUS_RF_TIMEOUT)) 1172 { 1173 // 0x89, 0x09 HCI response values from PN544 indicate timeout 1174 trans_status = NFCSTATUS_TARGET_LOST; 1175 } 1176 else 1177 { 1178 // PN544 did get some reply from tag, just not valid 1179 trans_status = NFCSTATUS_FAILED; 1180 } 1181 /*Update the state machine */ 1182 phLibNfc_UpdateCurState(status,gpphLibContext); 1183 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect; 1184 if(NFCSTATUS_PENDING != trans_status) 1185 { 1186 /* Tranceive over */ 1187 PHDBG_INFO("LibNfc:TXRX Callback-Update the Transceive responce"); 1188 if (NULL != pUpper_TagNtfCb) 1189 { 1190 if(trans_status == NFCSTATUS_SUCCESS) 1191 { 1192 gpphLibContext->LastTrancvSuccess = TRUE; 1193 pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx; 1194 trans_resp->buffer = response->buffer; 1195 trans_resp->length = response->length; 1196 /* Notify the upper layer */ 1197 PHDBG_INFO("LibNfc:Transceive Complete"); 1198 /* Notify the Transceive Completion to upper layer */ 1199 gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context, 1200 (phLibNfc_Handle)pRmtdev_info, 1201 trans_resp, 1202 trans_status); 1203 } 1204 else 1205 { 1206 gpphLibContext->LastTrancvSuccess = FALSE; 1207 pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx; 1208 trans_resp->length = 0; 1209 /* Notify the upper layer */ 1210 PHDBG_INFO("LibNfc:Transceive Complete"); 1211 /* Notify the Transceive Completion to upper layer */ 1212 gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context, 1213 (phLibNfc_Handle)pRmtdev_info, 1214 trans_resp, 1215 trans_status); 1216 } 1217 } 1218 } 1219 1220 } 1221 else 1222 { /*exception: wrong context pointer returned*/ 1223 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 1224 } 1225 1226 return; 1227 } 1228 /** 1229 * Interface to configure P2P configurations. 1230 */ 1231 NFCSTATUS 1232 phLibNfc_Mgt_SetP2P_ConfigParams(phLibNfc_sNfcIPCfg_t* pConfigInfo, 1233 pphLibNfc_RspCb_t pConfigRspCb, 1234 void* pContext 1235 ) 1236 { 1237 NFCSTATUS RetVal = NFCSTATUS_FAILED; 1238 /* LibNfc Initialized or not */ 1239 if((NULL == gpphLibContext)|| 1240 (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) 1241 { 1242 RetVal = NFCSTATUS_NOT_INITIALISED; 1243 }/* Check for valid parameters */ 1244 else if((NULL == pConfigInfo) || (NULL == pConfigRspCb) 1245 || (NULL == pContext)) 1246 { 1247 RetVal= NFCSTATUS_INVALID_PARAMETER; 1248 } 1249 else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) 1250 { 1251 RetVal = NFCSTATUS_SHUTDOWN; 1252 } 1253 else if(TRUE == gpphLibContext->status.GenCb_pending_status) 1254 { /*Previous callback is pending */ 1255 RetVal = NFCSTATUS_BUSY; 1256 } 1257 else 1258 { 1259 if(eLibNfcHalStatePresenceChk != 1260 gpphLibContext->LibNfcState.next_state) 1261 { 1262 phHal_uConfig_t uConfig; 1263 /* copy General bytes of Max length = 48 bytes */ 1264 (void)memcpy((void *)&(uConfig.nfcIPConfig.generalBytes), 1265 (void *)pConfigInfo->generalBytes, 1266 pConfigInfo->generalBytesLength); 1267 /* also copy the General Bytes length*/ 1268 uConfig.nfcIPConfig.generalBytesLength = pConfigInfo->generalBytesLength; 1269 1270 RetVal = phHal4Nfc_ConfigParameters( 1271 gpphLibContext->psHwReference, 1272 NFC_P2P_CONFIG, 1273 &uConfig, 1274 phLibNfc_Mgt_SetP2P_ConfigParams_Cb, 1275 (void *)gpphLibContext 1276 ); 1277 } 1278 else 1279 { 1280 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb= NULL; 1281 RetVal = NFCSTATUS_PENDING; 1282 } 1283 if(NFCSTATUS_PENDING == RetVal) 1284 { 1285 /* save the context and callback for later use */ 1286 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = pConfigRspCb; 1287 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = pContext; 1288 gpphLibContext->status.GenCb_pending_status=TRUE; 1289 /* Next state is configured */ 1290 gpphLibContext->LibNfcState.next_state =eLibNfcHalStateConfigReady; 1291 } 1292 else 1293 { 1294 RetVal = NFCSTATUS_FAILED; 1295 } 1296 } 1297 return RetVal; 1298 } 1299 /** 1300 * Response callback for P2P configurations. 1301 */ 1302 STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb(void *context, 1303 NFCSTATUS status) 1304 { 1305 pphLibNfc_RspCb_t pClientCb=NULL; 1306 void *pUpperLayerContext=NULL; 1307 /* Check for the context returned by below layer */ 1308 if((phLibNfc_LibContext_t *)context != gpphLibContext) 1309 { /*wrong context returned*/ 1310 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 1311 } 1312 else 1313 { 1314 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 1315 { /*shutdown called before completion of this api allow 1316 shutdown to happen */ 1317 phLibNfc_Pending_Shutdown(); 1318 status = NFCSTATUS_SHUTDOWN; 1319 } 1320 else 1321 { 1322 gpphLibContext->status.GenCb_pending_status = FALSE; 1323 if(NFCSTATUS_SUCCESS != status) 1324 { 1325 status = NFCSTATUS_FAILED; 1326 } 1327 else 1328 { 1329 status = NFCSTATUS_SUCCESS; 1330 } 1331 } 1332 /*update the current state */ 1333 phLibNfc_UpdateCurState(status,gpphLibContext); 1334 1335 pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb; 1336 pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx; 1337 1338 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = NULL; 1339 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = NULL; 1340 if (NULL != pClientCb) 1341 { 1342 /* Notify to upper layer status of configure operation */ 1343 pClientCb(pUpperLayerContext, status); 1344 } 1345 } 1346 return; 1347 } 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358