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