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 /*! 18 * \file phLibNfc_Target.c 19 20 * Project: NFC FRI 1.1 21 * 22 * $Date: Thu Oct 15 15:24:43 2009 $ 23 * $Author: ing07299 $ 24 * $Revision: 1.12 $ 25 * $Aliases: NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK944_SDK,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK949_SDK_INT,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK1003_SDK,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1008_SDK,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1007_SDK,NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $ 26 * 27 */ 28 29 /* 30 ************************* Header Files *************************************** 31 */ 32 33 #include <phLibNfcStatus.h> 34 #include <phLibNfc.h> 35 #include <phHal4Nfc.h> 36 #include <phOsalNfc.h> 37 #include <phLibNfc_Internal.h> 38 #include <phLibNfc_ndef_raw.h> 39 #include <phLibNfc_initiator.h> 40 #include <phLibNfc_discovery.h> 41 42 /* 43 *************************** Macro's **************************************** 44 */ 45 46 #ifndef STATIC_DISABLE 47 #define STATIC static 48 #else 49 //#undef STATIC 50 #define STATIC 51 #endif 52 /* 53 *************************** Global Variables ********************************** 54 */ 55 56 /* 57 *************************** Static Function Declaration *********************** 58 */ 59 60 /* Remote device receive callback */ 61 STATIC void phLibNfc_RemoteDev_Receive_Cb( 62 void *context, 63 phNfc_sData_t *rec_rsp_data, 64 NFCSTATUS status 65 ); 66 67 /* Remote device Send callback */ 68 STATIC void phLibNfc_RemoteDev_Send_Cb( 69 void *Context, 70 NFCSTATUS status 71 ); 72 73 /* 74 *************************** Function Definitions ****************************** 75 */ 76 77 /** 78 * Interface used to receive data from initiator at target side during P2P 79 * communication. 80 */ 81 NFCSTATUS phLibNfc_RemoteDev_Receive(phLibNfc_Handle hRemoteDevice, 82 pphLibNfc_Receive_RspCb_t pReceiveRspCb, 83 void *pContext 84 ) 85 { 86 NFCSTATUS RetVal = NFCSTATUS_FAILED; 87 /*Check Lib Nfc is initialized*/ 88 if((NULL == gpphLibContext)|| 89 (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) 90 { 91 RetVal = NFCSTATUS_NOT_INITIALISED; 92 }/*Check application has sent valid parameters*/ 93 else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease) 94 { 95 RetVal = NFCSTATUS_DESELECTED; 96 } 97 else if((NULL == pReceiveRspCb) 98 || (NULL == pContext) 99 || (0 == hRemoteDevice)) 100 { 101 RetVal= NFCSTATUS_INVALID_PARAMETER; 102 } 103 else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) 104 { 105 RetVal = NFCSTATUS_SHUTDOWN; 106 } 107 else if((TRUE == gpphLibContext->status.GenCb_pending_status) 108 ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb) 109 ||(phHal_eNfcIP1_Target== 110 ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType)) 111 { 112 /*Previous callback is pending or if initiator uses this api */ 113 RetVal = NFCSTATUS_REJECTED; 114 }/*check for Discovered initiator handle and handle sent by application */ 115 else if(gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle != hRemoteDevice) 116 { 117 RetVal= NFCSTATUS_INVALID_DEVICE; 118 } 119 #ifdef LLCP_TRANSACT_CHANGES 120 else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state) 121 && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state)) 122 { 123 RetVal = NFCSTATUS_BUSY; 124 } 125 #endif /* #ifdef LLCP_TRANSACT_CHANGES */ 126 else 127 { 128 if(eLibNfcHalStatePresenceChk == 129 gpphLibContext->LibNfcState.next_state) 130 { 131 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL; 132 RetVal = NFCSTATUS_PENDING; 133 } 134 else 135 { 136 /*Call below layer receive and register the callback with it*/ 137 PHDBG_INFO("LibNfc:P2P Receive In Progress"); 138 RetVal =phHal4Nfc_Receive( 139 gpphLibContext->psHwReference, 140 (phHal4Nfc_TransactInfo_t*)gpphLibContext->psTransInfo, 141 (pphLibNfc_Receive_RspCb_t) 142 phLibNfc_RemoteDev_Receive_Cb, 143 (void *)gpphLibContext 144 ); 145 } 146 if(NFCSTATUS_PENDING == RetVal) 147 { 148 /*Update the Next state as Transaction*/ 149 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb= pReceiveRspCb; 150 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = pContext; 151 gpphLibContext->status.GenCb_pending_status=TRUE; 152 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; 153 } 154 else 155 { 156 RetVal = NFCSTATUS_FAILED; 157 } 158 } 159 return RetVal; 160 } 161 /** 162 * Response callback for Remote Device Receive. 163 */ 164 STATIC void phLibNfc_RemoteDev_Receive_Cb( 165 void *context, 166 phNfc_sData_t *rec_rsp_data, 167 NFCSTATUS status 168 ) 169 { 170 pphLibNfc_Receive_RspCb_t pClientCb=NULL; 171 172 phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)context; 173 void *pUpperLayerContext=NULL; 174 175 /* Check for the context returned by below layer */ 176 if(pLibNfc_Ctxt != gpphLibContext) 177 { /*wrong context returned*/ 178 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 179 } 180 else 181 { 182 pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb; 183 pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx; 184 185 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL; 186 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = NULL; 187 gpphLibContext->status.GenCb_pending_status = FALSE; 188 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 189 { /*shutdown called before completion of P2P receive allow 190 shutdown to happen */ 191 phLibNfc_Pending_Shutdown(); 192 status = NFCSTATUS_SHUTDOWN; 193 } 194 else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) 195 { 196 status = NFCSTATUS_ABORTED; 197 } 198 else 199 { 200 if((NFCSTATUS_SUCCESS != status) && 201 (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) ) 202 { 203 /*During p2p receive operation initiator was removed 204 from RF field of target*/ 205 status = NFCSTATUS_DESELECTED; 206 } 207 else 208 { 209 status = NFCSTATUS_SUCCESS; 210 } 211 } 212 /* Update current state */ 213 phLibNfc_UpdateCurState(status,gpphLibContext); 214 215 if (NULL != pClientCb) 216 { 217 /*Notify to upper layer status and No. of bytes 218 actually received */ 219 pClientCb(pUpperLayerContext, rec_rsp_data, status); 220 } 221 } 222 return; 223 } 224 225 /** 226 * Interface used to send data from target to initiator during P2P communication 227 */ 228 NFCSTATUS 229 phLibNfc_RemoteDev_Send( 230 phLibNfc_Handle hRemoteDevice, 231 phNfc_sData_t * pTransferData, 232 pphLibNfc_RspCb_t pSendRspCb, 233 void *pContext 234 ) 235 { 236 NFCSTATUS RetVal = NFCSTATUS_FAILED; 237 /*Check Lib Nfc stack is initilized*/ 238 if((NULL == gpphLibContext)|| 239 (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) 240 { 241 RetVal = NFCSTATUS_NOT_INITIALISED; 242 } 243 else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease) 244 { 245 RetVal = NFCSTATUS_DESELECTED; 246 } 247 /*Check application has sent the valid parameters*/ 248 else if((NULL == pTransferData) 249 || (NULL == pSendRspCb) 250 || (NULL == pTransferData->buffer) 251 || (0 == pTransferData->length) 252 || (NULL == pContext) 253 || (0 == hRemoteDevice)) 254 { 255 RetVal= NFCSTATUS_INVALID_PARAMETER; 256 } 257 else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) 258 { 259 RetVal = NFCSTATUS_SHUTDOWN; 260 } 261 else if((TRUE == gpphLibContext->status.GenCb_pending_status) 262 ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb) 263 ||(phHal_eNfcIP1_Target== 264 ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType)) 265 { 266 /*Previous callback is pending or local device is Initiator 267 then don't allow */ 268 RetVal = NFCSTATUS_REJECTED; 269 }/*Check for Discovered initiator handle and handle sent by application */ 270 else if(gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle != hRemoteDevice) 271 { 272 RetVal= NFCSTATUS_INVALID_DEVICE; 273 } 274 else if((NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb)) 275 { 276 RetVal =NFCSTATUS_BUSY ; 277 } 278 #ifdef LLCP_TRANSACT_CHANGES 279 else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state) 280 && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state)) 281 { 282 RetVal= NFCSTATUS_BUSY; 283 } 284 #endif /* #ifdef LLCP_TRANSACT_CHANGES */ 285 else 286 { 287 if(eLibNfcHalStatePresenceChk == 288 gpphLibContext->LibNfcState.next_state) 289 { 290 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL; 291 RetVal = NFCSTATUS_PENDING; 292 } 293 else 294 { 295 if(gpphLibContext->psTransInfo!=NULL) 296 { 297 (void)memset(gpphLibContext->psTransInfo, 298 0, 299 sizeof(phLibNfc_sTransceiveInfo_t)); 300 301 gpphLibContext->psTransInfo->addr =UNKNOWN_BLOCK_ADDRESS; 302 /*pointer to send data */ 303 gpphLibContext->psTransInfo->sSendData.buffer = 304 pTransferData->buffer; 305 /*size of send data*/ 306 gpphLibContext->psTransInfo->sSendData.length = 307 pTransferData->length; 308 309 /* Copy remote device type */ 310 gpphLibContext->sNfcIp_Context.TransactInfoRole.remotePCDType = 311 ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType; 312 /*Call Hal4 Send API and register callback with it*/ 313 PHDBG_INFO("LibNfc:P2P send In Progress"); 314 RetVal= phHal4Nfc_Send( 315 gpphLibContext->psHwReference, 316 &(gpphLibContext->sNfcIp_Context.TransactInfoRole), 317 gpphLibContext->psTransInfo->sSendData, 318 (pphLibNfc_RspCb_t) 319 phLibNfc_RemoteDev_Send_Cb, 320 (void *)gpphLibContext 321 ); 322 } 323 } 324 if(NFCSTATUS_PENDING == RetVal) 325 { 326 /* Update next state to transaction */ 327 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb= pSendRspCb; 328 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = pContext; 329 gpphLibContext->status.GenCb_pending_status=TRUE; 330 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; 331 } 332 else 333 { 334 RetVal = NFCSTATUS_FAILED; 335 } 336 } 337 return RetVal; 338 } 339 340 /* 341 * Response callback for Remote Device Send. 342 */ 343 STATIC void phLibNfc_RemoteDev_Send_Cb( 344 void *Context, 345 NFCSTATUS status 346 ) 347 { 348 pphLibNfc_RspCb_t pClientCb=NULL; 349 phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context; 350 void *pUpperLayerContext=NULL; 351 352 /* Check for the context returned by below layer */ 353 if(pLibNfc_Ctxt != gpphLibContext) 354 { /*wrong context returned*/ 355 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 356 } 357 else 358 { 359 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 360 { /*shutdown called before completion p2p send allow 361 shutdown to happen */ 362 phLibNfc_Pending_Shutdown(); 363 status = NFCSTATUS_SHUTDOWN; 364 } 365 else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) 366 { 367 status = NFCSTATUS_ABORTED; 368 } 369 else 370 { 371 gpphLibContext->status.GenCb_pending_status = FALSE; 372 if((NFCSTATUS_SUCCESS != status) && 373 (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) ) 374 { 375 /*During p2p send operation initator was not present in RF 376 field of target*/ 377 status = NFCSTATUS_DESELECTED; 378 } 379 else 380 { 381 status = NFCSTATUS_SUCCESS; 382 } 383 } 384 /* Update current state */ 385 phLibNfc_UpdateCurState(status,gpphLibContext); 386 387 pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb; 388 pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx; 389 390 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL; 391 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = NULL; 392 if (NULL != pClientCb) 393 { 394 /* Notify to upper layer status and No. of bytes 395 actually written or send to initiator */ 396 pClientCb(pUpperLayerContext, status); 397 } 398 } 399 return; 400 } 401 402 403 404 405