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_P2P.c 18 * \brief Hal4Nfc_P2P source. 19 * 20 * Project: NFC-FRI 1.1 21 * 22 * $Date: Mon May 31 11:43:43 2010 $ 23 * $Author: ing07385 $ 24 * $Revision: 1.56 $ 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 <phOsalNfc_Timer.h> 34#include <phHciNfc.h> 35#include <phNfcConfig.h> 36 37/* ------------------------------- Macros ------------------------------------*/ 38 39#ifdef _WIN32 40/*Timeout value for recv data timer for P2P.This timer is used for creating 41 Asynchronous behavior in the scenario where the data is received even before 42 the upper layer calls the phHal4Nfc_receive().*/ 43#define PH_HAL4NFC_RECV_CB_TIMEOUT 100U 44#else 45#define PH_HAL4NFC_RECV_CB_TIMEOUT 0x00U 46#endif/*#ifdef _WIN32*/ 47 48 49/* --------------------Structures and enumerations --------------------------*/ 50 51/*timer callback to send already buffered receive data to upper layer*/ 52static void phHal4Nfc_P2PRecvTimerCb(uint32_t P2PRecvTimerId, void *pContext); 53 54/* ---------------------- Function definitions ------------------------------*/ 55 56/* Transfer the user data to another NfcIP device from the host. 57 * pTransferCallback is called, when all steps in the transfer sequence are 58 * completed.*/ 59NFCSTATUS 60phHal4Nfc_Send( 61 phHal_sHwReference_t *psHwReference, 62 phHal4Nfc_TransactInfo_t *psTransferInfo, 63 phNfc_sData_t sTransferData, 64 pphHal4Nfc_SendCallback_t pSendCallback, 65 void *pContext 66 ) 67{ 68 NFCSTATUS RetStatus = NFCSTATUS_PENDING; 69 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 70 71 /*NULL checks*/ 72 if((NULL == psHwReference) 73 ||( NULL == pSendCallback ) 74 || (NULL == psTransferInfo) 75 ) 76 { 77 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 78 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); 79 } 80 /*Check initialised state*/ 81 else if((NULL == psHwReference->hal_context) 82 || (((phHal4Nfc_Hal4Ctxt_t *) 83 psHwReference->hal_context)->Hal4CurrentState 84 < eHal4StateOpenAndReady) 85 || (((phHal4Nfc_Hal4Ctxt_t *) 86 psHwReference->hal_context)->Hal4NextState 87 == eHal4StateClosed)) 88 { 89 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); 90 } 91 /*Only NfcIp1 Target can call this API*/ 92 else if(phHal_eNfcIP1_Initiator != psTransferInfo->remotePCDType) 93 { 94 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_DEVICE); 95 } 96 else 97 { 98 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 99 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 100 { 101 RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED); 102 } 103 /*Check Activated*/ 104 else if(NFC_EVT_ACTIVATED == Hal4Ctxt->sTgtConnectInfo.EmulationState) 105 { 106 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 107 /*Register upper layer callback*/ 108 Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = pSendCallback; 109 PHDBG_INFO("NfcIP1 Send"); 110 /*allocate buffer to store senddata received from upper layer*/ 111 if (NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) 112 { 113 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData = (phNfc_sData_t *) 114 phOsalNfc_GetMemory(sizeof(phNfc_sData_t)); 115 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) 116 { 117 (void)memset(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData, 0, 118 sizeof(phNfc_sData_t)); 119 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 120 = PH_OSALNFC_INVALID_TIMER_ID; 121 } 122 } 123 124 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer 125 = sTransferData.buffer; 126 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length 127 = sTransferData.length; 128 129 /* If data size is less than Peer's Max frame length, then no chaining is required */ 130 if(Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength >= sTransferData.length) 131 { 132 Hal4Ctxt->psTrcvCtxtInfo-> 133 XchangeInfo.params.nfc_info.more_info = FALSE; 134 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length 135 = (uint8_t)sTransferData.length; 136 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer 137 = sTransferData.buffer; 138 } 139 else/*set more_info to true,to indicate more data pending to be sent*/ 140 { 141 Hal4Ctxt->psTrcvCtxtInfo-> 142 XchangeInfo.params.nfc_info.more_info = TRUE; 143 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length 144 = Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength; 145 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer 146 = sTransferData.buffer; 147 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent 148 += Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength; 149 } 150 PHDBG_INFO("HAL4:Calling Hci_Send_data()"); 151 RetStatus = phHciNfc_Send_Data ( 152 Hal4Ctxt->psHciHandle, 153 psHwReference, 154 NULL, 155 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) 156 ); 157 /*check return status*/ 158 if (NFCSTATUS_PENDING == RetStatus) 159 { 160 /*Set P2P_Send_In_Progress to defer any disconnect call until 161 Send complete occurs*/ 162 Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE; 163 Hal4Ctxt->Hal4NextState = eHal4StateTransaction; 164 /*No of bytes remaining for next send*/ 165 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length 166 -= Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length; 167 } 168 } 169 else/*Deactivated*/ 170 { 171 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED); 172 } 173 } 174 return RetStatus; 175} 176 177 178/* Transfer the user data to the another NfcIP device from the host. 179 * pTransferCallback is called, when all steps in the transfer sequence are 180 * completed.*/ 181 182NFCSTATUS 183phHal4Nfc_Receive( 184 phHal_sHwReference_t *psHwReference, 185 phHal4Nfc_TransactInfo_t *psRecvInfo, 186 pphHal4Nfc_ReceiveCallback_t pReceiveCallback, 187 void *pContext 188 ) 189{ 190 NFCSTATUS RetStatus = NFCSTATUS_PENDING; 191 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; 192 /*NULL checks*/ 193 if((NULL == psHwReference) 194 ||( NULL == pReceiveCallback) 195 ||( NULL == psRecvInfo)) 196 { 197 phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); 198 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); 199 } 200 /*Check initialised state*/ 201 else if((NULL == psHwReference->hal_context) 202 || (((phHal4Nfc_Hal4Ctxt_t *) 203 psHwReference->hal_context)->Hal4CurrentState 204 < eHal4StateOpenAndReady) 205 || (((phHal4Nfc_Hal4Ctxt_t *) 206 psHwReference->hal_context)->Hal4NextState 207 == eHal4StateClosed)) 208 { 209 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); 210 } 211 else 212 { 213 Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; 214 if(NFC_EVT_ACTIVATED == Hal4Ctxt->sTgtConnectInfo.EmulationState) 215 { 216 /*Following condition gets satisfied only on target side,if receive 217 is not already called*/ 218 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 219 { 220 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t) 221 phOsalNfc_GetMemory((uint32_t) 222 (sizeof(phHal4Nfc_TrcvCtxtInfo_t))); 223 if(NULL != Hal4Ctxt->psTrcvCtxtInfo) 224 { 225 (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0, 226 sizeof(phHal4Nfc_TrcvCtxtInfo_t)); 227 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 228 = PH_OSALNFC_INVALID_TIMER_ID; 229 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus = NFCSTATUS_PENDING; 230 } 231 } 232 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 233 { 234 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 235 RetStatus= PHNFCSTVAL(CID_NFC_HAL , 236 NFCSTATUS_INSUFFICIENT_RESOURCES); 237 } 238 else /*Store callback & Return status pending*/ 239 { 240 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; 241 /*Register upper layer callback*/ 242 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; 243 Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = pReceiveCallback; 244 if(NFCSTATUS_PENDING != 245 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus) 246 { 247 /**Create a timer to send received data in the callback*/ 248 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 249 == PH_OSALNFC_INVALID_TIMER_ID) 250 { 251 PHDBG_INFO("HAL4: Transaction Timer Create for Receive"); 252 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 253 = phOsalNfc_Timer_Create(); 254 } 255 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 256 == PH_OSALNFC_INVALID_TIMER_ID) 257 { 258 RetStatus = PHNFCSTVAL(CID_NFC_HAL , 259 NFCSTATUS_INSUFFICIENT_RESOURCES); 260 } 261 else/*start the timer*/ 262 { 263 phOsalNfc_Timer_Start( 264 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId, 265 PH_HAL4NFC_RECV_CB_TIMEOUT, 266 phHal4Nfc_P2PRecvTimerCb, 267 NULL 268 ); 269 } 270 } 271 } 272 } 273 else/*deactivated*/ 274 { 275 RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED); 276 } 277 } 278 return RetStatus; 279} 280 281/*Timer callback for recv data timer for P2P.This timer is used for creating 282 Asynchronous behavior in the scenario where the data is received even before 283 the upper layer calls the phHal4Nfc_receive().*/ 284static void phHal4Nfc_P2PRecvTimerCb(uint32_t P2PRecvTimerId, void *pContext) 285{ 286 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)( 287 gpphHal4Nfc_Hwref->hal_context); 288 pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; 289 NFCSTATUS RecvDataBufferStatus = NFCSTATUS_PENDING; 290 PHNFC_UNUSED_VARIABLE(pContext); 291 292 phOsalNfc_Timer_Stop(P2PRecvTimerId); 293 phOsalNfc_Timer_Delete(P2PRecvTimerId); 294 if(NULL != Hal4Ctxt->psTrcvCtxtInfo) 295 { 296 RecvDataBufferStatus = Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus; 297 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus = NFCSTATUS_PENDING; 298 299 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 300 = PH_OSALNFC_INVALID_TIMER_ID; 301 /*Update state*/ 302 Hal4Ctxt->Hal4NextState = (eHal4StateTransaction 303 == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState); 304 /*Provide address of received data to upper layer data pointer*/ 305 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData 306 = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData); 307 /*Chk NULL and call recv callback*/ 308 if(Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb != NULL) 309 { 310 pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; 311 Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL; 312 (*pUpperRecvCb)( 313 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 314 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, 315 RecvDataBufferStatus 316 ); 317 } 318 } 319 return; 320} 321 322/**Send complete handler*/ 323void phHal4Nfc_SendCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo) 324{ 325 pphHal4Nfc_SendCallback_t pUpperSendCb = NULL; 326 pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL; 327 NFCSTATUS SendStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; 328 pphHal4Nfc_DiscntCallback_t pUpperDisconnectCb = NULL; 329 Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = FALSE; 330 /*Send status Success or Pending disconnect in HAl4*/ 331 if((SendStatus != NFCSTATUS_SUCCESS) 332 ||(NFC_INVALID_RELEASE_TYPE != Hal4Ctxt->sTgtConnectInfo.ReleaseType)) 333 { 334 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 335 /*Update Status*/ 336 SendStatus = (NFCSTATUS)(NFC_INVALID_RELEASE_TYPE != 337 Hal4Ctxt->sTgtConnectInfo.ReleaseType?NFCSTATUS_RELEASED:SendStatus); 338 /*Callback For Target Send*/ 339 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb) 340 { 341 pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb; 342 Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = NULL; 343 (*pUpperSendCb)( 344 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 345 SendStatus 346 ); 347 } 348 else/*Callback For Initiator Send*/ 349 { 350 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb) 351 { 352 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0; 353 pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; 354 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; 355 (*pUpperTrcvCb)( 356 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 357 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 358 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, 359 SendStatus 360 ); 361 } 362 } 363 /*Issue Pending disconnect from HAl4*/ 364 if(NFC_INVALID_RELEASE_TYPE != Hal4Ctxt->sTgtConnectInfo.ReleaseType) 365 { 366 SendStatus = phHal4Nfc_Disconnect_Execute(gpphHal4Nfc_Hwref); 367 if((NFCSTATUS_PENDING != SendStatus) && 368 (NULL != Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb)) 369 { 370 pUpperDisconnectCb = 371 Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb; 372 Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = NULL; 373 (*pUpperDisconnectCb)( 374 Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt, 375 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 376 SendStatus 377 );/*Notify disconnect failed to upper layer*/ 378 } 379 } 380 } 381 else 382 { 383 /*More info remaining in send buffer.continue with sending remaining 384 bytes*/ 385 if(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length 386 > Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength) 387 { 388 /*Set more info*/ 389 Hal4Ctxt->psTrcvCtxtInfo-> 390 XchangeInfo.params.nfc_info.more_info = TRUE; 391 /*copy to tx_buffer ,remaining bytes.NumberOfBytesSent is the 392 number of bytes already sent from current send buffer.*/ 393 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer 394 = (Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer 395 + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent); 396 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length 397 = Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength; 398 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent 399 += Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength; 400 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length 401 -= Hal4Ctxt->rem_dev_list[0]->RemoteDevInfo.NfcIP_Info.MaxFrameLength; 402 PHDBG_INFO("Hal4:Calling Hci_senddata() from sendcompletehandler1"); 403 SendStatus = phHciNfc_Send_Data ( 404 Hal4Ctxt->psHciHandle, 405 gpphHal4Nfc_Hwref, 406 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 407 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) 408 ); 409 if(NFCSTATUS_PENDING == SendStatus) 410 { 411 Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE; 412 } 413 } 414 /*Remaining bytes is less than PH_HAL4NFC_MAX_SEND_LEN*/ 415 else if(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length > 0) 416 { 417 Hal4Ctxt->psTrcvCtxtInfo-> 418 XchangeInfo.params.nfc_info.more_info = FALSE; 419 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length 420 = (uint8_t)Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length; 421 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer 422 = (Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer 423 + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent); 424 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent = 0; 425 /*No of bytes remaining for next send*/ 426 Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length = 0; 427 PHDBG_INFO("Hal4:Calling Hci_senddata() from sendcompletehandler2"); 428 SendStatus = phHciNfc_Send_Data ( 429 Hal4Ctxt->psHciHandle, 430 gpphHal4Nfc_Hwref, 431 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 432 &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) 433 ); 434 } 435 else/*No more Bytes left.Send complete*/ 436 { 437 Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent = 0; 438 /*Callback For Target Send*/ 439 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb) 440 { 441 pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb; 442 Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = NULL; 443 (*pUpperSendCb)( 444 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 445 SendStatus 446 ); 447 } 448 else 449 { 450 /**Start timer to keep track of transceive timeout*/ 451#ifdef TRANSACTION_TIMER 452 phOsalNfc_Timer_Start( 453 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId, 454 PH_HAL4NFC_TRANSCEIVE_TIMEOUT, 455 phHal4Nfc_TrcvTimeoutHandler 456 ); 457#endif /*TRANSACTION_TIMER*/ 458 } 459 } 460 } 461 return; 462} 463 464/**Receive complete handler*/ 465void phHal4Nfc_RecvCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo) 466{ 467 pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; 468 pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL; 469 NFCSTATUS RecvStatus = ((phNfc_sTransactionInfo_t *)pInfo)->status; 470 /*allocate TrcvContext if not already allocated.Required since 471 Receive complete can occur before any other send /receive calls.*/ 472 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 473 { 474 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t) 475 phOsalNfc_GetMemory((uint32_t) 476 (sizeof(phHal4Nfc_TrcvCtxtInfo_t))); 477 if(NULL != Hal4Ctxt->psTrcvCtxtInfo) 478 { 479 (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0, 480 sizeof(phHal4Nfc_TrcvCtxtInfo_t)); 481 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 482 = PH_OSALNFC_INVALID_TIMER_ID; 483 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus 484 = NFCSTATUS_PENDING; 485 } 486 } 487 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 488 { 489 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 490 RecvStatus = PHNFCSTVAL(CID_NFC_HAL , 491 NFCSTATUS_INSUFFICIENT_RESOURCES); 492 } 493 else 494 { 495 /*Allocate 4K buffer to copy the received data into*/ 496 if(NULL == Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) 497 { 498 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer 499 = (uint8_t *)phOsalNfc_GetMemory( 500 PH_HAL4NFC_MAX_RECEIVE_BUFFER 501 ); 502 if(NULL == Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) 503 { 504 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory, 505 0); 506 RecvStatus = NFCSTATUS_INSUFFICIENT_RESOURCES; 507 } 508 else/*memset*/ 509 { 510 (void)memset( 511 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer, 512 0, 513 PH_HAL4NFC_MAX_RECEIVE_BUFFER 514 ); 515 } 516 } 517 518 if(RecvStatus != NFCSTATUS_INSUFFICIENT_RESOURCES) 519 { 520 /*Copy the data*/ 521 (void)memcpy( 522 (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer 523 + Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength), 524 ((phNfc_sTransactionInfo_t *)pInfo)->buffer, 525 ((phNfc_sTransactionInfo_t *)pInfo)->length 526 ); 527 /*Update P2PRecvLength,this also acts as the offset to append more 528 received bytes*/ 529 Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength 530 += ((phNfc_sTransactionInfo_t *)pInfo)->length; 531 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length 532 = Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength; 533 } 534 535 if(RecvStatus != NFCSTATUS_MORE_INFORMATION) 536 { 537 Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength = 0; 538 Hal4Ctxt->Hal4NextState = (eHal4StateTransaction 539 == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState); 540 if(NFCSTATUS_PENDING == Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus) 541 { 542 /*Initiator case*/ 543 if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb) 544 { 545 RecvStatus =(NFCSTATUS_RF_TIMEOUT == RecvStatus? 546 NFCSTATUS_DESELECTED:RecvStatus); 547 pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; 548 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; 549 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData 550 = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData); 551 (*pUpperTrcvCb)( 552 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 553 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, 554 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, 555 RecvStatus 556 ); 557 } 558 /*P2P target*/ 559 else if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb) 560 { 561 pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; 562 Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL; 563 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData 564 = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData); 565 (*pUpperRecvCb)( 566 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 567 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, 568 RecvStatus 569 ); 570 } 571 else 572 { 573 /*Receive data buffer is complete with data & P2P receive has 574 not yet been called*/ 575 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus 576 = NFCSTATUS_SUCCESS; 577 } 578 } 579 } 580 } 581 return; 582} 583 584/*Activation complete handler*/ 585void phHal4Nfc_P2PActivateComplete( 586 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 587 void *pInfo 588 ) 589{ 590 phHal_sEventInfo_t *psEventInfo = (phHal_sEventInfo_t *)pInfo; 591 NFCSTATUS Status = NFCSTATUS_SUCCESS; 592 static phHal4Nfc_DiscoveryInfo_t sDiscoveryInfo; 593 /*Copy notification info to provide to upper layer*/ 594 phHal4Nfc_NotificationInfo_t uNotificationInfo = {&sDiscoveryInfo}; 595 Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_ACTIVATED; 596 /*if P2p notification is registered*/ 597 if( NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) 598 { 599 /*Allocate remote device Info for P2P target*/ 600 uNotificationInfo.psDiscoveryInfo->NumberOfDevices = 1; 601 if(NULL == Hal4Ctxt->rem_dev_list[0]) 602 { 603 Hal4Ctxt->rem_dev_list[0] 604 = (phHal_sRemoteDevInformation_t *) 605 phOsalNfc_GetMemory( 606 sizeof(phHal_sRemoteDevInformation_t) 607 ); 608 } 609 if(NULL == Hal4Ctxt->rem_dev_list[0]) 610 { 611 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 612 Status = PHNFCSTVAL(CID_NFC_HAL , 613 NFCSTATUS_INSUFFICIENT_RESOURCES); 614 } 615 else 616 { 617 (void)memset((void *)Hal4Ctxt->rem_dev_list[0], 618 0,sizeof(phHal_sRemoteDevInformation_t)); 619 /*Copy device info*/ 620 (void)memcpy(Hal4Ctxt->rem_dev_list[0], 621 psEventInfo->eventInfo.pRemoteDevInfo, 622 sizeof(phHal_sRemoteDevInformation_t) 623 ); 624 /*Allocate Trcv context info*/ 625 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 626 { 627 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t) 628 phOsalNfc_GetMemory((uint32_t) 629 (sizeof(phHal4Nfc_TrcvCtxtInfo_t))); 630 if(NULL != Hal4Ctxt->psTrcvCtxtInfo) 631 { 632 (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0, 633 sizeof(phHal4Nfc_TrcvCtxtInfo_t)); 634 Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus 635 = NFCSTATUS_PENDING; 636 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId 637 = PH_OSALNFC_INVALID_TIMER_ID; 638 } 639 } 640 if(NULL == Hal4Ctxt->psTrcvCtxtInfo) 641 { 642 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); 643 Status= PHNFCSTVAL(CID_NFC_HAL , 644 NFCSTATUS_INSUFFICIENT_RESOURCES); 645 } 646 else 647 { 648 /*Update state*/ 649 Hal4Ctxt->Hal4CurrentState = eHal4StateEmulation; 650 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 651 uNotificationInfo.psDiscoveryInfo->ppRemoteDevInfo 652 = Hal4Ctxt->rem_dev_list; 653 /*set session Opened ,this will keep track of whether the session 654 is alive.will be reset if a Event DEACTIVATED is received*/ 655 Hal4Ctxt->rem_dev_list[0]->SessionOpened = TRUE; 656 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)( 657 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt, 658 NFC_DISCOVERY_NOTIFICATION, 659 uNotificationInfo, 660 Status 661 ); 662 } 663 } 664 } 665 return; 666} 667 668/*Deactivation complete handler*/ 669void phHal4Nfc_HandleP2PDeActivate( 670 phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, 671 void *pInfo 672 ) 673{ 674 pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; 675 pphHal4Nfc_SendCallback_t pUpperSendCb = NULL; 676 phHal4Nfc_NotificationInfo_t uNotificationInfo; 677 uNotificationInfo.psEventInfo = (phHal_sEventInfo_t *)pInfo; 678 /*session is closed*/ 679 if(NULL != Hal4Ctxt->rem_dev_list[0]) 680 { 681 Hal4Ctxt->rem_dev_list[0]->SessionOpened = FALSE; 682 Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; 683 } 684 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; 685 /*Update state*/ 686 Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady; 687 Hal4Ctxt->Hal4NextState = eHal4StateInvalid; 688 Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_DEACTIVATED; 689 /*If Trcv ctxt info is allocated ,free it here*/ 690 if(NULL != Hal4Ctxt->psTrcvCtxtInfo) 691 { 692 if(PH_OSALNFC_INVALID_TIMER_ID != 693 Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId) 694 { 695 phOsalNfc_Timer_Stop(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId); 696 phOsalNfc_Timer_Delete(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId); 697 } 698 pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; 699 pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb; 700 /*Free Hal4 resources used by Target*/ 701 if (NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) 702 { 703 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo-> 704 sLowerRecvData.buffer); 705 } 706 if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 707 && (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData)) 708 { 709 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData); 710 } 711 phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo); 712 Hal4Ctxt->psTrcvCtxtInfo = NULL; 713 } 714 /*if recv callback is pending*/ 715 if(NULL != pUpperRecvCb) 716 { 717 (*pUpperRecvCb)( 718 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 719 NULL, 720 NFCSTATUS_DESELECTED 721 ); 722 } 723 /*if send callback is pending*/ 724 else if(NULL != pUpperSendCb) 725 { 726 (*pUpperSendCb)( 727 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, 728 NFCSTATUS_DESELECTED 729 ); 730 } 731 /*if pP2PNotification is registered*/ 732 else if(NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) 733 { 734 (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)( 735 Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt, 736 NFC_EVENT_NOTIFICATION, 737 uNotificationInfo, 738 NFCSTATUS_DESELECTED 739 ); 740 } 741 else/*Call Default event handler*/ 742 { 743 if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler) 744 { 745 Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler( 746 Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt, 747 NFC_EVENT_NOTIFICATION, 748 uNotificationInfo, 749 NFCSTATUS_DESELECTED 750 ); 751 } 752 } 753} 754