Nick Pelly | 5d9927b | 2010-09-23 12:47:58 -0700 | [diff] [blame] | 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 | } |
daniel_Tomas | 6e28604 | 2010-11-19 09:51:28 +0100 | [diff] [blame] | 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 */ |
Nick Pelly | 5d9927b | 2010-09-23 12:47:58 -0700 | [diff] [blame] | 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 | } |
Nick Pelly | 5d9927b | 2010-09-23 12:47:58 -0700 | [diff] [blame] | 274 | else if((NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb)) |
| 275 | { |
| 276 | RetVal =NFCSTATUS_BUSY ; |
| 277 | } |
daniel_Tomas | 6e28604 | 2010-11-19 09:51:28 +0100 | [diff] [blame] | 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 */ |
Nick Pelly | 5d9927b | 2010-09-23 12:47:58 -0700 | [diff] [blame] | 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 | |