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_Reader.c 18 * \brief Hal4Nfc Reader source. 19 * 20 * Project: NFC-FRI 1.1 21 * 22 * $Date: Mon May 31 11:43:43 2010 $ 23 * $Author: ing07385 $ 24 * $Revision: 1.120 $ 25 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $ 26 * 27 */ 28 29 /* ---------------------------Include files ------------------------------------*/ 30 #include <phHal4Nfc.h> 31 #include <phHal4Nfc_Internal.h> 32 #include <phOsalNfc.h> 33 #include <phHciNfc.h> 34 #include <phOsalNfc_Timer.h> 35 #include <phNfcConfig.h> 36 37 38 /* ------------------------------- Macros ------------------------------------*/ 39 #define PH_HAL4NFC_CMD_LENGTH PHHAL_MAX_DATASIZE+12/**< Cmd length used 40 for Transceive*/ 41 #define PH_HAL4NFC_MAX_TRCV_LEN 4096 /**<Only a max of 1KB 42 can be sent at 43 a time*/ 44 #define PH_HAL4NFC_FLAG_0 0 45 46 #define PH_HAL4NFC_FLAG_1 1 47 48 #define PH_HAL4NFC_SEL_SECTOR1_BYTE0 0xC2 49 #define PH_HAL4NFC_SEL_SECTOR1_BYTE1 0xFF 50 51 #define PH_HAL4NFC_SEL_SECTOR2_BYTE0 0x02 52 #define PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED 0x00 53 54 55 /* --------------------Structures and enumerations --------------------------*/ 56 57 static void phHal4Nfc_Iso_3A_Transceive( 58 phHal_sTransceiveInfo_t *psTransceiveInfo, 59 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt 60 ); 61 62 static void phHal4Nfc_MifareTransceive( 63 phHal_sTransceiveInfo_t *psTransceiveInfo, 64 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 65 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt 66 ); 67 68 /*Allows to connect to a single, specific, already known Remote Device.*/ 69 NFCSTATUS phHal4Nfc_Connect( 70 phHal_sHwReference_t *psHwReference, 71 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 72 pphHal4Nfc_ConnectCallback_t pNotifyConnectCb, 73 void *pContext 74 ) 75 { 76 NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; 77 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 78 uint8_t RemoteDevCount = 0; 79 int32_t MemCmpRet = 0; 80 /*NULL chks*/ 81 if(NULL == psHwReference 82 || NULL == pNotifyConnectCb 83 || NULL == psRemoteDevInfo) 84 { 85 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 86 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); 87 } 88 /*Check initialised state*/ 89 else if((NULL == psHwReference->hal_context) 90 || (((phHal4Nfc_Hal4Ctxt_t *) 91 psHwReference->hal_context)->Hal4CurrentState 92 < eHal4StateOpenAndReady) 93 || (((phHal4Nfc_Hal4Ctxt_t *) 94 psHwReference->hal_context)->Hal4NextState 95 == eHal4StateClosed)) 96 { 97 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); 98 } 99 else if ((psRemoteDevInfo == 100 ((phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context)-> 101 sTgtConnectInfo.psConnectedDevice) 102 &&((phHal_eNfcIP1_Target == psRemoteDevInfo->RemDevType) 103 ||(phHal_eJewel_PICC == psRemoteDevInfo->RemDevType))) 104 { 105 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FEATURE_NOT_SUPPORTED); 106 } 107 else 108 { 109 /*Get Hal ctxt from hardware reference*/ 110 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 111 /*Register upper layer context*/ 112 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 113 /*Register upper layer callback*/ 114 Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = pNotifyConnectCb; 115 /*Allow Connect only if no other remote device is connected*/ 116 if((eHal4StateTargetDiscovered == Hal4Ctxt->Hal4CurrentState) 117 && (NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)) 118 { 119 RemoteDevCount = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 120 while(0 != RemoteDevCount) 121 { 122 RemoteDevCount--; 123 /*Check if handle provided by upper layer matches with any 124 remote device in the list*/ 125 if(psRemoteDevInfo 126 == (Hal4Ctxt->rem_dev_list[RemoteDevCount])) 127 { 128 129 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice 130 = Hal4Ctxt->rem_dev_list[RemoteDevCount]; 131 break; 132 } 133 }/*End of while*/ 134 135 if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 136 { 137 /*No matching device handle in list*/ 138 RetStatus = PHNFCSTVAL(CID_NFC_HAL , 139 NFCSTATUS_INVALID_REMOTE_DEVICE); 140 } 141 else 142 { 143 MemCmpRet = phOsalNfc_MemCompare( 144 (void *)&(psRemoteDevInfo->RemoteDevInfo), 145 (void *)&(Hal4Ctxt->rem_dev_list[Hal4Ctxt 146 ->psADDCtxtInfo->nbr_of_devices - 1]->RemoteDevInfo), 147 sizeof(phHal_uRemoteDevInfo_t)); 148 149 /*If device is already selected issue connect from here*/ 150 if(0 == MemCmpRet) 151 { 152 RetStatus = phHciNfc_Connect(Hal4Ctxt->psHciHandle, 153 (void *)psHwReference, 154 Hal4Ctxt->rem_dev_list[RemoteDevCount]); 155 if(NFCSTATUS_PENDING == RetStatus) 156 { 157 Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected; 158 } 159 160 } 161 else/*Select the matching device to connect to*/ 162 { 163 RetStatus = phHciNfc_Reactivate ( 164 Hal4Ctxt->psHciHandle, 165 (void *)psHwReference, 166 Hal4Ctxt->rem_dev_list[RemoteDevCount] 167 ); 168 Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate; 169 } 170 if(NFCSTATUS_PENDING != RetStatus) 171 { 172 /*Rollback state*/ 173 Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady; 174 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; 175 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = NULL; 176 Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; 177 } 178 } 179 } 180 /*Issue Reconnect*/ 181 else if(psRemoteDevInfo == 182 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 183 { 184 RetStatus = phHciNfc_Reactivate ( 185 Hal4Ctxt->psHciHandle, 186 (void *)psHwReference, 187 psRemoteDevInfo 188 ); 189 Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate; 190 } 191 #ifdef RECONNECT_SUPPORT 192 else if (psRemoteDevInfo != 193 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 194 { 195 phHal_sRemoteDevInformation_t *ps_store_connected_device = 196 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice; 197 198 RemoteDevCount = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; 199 200 while (0 != RemoteDevCount) 201 { 202 RemoteDevCount--; 203 /*Check if handle provided by upper layer matches with any 204 remote device in the list*/ 205 if(psRemoteDevInfo == (Hal4Ctxt->rem_dev_list[RemoteDevCount])) 206 { 207 break; 208 } 209 }/*End of while*/ 210 211 if (ps_store_connected_device == 212 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 213 { 214 RetStatus = phHciNfc_Reactivate (Hal4Ctxt->psHciHandle, 215 (void *)psHwReference, 216 psRemoteDevInfo); 217 218 if (NFCSTATUS_PENDING == RetStatus) 219 { 220 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = 221 Hal4Ctxt->rem_dev_list[RemoteDevCount]; 222 Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate; 223 } 224 } 225 } 226 #endif /* #ifdef RECONNECT_SUPPORT */ 227 else if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 228 { 229 /*Wrong state to issue connect*/ 230 RetStatus = PHNFCSTVAL(CID_NFC_HAL, 231 NFCSTATUS_INVALID_REMOTE_DEVICE); 232 } 233 else/*No Target or already connected to device*/ 234 { 235 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED); 236 } 237 238 } 239 return RetStatus; 240 } 241 242 /*For Ordering Transceive Info for ISO_3A type tags*/ 243 static void phHal4Nfc_Iso_3A_Transceive( 244 phHal_sTransceiveInfo_t *psTransceiveInfo, 245 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt 246 ) 247 { 248 uint16_t i; 249 uint16_t counter= 0; 250 /* Mifare UL, Keep MIFARE RAW command as it is */ 251 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type 252 = (uint8_t)psTransceiveInfo->cmd.MfCmd; 253 /* Set flags for Select Sector */ 254 if (psTransceiveInfo->sSendData.buffer[0] != phHal_eMifareWrite4) 255 { 256 if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_0) 257 { 258 /* First Select Sector command */ 259 if ((psTransceiveInfo->sSendData.buffer[1] == PH_HAL4NFC_SEL_SECTOR1_BYTE0) && 260 (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR1_BYTE1)) 261 { 262 Hal4Ctxt->SelectSectorFlag++; 263 PHDBG_INFO("Inside 3ATrancv,first cmd, SelectSectorFlag is 1"); 264 for (i = 1; i < psTransceiveInfo->sSendData.length; i++) 265 { 266 psTransceiveInfo->sSendData.buffer[i - 1] = 267 psTransceiveInfo->sSendData.buffer[i]; 268 } 269 270 psTransceiveInfo->sSendData.length--; 271 } 272 else 273 { 274 PHDBG_INFO("Inside 3ATrancv,first cmd,setting SelectSectorFlag 0"); 275 Hal4Ctxt->SelectSectorFlag = 0; 276 } 277 } 278 else if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_1) 279 { 280 if ((psTransceiveInfo->sSendData.buffer[1] < PH_HAL4NFC_SEL_SECTOR2_BYTE0) && 281 (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) && 282 (psTransceiveInfo->sSendData.buffer[3] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) && 283 (psTransceiveInfo->sSendData.buffer[4] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED)) 284 { 285 Hal4Ctxt->SelectSectorFlag++; 286 PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 2"); 287 for (i = 1; i < psTransceiveInfo->sSendData.length; i++) 288 { 289 psTransceiveInfo->sSendData.buffer[i - 1] = 290 psTransceiveInfo->sSendData.buffer[i]; 291 } 292 293 psTransceiveInfo->sSendData.length--; 294 } 295 else 296 { 297 PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 0"); 298 Hal4Ctxt->SelectSectorFlag = 0; 299 } 300 } 301 else 302 { 303 Hal4Ctxt->SelectSectorFlag = 0; 304 } 305 } 306 else 307 { 308 PHDBG_INFO("Inside 3ATrancv,Mifarewrite4"); 309 /* Convert MIFARE RAW to MIFARE CMD */ 310 if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw) 311 { 312 psTransceiveInfo->cmd.MfCmd = 313 (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0]; 314 315 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type = 316 (uint8_t)psTransceiveInfo->cmd.MfCmd; 317 318 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr = 319 psTransceiveInfo->addr = 320 psTransceiveInfo->sSendData.buffer[1]; 321 322 for (counter = 2; counter < psTransceiveInfo->sSendData.length; 323 counter++) 324 { 325 psTransceiveInfo->sSendData.buffer[counter - 2] = 326 psTransceiveInfo->sSendData.buffer[counter]; 327 } 328 PHDBG_INFO("Hal4:Inside 3A_Trcv() ,minus length by 4"); 329 psTransceiveInfo->sSendData.length = 330 psTransceiveInfo->sSendData.length - 4; 331 } 332 else 333 { 334 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type 335 = (uint8_t)psTransceiveInfo->cmd.MfCmd; 336 } 337 } 338 return; 339 } 340 341 /*For Ordering Transceive Info for Mifare tags*/ 342 static void phHal4Nfc_MifareTransceive( 343 phHal_sTransceiveInfo_t *psTransceiveInfo, 344 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 345 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt 346 ) 347 { 348 uint16_t counter; 349 if ( 350 #ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND 351 phHal_eMifareWrite4 != psTransceiveInfo->sSendData.buffer[0] 352 #else 353 1 354 #endif/*#ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND*/ 355 ) 356 357 { 358 /* Mifare UL, Keep MIFARE RAW command as it is */ 359 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type 360 = (uint8_t)psTransceiveInfo->cmd.MfCmd; 361 362 } 363 else 364 { 365 /* Convert MIFARE RAW to MIFARE CMD */ 366 if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw) 367 { 368 psTransceiveInfo->cmd.MfCmd = 369 (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0]; 370 371 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type = 372 (uint8_t)psTransceiveInfo->cmd.MfCmd; 373 374 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr = 375 psTransceiveInfo->addr = 376 psTransceiveInfo->sSendData.buffer[1]; 377 378 for (counter = 2; counter < psTransceiveInfo->sSendData.length; 379 counter++) 380 { 381 psTransceiveInfo->sSendData.buffer[counter - 2] = 382 psTransceiveInfo->sSendData.buffer[counter]; 383 } 384 PHDBG_INFO("Hal4:Inside MifareTrcv() ,minus length by 4"); 385 psTransceiveInfo->sSendData.length = 386 psTransceiveInfo->sSendData.length - 4; 387 388 } 389 else 390 { 391 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type 392 = (uint8_t)psTransceiveInfo->cmd.MfCmd; 393 } 394 } 395 return; 396 } 397 398 /* The phHal4Nfc_Transceive function allows the Initiator to send and receive 399 * data to and from the Remote Device selected by the caller.*/ 400 NFCSTATUS phHal4Nfc_Transceive( 401 phHal_sHwReference_t *psHwReference, 402 phHal_sTransceiveInfo_t *psTransceiveInfo, 403 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 404 pphHal4Nfc_TransceiveCallback_t pTrcvCallback, 405 void *pContext 406 ) 407 { 408 NFCSTATUS RetStatus = NFCSTATUS_PENDING; 409 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext; 410 411 /*NULL checks*/ 412 if((NULL == psHwReference) 413 ||( NULL == pTrcvCallback ) 414 || (NULL == psRemoteDevInfo) 415 || (NULL == psTransceiveInfo) 416 || (NULL == psTransceiveInfo->sRecvData.buffer) 417 || (NULL == psTransceiveInfo->sSendData.buffer) 418 ) 419 { 420 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 421 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); 422 } 423 #ifdef HAL_TRCV_LIMIT 424 else if(PH_HAL4NFC_MAX_TRCV_LEN < psTransceiveInfo->sSendData.length) 425 { 426 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_ALLOWED); 427 } 428 #endif/*#ifdef HAL_TRCV_LIMIT*/ 429 /*Check initialised state*/ 430 else if((NULL == psHwReference->hal_context) 431 || (((phHal4Nfc_Hal4Ctxt_t *) 432 psHwReference->hal_context)->Hal4CurrentState 433 < eHal4StateOpenAndReady) 434 || (((phHal4Nfc_Hal4Ctxt_t *) 435 psHwReference->hal_context)->Hal4NextState 436 == eHal4StateClosed)) 437 { 438 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); 439 } 440 else 441 { 442 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 443 gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)psHwReference; 444 if((eHal4StateTargetConnected != Hal4Ctxt->Hal4CurrentState) 445 ||(eHal4StateInvalid != Hal4Ctxt->Hal4NextState)) 446 { 447 /*Hal4 state Busy*/ 448 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY); 449 PHDBG_INFO("HAL4:Trcv Failed.Returning Busy"); 450 } 451 else if(psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 452 { 453 /*No such Target connected*/ 454 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE); 455 } 456 else 457 { 458 /*allocate Trcv context*/ 459 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 460 { 461 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t) 462 phOsalNfc_GetMemory((uint32_t)(sizeof(phHal4Nfc_TrcvCtxtInfo_t))); 463 if(NULL != Hal4Ctxt->psTrcvCtxtInfo) 464 { 465 (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0, 466 sizeof(phHal4Nfc_TrcvCtxtInfo_t)); 467 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus 468 = NFCSTATUS_PENDING; 469 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 470 = PH_OSALNFC_INVALID_TIMER_ID; 471 } 472 } 473 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 474 { 475 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 476 RetStatus= PHNFCSTVAL(CID_NFC_HAL , 477 NFCSTATUS_INSUFFICIENT_RESOURCES); 478 } 479 else 480 { 481 /*Process transceive based on Remote device type*/ 482 switch(Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType) 483 { 484 case phHal_eISO14443_3A_PICC: 485 phHal4Nfc_Iso_3A_Transceive( 486 psTransceiveInfo, 487 Hal4Ctxt 488 ); 489 break; 490 case phHal_eMifare_PICC: 491 PHDBG_INFO("Mifare Cmd received"); 492 phHal4Nfc_MifareTransceive( 493 psTransceiveInfo, 494 psRemoteDevInfo, 495 Hal4Ctxt 496 ); 497 498 #if 0 499 Hal4Ctxt->psTrcvCtxtInfo-> 500 XchangeInfo.params.tag_info.cmd_type 501 = (uint8_t)psTransceiveInfo->cmd.MfCmd; 502 #endif 503 break; 504 case phHal_eISO14443_A_PICC: 505 case phHal_eISO14443_B_PICC: 506 PHDBG_INFO("ISO14443 Cmd received"); 507 Hal4Ctxt->psTrcvCtxtInfo-> 508 XchangeInfo.params.tag_info.cmd_type 509 = (uint8_t)psTransceiveInfo->cmd.Iso144434Cmd; 510 break; 511 case phHal_eISO15693_PICC: 512 PHDBG_INFO("ISO15693 Cmd received"); 513 Hal4Ctxt->psTrcvCtxtInfo-> 514 XchangeInfo.params.tag_info.cmd_type 515 = (uint8_t)psTransceiveInfo->cmd.Iso15693Cmd; 516 break; 517 case phHal_eNfcIP1_Target: 518 { 519 PHDBG_INFO("NfcIP1 Transceive"); 520 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData 521 = &(psTransceiveInfo->sSendData); 522 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData = 523 &(psTransceiveInfo->sRecvData); 524 } 525 break; 526 case phHal_eFelica_PICC: 527 PHDBG_INFO("Felica Cmd received"); 528 Hal4Ctxt->psTrcvCtxtInfo-> 529 XchangeInfo.params.tag_info.cmd_type 530 = (uint8_t)psTransceiveInfo->cmd.FelCmd; 531 break; 532 case phHal_eJewel_PICC: 533 PHDBG_INFO("Jewel Cmd received"); 534 Hal4Ctxt->psTrcvCtxtInfo-> 535 XchangeInfo.params.tag_info.cmd_type 536 = (uint8_t)psTransceiveInfo->cmd.JewelCmd; 537 break; 538 case phHal_eISO14443_BPrime_PICC: 539 RetStatus = PHNFCSTVAL(CID_NFC_HAL , 540 NFCSTATUS_FEATURE_NOT_SUPPORTED); 541 break; 542 default: 543 PHDBG_WARNING("Invalid Device type received"); 544 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED); 545 break; 546 547 } 548 } 549 } 550 /*If status is anything other than NFCSTATUS_PENDING ,an error has 551 already occured, so dont process any further and return*/ 552 if(RetStatus == NFCSTATUS_PENDING) 553 { 554 if(phHal_eNfcIP1_Target == 555 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType) 556 { 557 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 558 /*Register upper layer callback*/ 559 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = pTrcvCallback; 560 if(PH_HAL4NFC_MAX_SEND_LEN 561 >= psTransceiveInfo->sSendData.length) 562 { 563 Hal4Ctxt->psTrcvCtxtInfo-> 564 XchangeInfo.params.nfc_info.more_info = FALSE; 565 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length 566 = (uint8_t)psTransceiveInfo->sSendData.length; 567 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer 568 = psTransceiveInfo->sSendData.buffer; 569 /*Number of bytes remaining for next send*/ 570 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length = 0; 571 } 572 else 573 { 574 Hal4Ctxt->psTrcvCtxtInfo-> 575 XchangeInfo.params.nfc_info.more_info = TRUE; 576 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer 577 = Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer; 578 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length 579 = PH_HAL4NFC_MAX_SEND_LEN; 580 #if 0 581 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer 582 += PH_HAL4NFC_MAX_SEND_LEN; 583 #else 584 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent 585 += PH_HAL4NFC_MAX_SEND_LEN; 586 #endif 587 /*Number of bytes remaining for next send*/ 588 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length 589 -= PH_HAL4NFC_MAX_SEND_LEN; 590 } 591 Hal4Ctxt->Hal4NextState = eHal4StateTransaction; 592 #ifdef TRANSACTION_TIMER 593 /**Create a timer to keep track of transceive timeout*/ 594 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 595 == PH_OSALNFC_INVALID_TIMER_ID) 596 { 597 PHDBG_INFO("HAL4: Transaction Timer Create for transceive"); 598 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 599 = phOsalNfc_Timer_Create(); 600 } 601 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 602 == PH_OSALNFC_INVALID_TIMER_ID) 603 { 604 RetStatus = PHNFCSTVAL(CID_NFC_HAL , 605 NFCSTATUS_INSUFFICIENT_RESOURCES); 606 } 607 else 608 #endif/*TRANSACTION_TIMER*/ 609 { 610 PHDBG_INFO("Hal4:Calling phHciNfc_Send_Data from Hal4_Transceive()"); 611 RetStatus = phHciNfc_Send_Data ( 612 Hal4Ctxt->psHciHandle, 613 psHwReference, 614 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 615 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) 616 ); 617 if(NFCSTATUS_PENDING == RetStatus) 618 { 619 Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE; 620 } 621 } 622 } 623 else if(psTransceiveInfo->sSendData.length > PH_HAL4NFC_CMD_LENGTH) 624 { 625 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_PARAMETER); 626 } 627 else if((psTransceiveInfo->sSendData.length == 0) 628 && (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length != 0)) 629 { 630 PHDBG_INFO("Hal4:Read remaining bytes"); 631 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData 632 = &(psTransceiveInfo->sRecvData); 633 /*Number of read bytes left is greater than bytes requested 634 by upper layer*/ 635 if(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length 636 < Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length) 637 { 638 (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo 639 ->psUpperRecvData->buffer, 640 (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer 641 + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset) 642 ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length); 643 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length -= 644 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length; 645 Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset 646 += Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length; 647 RetStatus = PHNFCSTVAL(CID_NFC_HAL , 648 NFCSTATUS_MORE_INFORMATION); 649 } 650 else/*Number of read bytes left is smaller.Copy all bytes 651 and free Hal's buffer*/ 652 { 653 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length 654 = Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length; 655 (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo 656 ->psUpperRecvData 657 ->buffer, 658 (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer 659 + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset) 660 ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length); 661 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo 662 ->sLowerRecvData.buffer); 663 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer = NULL; 664 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0; 665 Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset = 0; 666 RetStatus = NFCSTATUS_SUCCESS; 667 } 668 } 669 else/*No more bytes remaining in Hal.Read from device*/ 670 { 671 /*Register upper layer context*/ 672 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 673 /*Register upper layer callback*/ 674 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = pTrcvCallback; 675 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr 676 = psTransceiveInfo->addr; 677 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length 678 = (uint16_t)psTransceiveInfo->sSendData.length; 679 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer 680 = psTransceiveInfo->sSendData.buffer; 681 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData 682 = &(psTransceiveInfo->sRecvData); 683 #ifdef TRANSACTION_TIMER 684 /**Create a timer to keep track of transceive timeout*/ 685 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 686 == PH_OSALNFC_INVALID_TIMER_ID) 687 { 688 PHDBG_INFO("HAL4: Transaction Timer Create for transceive"); 689 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 690 = phOsalNfc_Timer_Create(); 691 } 692 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 693 == PH_OSALNFC_INVALID_TIMER_ID) 694 { 695 RetStatus = PHNFCSTVAL(CID_NFC_HAL , 696 NFCSTATUS_INSUFFICIENT_RESOURCES); 697 } 698 else 699 #endif /*TRANSACTION_TIMER*/ 700 { 701 PHDBG_INFO("Calling phHciNfc_Exchange_Data"); 702 RetStatus = phHciNfc_Exchange_Data( 703 Hal4Ctxt->psHciHandle, 704 psHwReference, 705 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 706 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) 707 ); 708 709 if(NFCSTATUS_PENDING == RetStatus) 710 { 711 Hal4Ctxt->Hal4NextState = eHal4StateTransaction; 712 #ifdef TRANSACTION_TIMER 713 /**Start timer to keep track of transceive timeout*/ 714 phOsalNfc_Timer_Start( 715 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId, 716 PH_HAL4NFC_TRANSCEIVE_TIMEOUT, 717 phHal4Nfc_TrcvTimeoutHandler 718 ); 719 #endif/*#ifdef TRANSACTION_TIMER*/ 720 } 721 else 722 { 723 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 724 } 725 } 726 } 727 } 728 } 729 return RetStatus; 730 } 731 732 #ifdef TRANSACTION_TIMER 733 /**Handle transceive timeout*/ 734 void phHal4Nfc_TrcvTimeoutHandler(uint32_t TrcvTimerId) 735 { 736 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = gpphHal4Nfc_Hwref->hal_context; 737 pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; 738 pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL; 739 phOsalNfc_Timer_Stop(TrcvTimerId); 740 phOsalNfc_Timer_Delete(TrcvTimerId); 741 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId = PH_OSALNFC_INVALID_TIMER_ID; 742 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 743 /*For a P2P target*/ 744 if(Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb != NULL) 745 { 746 pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; 747 Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL; 748 (*pUpperRecvCb)( 749 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 750 NULL, 751 NFCSTATUS_RF_TIMEOUT 752 ); 753 } 754 else 755 { 756 /*For a P2P Initiator and tags*/ 757 if(Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb != NULL) 758 { 759 pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; 760 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; 761 (*pUpperTrcvCb)( 762 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 763 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 764 NULL, 765 NFCSTATUS_RF_TIMEOUT 766 ); 767 } 768 } 769 } 770 #endif /*TRANSACTION_TIMER*/ 771 772 773 /**The function allows to disconnect from a specific Remote Device.*/ 774 NFCSTATUS phHal4Nfc_Disconnect( 775 phHal_sHwReference_t *psHwReference, 776 phHal_sRemoteDevInformation_t *psRemoteDevInfo, 777 phHal_eReleaseType_t ReleaseType, 778 pphHal4Nfc_DiscntCallback_t pDscntCallback, 779 void *pContext 780 ) 781 { 782 NFCSTATUS RetStatus = NFCSTATUS_PENDING; 783 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 784 PHDBG_INFO("Hal4:Inside Hal4 disconnect"); 785 /*NULL checks*/ 786 if(NULL == psHwReference || NULL == pDscntCallback 787 || NULL == psRemoteDevInfo) 788 { 789 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 790 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); 791 } 792 /*Check Initialised state*/ 793 else if((NULL == psHwReference->hal_context) 794 || (((phHal4Nfc_Hal4Ctxt_t *) 795 psHwReference->hal_context)->Hal4CurrentState 796 < eHal4StateOpenAndReady) 797 || (((phHal4Nfc_Hal4Ctxt_t *) 798 psHwReference->hal_context)->Hal4NextState 799 == eHal4StateClosed)) 800 { 801 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); 802 } 803 else if(((phHal4Nfc_Hal4Ctxt_t *) 804 psHwReference->hal_context)->Hal4CurrentState 805 != eHal4StateTargetConnected) 806 { 807 PHDBG_INFO("Hal4:Current sate is not connect.Release returning failed"); 808 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_FAILED); 809 } 810 else 811 { 812 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 813 if((Hal4Ctxt->sTgtConnectInfo.psConnectedDevice == NULL) 814 || (psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)) 815 { 816 PHDBG_INFO("Hal4:disconnect returning INVALID_REMOTE_DEVICE"); 817 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE); 818 } 819 else 820 { 821 /*Register upper layer context*/ 822 Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt = pContext; 823 /*Register upper layer callback*/ 824 Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = pDscntCallback; 825 /*Register Release Type*/ 826 Hal4Ctxt->sTgtConnectInfo.ReleaseType = ReleaseType; 827 if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState) 828 &&((phHal_eNfcIP1_Target != psRemoteDevInfo->RemDevType) 829 ||((NFC_DISCOVERY_CONTINUE != ReleaseType) 830 &&(NFC_DISCOVERY_RESTART != ReleaseType)))) 831 { 832 Hal4Ctxt->sTgtConnectInfo.ReleaseType 833 = NFC_INVALID_RELEASE_TYPE; 834 PHDBG_INFO("Hal4:disconnect returning NFCSTATUS_NOT_ALLOWED"); 835 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_ALLOWED); 836 } 837 else if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState) 838 &&(NULL != Hal4Ctxt->psTrcvCtxtInfo) 839 &&(TRUE == Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress)) 840 { 841 /*store the hardware reference for executing disconnect later*/ 842 gpphHal4Nfc_Hwref = psHwReference; 843 PHDBG_INFO("Hal4:disconnect deferred"); 844 } 845 else/*execute disconnect*/ 846 { 847 RetStatus = phHal4Nfc_Disconnect_Execute(psHwReference); 848 } 849 } 850 } 851 return RetStatus; 852 } 853 854 /**Execute Hal4 Disconnect*/ 855 NFCSTATUS phHal4Nfc_Disconnect_Execute( 856 phHal_sHwReference_t *psHwReference 857 ) 858 { 859 NFCSTATUS RetStatus = NFCSTATUS_PENDING; 860 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = 861 (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 862 phHal_eSmartMX_Mode_t SmxMode = eSmartMx_Default; 863 PHDBG_INFO("Hal4:Inside Hal4 disconnect execute"); 864 switch(Hal4Ctxt->sTgtConnectInfo.ReleaseType) 865 { 866 /*Switch mode to Default*/ 867 case NFC_SMARTMX_RELEASE: 868 SmxMode = eSmartMx_Default; 869 RetStatus = phHciNfc_Switch_SmxMode ( 870 Hal4Ctxt->psHciHandle, 871 psHwReference, 872 SmxMode, 873 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg) 874 ); 875 break; 876 /*Disconnect and continue polling wheel*/ 877 case NFC_DISCOVERY_CONTINUE: 878 { 879 RetStatus = phHciNfc_Disconnect ( 880 Hal4Ctxt->psHciHandle, 881 psHwReference, 882 FALSE 883 ); 884 if(NFCSTATUS_PENDING != RetStatus) 885 { 886 PHDBG_INFO("Hal4:Hci disconnect failed.Restarting discovery"); 887 RetStatus = phHciNfc_Restart_Discovery ( 888 (void *)Hal4Ctxt->psHciHandle, 889 (void *)gpphHal4Nfc_Hwref, 890 FALSE 891 ); 892 if(NFCSTATUS_PENDING != RetStatus) 893 { 894 PHDBG_INFO("Hal4:Hci Restart discovery also failed"); 895 } 896 } 897 break; 898 } 899 /*Disconnect and restart polling wheel*/ 900 case NFC_DISCOVERY_RESTART: 901 RetStatus = phHciNfc_Disconnect ( 902 Hal4Ctxt->psHciHandle, 903 psHwReference, 904 TRUE 905 ); 906 break; 907 default: 908 RetStatus = PHNFCSTVAL(CID_NFC_HAL, 909 NFCSTATUS_FEATURE_NOT_SUPPORTED); 910 break; 911 } 912 Hal4Ctxt->sTgtConnectInfo.ReleaseType = NFC_INVALID_RELEASE_TYPE; 913 /*Update or rollback next state*/ 914 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus? 915 eHal4StateOpenAndReady:Hal4Ctxt->Hal4NextState); 916 return RetStatus; 917 } 918 919 /*The function allows to check for presence in vicinity of connected remote 920 device.*/ 921 NFCSTATUS phHal4Nfc_PresenceCheck( 922 phHal_sHwReference_t *psHwReference, 923 pphHal4Nfc_GenCallback_t pPresenceChkCb, 924 void *context 925 ) 926 { 927 NFCSTATUS RetStatus = NFCSTATUS_FAILED; 928 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 929 /*NULL checks*/ 930 if((NULL == pPresenceChkCb) || (NULL == psHwReference)) 931 { 932 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_PARAMETER); 933 } 934 /*Check Initialised state*/ 935 else if((NULL == psHwReference->hal_context) 936 || (((phHal4Nfc_Hal4Ctxt_t *) 937 psHwReference->hal_context)->Hal4CurrentState 938 < eHal4StateOpenAndReady) 939 || (((phHal4Nfc_Hal4Ctxt_t *) 940 psHwReference->hal_context)->Hal4NextState 941 == eHal4StateClosed)) 942 { 943 PHDBG_INFO("HAL4:Context not Open"); 944 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_INITIALISED); 945 } 946 /*check connected state and session alive*/ 947 else if((((phHal4Nfc_Hal4Ctxt_t *) 948 psHwReference->hal_context)->Hal4CurrentState 949 < eHal4StateTargetConnected)|| 950 (NULL == ((phHal4Nfc_Hal4Ctxt_t *) 951 psHwReference->hal_context)->sTgtConnectInfo.psConnectedDevice)|| 952 (FALSE == ((phHal4Nfc_Hal4Ctxt_t *) 953 psHwReference->hal_context)->sTgtConnectInfo. 954 psConnectedDevice->SessionOpened)) 955 { 956 PHDBG_INFO("HAL4:No target connected"); 957 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_RELEASED); 958 } 959 else 960 { 961 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 962 /*allow only one Presence chk command at any point in time*/ 963 if (eHal4StatePresenceCheck != Hal4Ctxt->Hal4NextState) 964 { 965 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = context; 966 Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb = pPresenceChkCb; 967 RetStatus = phHciNfc_Presence_Check(Hal4Ctxt->psHciHandle, 968 psHwReference 969 ); 970 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus? 971 eHal4StatePresenceCheck:Hal4Ctxt->Hal4NextState); 972 } 973 else/*Ongoing presence chk*/ 974 { 975 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY); 976 } 977 } 978 return RetStatus; 979 } 980 981 void phHal4Nfc_PresenceChkComplete( 982 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 983 void *pInfo 984 ) 985 { 986 NFCSTATUS RetStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; 987 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 988 /*Notify to upper layer*/ 989 if(NULL != Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb) 990 { 991 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened 992 =(uint8_t)(NFCSTATUS_SUCCESS == RetStatus?TRUE:FALSE); 993 (*Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb)( 994 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 995 RetStatus 996 ); 997 } 998 return; 999 } 1000 1001 /*Callback for reactivate target and to select appropriate target incase 1002 of multiple targets*/ 1003 void phHal4Nfc_ReactivationComplete( 1004 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 1005 void *pInfo 1006 ) 1007 { 1008 NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status; 1009 /*A NFCSTATUS_SUCCESS status returned here means that the correct device 1010 to connect to has now been selected.So issue connect from here to complete 1011 activation*/ 1012 if(NFCSTATUS_SUCCESS == Status) 1013 { 1014 Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected; 1015 Status = phHciNfc_Connect( 1016 Hal4Ctxt->psHciHandle, 1017 gpphHal4Nfc_Hwref, 1018 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice 1019 ); 1020 Status = (NFCSTATUS_PENDING == Status)? 1021 NFCSTATUS_PENDING:NFCSTATUS_FAILED; 1022 } 1023 else/*Device unavailable, return error in connect Callback*/ 1024 { 1025 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 1026 if(NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb) 1027 { 1028 (*Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)( 1029 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 1030 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 1031 Status 1032 ); 1033 } 1034 } 1035 return; 1036 } 1037 1038 1039 void phHal4Nfc_ConnectComplete( 1040 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 1041 void *pInfo 1042 ) 1043 { 1044 NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; 1045 pphHal4Nfc_ConnectCallback_t pUpperConnectCb 1046 = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb; 1047 /*Flag to decide whether or not upper layer callback has to be called*/ 1048 uint8_t CallConnectCb = TRUE; 1049 /*Remote device Connect successful*/ 1050 if((NFCSTATUS_SUCCESS == ConnectStatus) 1051 ||(eHal4StateTargetConnected == Hal4Ctxt->Hal4CurrentState)) 1052 { 1053 PHDBG_INFO("Hal4:Connect status Success"); 1054 Hal4Ctxt->Hal4CurrentState = eHal4StateTargetConnected; 1055 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 1056 /* Open the Session */ 1057 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened = 1058 (uint8_t)(NFCSTATUS_SUCCESS == ConnectStatus?TRUE:FALSE); 1059 Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; 1060 1061 } 1062 else/*Remote device Connect failed*/ 1063 { 1064 Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady; 1065 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened = FALSE; 1066 /*For a NfcIp1 target and case where it is not a internal reconnect 1067 from Hal4 ,notify callback to upper layer*/ 1068 if((phHal_eNfcIP1_Target 1069 == Hal4Ctxt->rem_dev_list[0]->RemDevType) 1070 || (NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)) 1071 { 1072 Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; 1073 } 1074 else/*do not notify callback*/ 1075 { 1076 CallConnectCb = FALSE; 1077 } 1078 /*Free the remote device list*/ 1079 do 1080 { 1081 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices--; 1082 if(NULL != Hal4Ctxt->rem_dev_list[ 1083 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) 1084 { 1085 phOsalNfc_FreeMemory((void *) 1086 (Hal4Ctxt->rem_dev_list[ 1087 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])); 1088 Hal4Ctxt->rem_dev_list[ 1089 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; 1090 } 1091 }while(0 < Hal4Ctxt->psADDCtxtInfo->nbr_of_devices); 1092 1093 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; 1094 } 1095 if(TRUE == CallConnectCb) 1096 { 1097 PHDBG_INFO("Hal4:Calling Connect callback"); 1098 /*Notify to the upper layer*/ 1099 (*pUpperConnectCb)( 1100 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 1101 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 1102 ConnectStatus 1103 ); 1104 } 1105 else 1106 { 1107 PHDBG_INFO("Hal4:Connect failed ,Restarting discovery"); 1108 /*Restart the Discovery wheel*/ 1109 ConnectStatus = phHciNfc_Restart_Discovery ( 1110 (void *)Hal4Ctxt->psHciHandle, 1111 (void *)gpphHal4Nfc_Hwref, 1112 FALSE 1113 ); 1114 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus? 1115 eHal4StateConfiguring:eHal4StateInvalid); 1116 } 1117 return; 1118 } 1119 1120 1121 1122 1123 void phHal4Nfc_DisconnectComplete( 1124 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 1125 void *pInfo 1126 ) 1127 { 1128 NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; 1129 phHal_sRemoteDevInformation_t *psConnectedDevice = NULL; 1130 pphHal4Nfc_DiscntCallback_t pUpperDisconnectCb = NULL; 1131 pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL; 1132 PHDBG_INFO("Hal4:Inside Hal4 disconnect callback"); 1133 if(NULL == Hal4Ctxt) 1134 { 1135 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 1136 } 1137 else if(NFCSTATUS_SUCCESS != ConnectStatus)/*Restart the Discovery wheel*/ 1138 { 1139 ConnectStatus = phHciNfc_Restart_Discovery ( 1140 (void *)Hal4Ctxt->psHciHandle, 1141 (void *)gpphHal4Nfc_Hwref, 1142 FALSE 1143 ); 1144 Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus? 1145 eHal4StateConfiguring:eHal4StateInvalid); 1146 } 1147 else/*Remote device Disconnect successful*/ 1148 { 1149 psConnectedDevice = Hal4Ctxt->sTgtConnectInfo.psConnectedDevice; 1150 pUpperDisconnectCb = Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb; 1151 /*Deallocate psTrcvCtxtInfo*/ 1152 if(NULL != Hal4Ctxt->psTrcvCtxtInfo) 1153 { 1154 if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 1155 { 1156 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) 1157 { 1158 phOsalNfc_FreeMemory( 1159 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData); 1160 } 1161 } 1162 else 1163 { 1164 if(phHal_eNfcIP1_Target 1165 == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType) 1166 { 1167 pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; 1168 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0; 1169 pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; 1170 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; 1171 } 1172 } 1173 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) 1174 { 1175 phOsalNfc_FreeMemory( 1176 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer); 1177 } 1178 1179 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo); 1180 Hal4Ctxt->psTrcvCtxtInfo = NULL; 1181 } 1182 /*Free the remote device list*/ 1183 do 1184 { 1185 if(NULL != Hal4Ctxt->rem_dev_list[Hal4Ctxt-> 1186 psADDCtxtInfo->nbr_of_devices-1]) 1187 { 1188 phOsalNfc_FreeMemory((void *) 1189 (Hal4Ctxt->rem_dev_list[Hal4Ctxt-> 1190 psADDCtxtInfo->nbr_of_devices-1])); 1191 Hal4Ctxt->rem_dev_list[Hal4Ctxt-> 1192 psADDCtxtInfo->nbr_of_devices-1] = NULL; 1193 } 1194 }while(--(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices)); 1195 1196 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; 1197 /*Disconnect successful.Go to Ready state*/ 1198 Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState; 1199 Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = NULL; 1200 Hal4Ctxt->Hal4NextState = ( 1201 eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState? 1202 eHal4StateInvalid:Hal4Ctxt->Hal4NextState); 1203 /*Issue any pending Trcv callback*/ 1204 if(NULL != pUpperTrcvCb) 1205 { 1206 (*pUpperTrcvCb)( 1207 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 1208 psConnectedDevice, 1209 NULL, 1210 NFCSTATUS_FAILED 1211 ); 1212 } 1213 /*Notify upper layer*/ 1214 if(NULL != pUpperDisconnectCb) 1215 { 1216 PHDBG_INFO("Hal4:Calling Upper layer disconnect callback"); 1217 (*pUpperDisconnectCb)( 1218 Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt, 1219 psConnectedDevice, 1220 ConnectStatus 1221 ); 1222 } 1223 } 1224 return; 1225 } 1226 1227 1228 /*Transceive complete handler function*/ 1229 void phHal4Nfc_TransceiveComplete( 1230 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 1231 void *pInfo 1232 ) 1233 { 1234 /*Copy status code*/ 1235 NFCSTATUS TrcvStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; 1236 /*Update next state*/ 1237 Hal4Ctxt->Hal4NextState = (eHal4StateTransaction 1238 == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState); 1239 /*Reset SelectSectorFlag for Mifare*/ 1240 if (Hal4Ctxt->SelectSectorFlag == 2) 1241 { 1242 TrcvStatus = NFCSTATUS_SUCCESS; 1243 PHDBG_INFO("Inside Hal4TrcvComplete SelectSectorFlag is 2"); 1244 Hal4Ctxt->SelectSectorFlag = 0; 1245 } 1246 1247 if(NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData) 1248 { 1249 /*if recv buffer is Null*/ 1250 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 1251 TrcvStatus = NFCSTATUS_FAILED; 1252 } 1253 else if(TrcvStatus == NFCSTATUS_SUCCESS) 1254 { 1255 /*Check if recvdata buffer given by upper layer is big enough to 1256 receive all response bytes.If it is not big enough ,copy number 1257 of bytes requested by upper layer to the buffer.Remaining 1258 bytes are retained in Hal4 and upper layer has to issue another 1259 transceive call to read the same.*/ 1260 if(((phNfc_sTransactionInfo_t *)pInfo) 1261 ->length > Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length ) 1262 { 1263 TrcvStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_MORE_INFORMATION); 1264 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length 1265 = ((phNfc_sTransactionInfo_t *)pInfo)->length 1266 - Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length; 1267 1268 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer 1269 = (uint8_t *)phOsalNfc_GetMemory( 1270 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length 1271 ); 1272 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) 1273 { 1274 (void)memcpy( 1275 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer, 1276 (((phNfc_sTransactionInfo_t *)pInfo)->buffer 1277 + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData 1278 ->length) 1279 ,Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length 1280 ); 1281 } 1282 else 1283 { 1284 TrcvStatus = PHNFCSTVAL(CID_NFC_HAL, 1285 NFCSTATUS_INSUFFICIENT_RESOURCES); 1286 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 1287 } 1288 1289 } 1290 else/*Buffer provided by upper layer is big enough to hold all read 1291 bytes*/ 1292 { 1293 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length 1294 = ((phNfc_sTransactionInfo_t *)pInfo)->length; 1295 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0; 1296 } 1297 (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->buffer, 1298 ((phNfc_sTransactionInfo_t *)pInfo)->buffer, 1299 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length 1300 ); 1301 1302 } 1303 else/*Error scenario.Set received bytes length to zero*/ 1304 { 1305 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0; 1306 } 1307 (void)memset((void *)&(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params), 1308 0, 1309 sizeof(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params) 1310 ); 1311 Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset = 0; 1312 /*Issue transceive callback*/ 1313 (*Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb)( 1314 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 1315 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 1316 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, 1317 TrcvStatus 1318 ); 1319 return; 1320 } 1321