Home | History | Annotate | Download | only in src
      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