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