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 else 120 { 121 if(eLibNfcHalStatePresenceChk == 122 gpphLibContext->LibNfcState.next_state) 123 { 124 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL; 125 RetVal = NFCSTATUS_PENDING; 126 } 127 else 128 { 129 /*Call below layer receive and register the callback with it*/ 130 PHDBG_INFO("LibNfc:P2P Receive In Progress"); 131 RetVal =phHal4Nfc_Receive( 132 gpphLibContext->psHwReference, 133 (phHal4Nfc_TransactInfo_t*)gpphLibContext->psTransInfo, 134 (pphLibNfc_Receive_RspCb_t) 135 phLibNfc_RemoteDev_Receive_Cb, 136 (void *)gpphLibContext 137 ); 138 } 139 if(NFCSTATUS_PENDING == RetVal) 140 { 141 /*Update the Next state as Transaction*/ 142 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb= pReceiveRspCb; 143 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = pContext; 144 gpphLibContext->status.GenCb_pending_status=TRUE; 145 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; 146 } 147 else 148 { 149 RetVal = NFCSTATUS_FAILED; 150 } 151 } 152 return RetVal; 153 } 154 /** 155 * Response callback for Remote Device Receive. 156 */ 157 STATIC void phLibNfc_RemoteDev_Receive_Cb( 158 void *context, 159 phNfc_sData_t *rec_rsp_data, 160 NFCSTATUS status 161 ) 162 { 163 pphLibNfc_Receive_RspCb_t pClientCb=NULL; 164 165 phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)context; 166 void *pUpperLayerContext=NULL; 167 168 /* Check for the context returned by below layer */ 169 if(pLibNfc_Ctxt != gpphLibContext) 170 { /*wrong context returned*/ 171 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 172 } 173 else 174 { 175 pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb; 176 pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx; 177 178 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL; 179 gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = NULL; 180 gpphLibContext->status.GenCb_pending_status = FALSE; 181 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 182 { /*shutdown called before completion of P2P receive allow 183 shutdown to happen */ 184 phLibNfc_Pending_Shutdown(); 185 status = NFCSTATUS_SHUTDOWN; 186 } 187 else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) 188 { 189 status = NFCSTATUS_ABORTED; 190 } 191 else 192 { 193 if((NFCSTATUS_SUCCESS != status) && 194 (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) ) 195 { 196 /*During p2p receive operation initiator was removed 197 from RF field of target*/ 198 status = NFCSTATUS_DESELECTED; 199 } 200 else 201 { 202 status = NFCSTATUS_SUCCESS; 203 } 204 } 205 /* Update current state */ 206 phLibNfc_UpdateCurState(status,gpphLibContext); 207 208 if (NULL != pClientCb) 209 { 210 /*Notify to upper layer status and No. of bytes 211 actually received */ 212 pClientCb(pUpperLayerContext, rec_rsp_data, status); 213 } 214 } 215 return; 216 } 217 218 /** 219 * Interface used to send data from target to initiator during P2P communication 220 */ 221 NFCSTATUS 222 phLibNfc_RemoteDev_Send( 223 phLibNfc_Handle hRemoteDevice, 224 phNfc_sData_t * pTransferData, 225 pphLibNfc_RspCb_t pSendRspCb, 226 void *pContext 227 ) 228 { 229 NFCSTATUS RetVal = NFCSTATUS_FAILED; 230 /*Check Lib Nfc stack is initilized*/ 231 if((NULL == gpphLibContext)|| 232 (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) 233 { 234 RetVal = NFCSTATUS_NOT_INITIALISED; 235 } 236 else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease) 237 { 238 RetVal = NFCSTATUS_DESELECTED; 239 } 240 /*Check application has sent the valid parameters*/ 241 else if((NULL == pTransferData) 242 || (NULL == pSendRspCb) 243 || (NULL == pTransferData->buffer) 244 || (0 == pTransferData->length) 245 || (NULL == pContext) 246 || (0 == hRemoteDevice)) 247 { 248 RetVal= NFCSTATUS_INVALID_PARAMETER; 249 } 250 else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) 251 { 252 RetVal = NFCSTATUS_SHUTDOWN; 253 } 254 else if((TRUE == gpphLibContext->status.GenCb_pending_status) 255 ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb) 256 ||(phHal_eNfcIP1_Target== 257 ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType)) 258 { 259 /*Previous callback is pending or local device is Initiator 260 then don't allow */ 261 RetVal = NFCSTATUS_REJECTED; 262 }/*Check for Discovered initiator handle and handle sent by application */ 263 else if(gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle != hRemoteDevice) 264 { 265 RetVal= NFCSTATUS_INVALID_DEVICE; 266 } 267 268 else if((NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb)) 269 { 270 RetVal =NFCSTATUS_BUSY ; 271 } 272 else 273 { 274 if(eLibNfcHalStatePresenceChk == 275 gpphLibContext->LibNfcState.next_state) 276 { 277 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL; 278 RetVal = NFCSTATUS_PENDING; 279 } 280 else 281 { 282 if(gpphLibContext->psTransInfo!=NULL) 283 { 284 (void)memset(gpphLibContext->psTransInfo, 285 0, 286 sizeof(phLibNfc_sTransceiveInfo_t)); 287 288 gpphLibContext->psTransInfo->addr =UNKNOWN_BLOCK_ADDRESS; 289 /*pointer to send data */ 290 gpphLibContext->psTransInfo->sSendData.buffer = 291 pTransferData->buffer; 292 /*size of send data*/ 293 gpphLibContext->psTransInfo->sSendData.length = 294 pTransferData->length; 295 296 /* Copy remote device type */ 297 gpphLibContext->sNfcIp_Context.TransactInfoRole.remotePCDType = 298 ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType; 299 /*Call Hal4 Send API and register callback with it*/ 300 PHDBG_INFO("LibNfc:P2P send In Progress"); 301 RetVal= phHal4Nfc_Send( 302 gpphLibContext->psHwReference, 303 &(gpphLibContext->sNfcIp_Context.TransactInfoRole), 304 gpphLibContext->psTransInfo->sSendData, 305 (pphLibNfc_RspCb_t) 306 phLibNfc_RemoteDev_Send_Cb, 307 (void *)gpphLibContext 308 ); 309 } 310 } 311 if(NFCSTATUS_PENDING == RetVal) 312 { 313 /* Update next state to transaction */ 314 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb= pSendRspCb; 315 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = pContext; 316 gpphLibContext->status.GenCb_pending_status=TRUE; 317 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; 318 } 319 else 320 { 321 RetVal = NFCSTATUS_FAILED; 322 } 323 } 324 return RetVal; 325 } 326 327 /* 328 * Response callback for Remote Device Send. 329 */ 330 STATIC void phLibNfc_RemoteDev_Send_Cb( 331 void *Context, 332 NFCSTATUS status 333 ) 334 { 335 pphLibNfc_RspCb_t pClientCb=NULL; 336 phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context; 337 void *pUpperLayerContext=NULL; 338 339 /* Check for the context returned by below layer */ 340 if(pLibNfc_Ctxt != gpphLibContext) 341 { /*wrong context returned*/ 342 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); 343 } 344 else 345 { 346 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) 347 { /*shutdown called before completion p2p send allow 348 shutdown to happen */ 349 phLibNfc_Pending_Shutdown(); 350 status = NFCSTATUS_SHUTDOWN; 351 } 352 else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) 353 { 354 status = NFCSTATUS_ABORTED; 355 } 356 else 357 { 358 gpphLibContext->status.GenCb_pending_status = FALSE; 359 if((NFCSTATUS_SUCCESS != status) && 360 (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) ) 361 { 362 /*During p2p send operation initator was not present in RF 363 field of target*/ 364 status = NFCSTATUS_DESELECTED; 365 } 366 else 367 { 368 status = NFCSTATUS_SUCCESS; 369 } 370 } 371 /* Update current state */ 372 phLibNfc_UpdateCurState(status,gpphLibContext); 373 374 pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb; 375 pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx; 376 377 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL; 378 gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = NULL; 379 if (NULL != pClientCb) 380 { 381 /* Notify to upper layer status and No. of bytes 382 actually written or send to initiator */ 383 pClientCb(pUpperLayerContext, status); 384 } 385 } 386 return; 387 } 388 389 390 391 392