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