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