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 /**
     19  * \file  phFriNfc_LlcpMacNfcip.c
     20  * \brief NFC LLCP MAC Mappings For Different RF Technologies.
     21  *
     22  * Project: NFC-FRI
     23  *
     24  */
     25 
     26 
     27 /*include files*/
     28 #include <phFriNfc_LlcpMac.h>
     29 #include <phLibNfcStatus.h>
     30 #include <phLibNfc.h>
     31 #include <phLibNfc_Internal.h>
     32 #include <stdio.h>
     33 #include <string.h>
     34 
     35 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
     36                                              phNfc_sData_t                    *psData,
     37                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
     38                                              void                             *pContext);
     39 
     40 
     41 static void phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(phFriNfc_LlcpMac_t  *LlcpMac,
     42                                                  NFCSTATUS           status)
     43 {
     44    phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB;
     45    void                          *pReceiveContext;
     46 
     47    if (LlcpMac->MacReceive_Cb != NULL)
     48    {
     49       /* Save callback params */
     50       pfReceiveCB = LlcpMac->MacReceive_Cb;
     51       pReceiveContext = LlcpMac->MacReceive_Context;
     52 
     53       /* Reset the pointer to the Receive Callback and Context*/
     54       LlcpMac->MacReceive_Cb = NULL;
     55       LlcpMac->MacReceive_Context = NULL;
     56 
     57       /* Call the receive callback */
     58       pfReceiveCB(pReceiveContext, status, LlcpMac->psReceiveBuffer);
     59    }
     60 }
     61 
     62 static void phFriNfc_LlcpMac_Nfcip_TriggerSendCb(phFriNfc_LlcpMac_t  *LlcpMac,
     63                                                  NFCSTATUS           status)
     64 {
     65    phFriNfc_LlcpMac_Send_CB_t pfSendCB;
     66    void                       *pSendContext;
     67 
     68    if (LlcpMac->MacSend_Cb != NULL)
     69    {
     70       /* Save context in local variables */
     71       pfSendCB     = LlcpMac->MacSend_Cb;
     72       pSendContext = LlcpMac->MacSend_Context;
     73 
     74       /* Reset the pointer to the Send Callback */
     75       LlcpMac->MacSend_Cb = NULL;
     76       LlcpMac->MacSend_Context = NULL;
     77 
     78       /* Call Send callback */
     79       pfSendCB(pSendContext, status);
     80    }
     81 }
     82 
     83 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t                   *LlcpMac,
     84                                             phFriNfc_LlcpMac_Chk_CB_t            ChkLlcpMac_Cb,
     85                                             void                                 *pContext)
     86 {
     87    NFCSTATUS status = NFCSTATUS_SUCCESS;
     88    uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D};
     89 
     90    if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext)
     91    {
     92       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
     93    }
     94    else
     95    {
     96       status = (NFCSTATUS)memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3);
     97       if(!status)
     98       {
     99          LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ;
    100          LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3);
    101          status = NFCSTATUS_SUCCESS;
    102       }
    103       else
    104       {
    105          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
    106       }
    107    }
    108 
    109    ChkLlcpMac_Cb(pContext,status);
    110    return status;
    111 }
    112 
    113 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t   *LlcpMac)
    114 {
    115    NFCSTATUS status  = NFCSTATUS_SUCCESS;
    116 
    117    if(LlcpMac == NULL)
    118    {
    119       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    120    }
    121    else
    122    {
    123       LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated;
    124       LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
    125                              LlcpMac->LinkState,
    126                              &LlcpMac->sConfigParam,
    127                              LlcpMac->PeerRemoteDevType);
    128    }
    129 
    130    return status;
    131 }
    132 
    133 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t   *LlcpMac)
    134 {
    135    NFCSTATUS status  = NFCSTATUS_SUCCESS;
    136 
    137    if(NULL == LlcpMac)
    138    {
    139       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    140    }
    141    else
    142    {
    143       /* Set the flag of LinkStatus to deactivate */
    144       LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated;
    145    }
    146 
    147    if (LlcpMac->SendPending)
    148    {
    149       /* Reset Flag */
    150       LlcpMac->SendPending = FALSE;
    151 
    152       phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED);
    153    }
    154 
    155    if (LlcpMac->RecvPending)
    156    {
    157       /* Reset Flag */
    158       LlcpMac->RecvPending = FALSE;
    159 
    160       phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED);
    161    }
    162 
    163    LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
    164                           LlcpMac->LinkState,
    165                           NULL,
    166                           LlcpMac->PeerRemoteDevType);
    167 
    168    return status;
    169 }
    170 
    171 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void       *pContext,
    172                                            NFCSTATUS   Status)
    173 {
    174    phFriNfc_LlcpMac_t            *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    175 
    176 #ifdef LLCP_CHANGES
    177    if(gpphLibContext->LibNfcState.next_state
    178                                == eLibNfcHalStateShutdown)
    179    {
    180       phLibNfc_Pending_Shutdown();
    181       Status = NFCSTATUS_SHUTDOWN;
    182    }
    183 #endif /* #ifdef LLCP_CHANGES */
    184 
    185    /* Reset Send and Receive Flag */
    186    LlcpMac->SendPending = FALSE;
    187    LlcpMac->RecvPending = FALSE;
    188 
    189    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
    190 
    191 }
    192 
    193 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void       *pContext,
    194                                               NFCSTATUS   Status)
    195 {
    196    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    197 #ifdef LLCP_CHANGES
    198 
    199    phFriNfc_LlcpMac_Send_CB_t       pfSendCB;
    200    void                             *pSendContext;
    201 
    202 
    203    if(gpphLibContext->LibNfcState.next_state
    204                                == eLibNfcHalStateShutdown)
    205    {
    206       phLibNfc_Pending_Shutdown();
    207       Status = NFCSTATUS_SHUTDOWN;
    208    }
    209 
    210    if (NFCSTATUS_SHUTDOWN == Status)
    211    {
    212       /* Save context in local variables */
    213       pfSendCB = LlcpMac->MacSend_Cb;
    214       pSendContext = LlcpMac->MacSend_Context;
    215 
    216       /* Reset the pointer to the Send Callback */
    217       LlcpMac->MacSend_Cb = NULL;
    218       LlcpMac->MacSend_Context = NULL;
    219 
    220       /* Reset Send and Receive Flag */
    221       LlcpMac->SendPending = FALSE;
    222       LlcpMac->RecvPending = FALSE;
    223    }
    224 
    225 #endif /* #ifdef LLCP_CHANGES */
    226 
    227    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
    228 
    229 #ifdef LLCP_CHANGES
    230 
    231    if (NFCSTATUS_SHUTDOWN == Status)
    232    {
    233        if ((LlcpMac->SendPending) && (NULL != pfSendCB))
    234        {
    235            pfSendCB(pSendContext, Status);
    236       }
    237    }
    238    else
    239 
    240 #endif /* #ifdef LLCP_CHANGES */
    241    {
    242    /* Test if a send is pending */
    243    if(LlcpMac->SendPending)
    244    {
    245       Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context);
    246    }
    247 }
    248 }
    249 
    250 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void       *pContext,
    251                                                  NFCSTATUS   Status)
    252 {
    253    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    254 
    255 #ifdef LLCP_CHANGES
    256    if(gpphLibContext->LibNfcState.next_state
    257                                == eLibNfcHalStateShutdown)
    258    {
    259       phLibNfc_Pending_Shutdown();
    260       Status = NFCSTATUS_SHUTDOWN;
    261    }
    262 #endif /* #ifdef LLCP_CHANGES */
    263 
    264    /* Reset Send and Receive Flag */
    265    LlcpMac->SendPending = FALSE;
    266    LlcpMac->RecvPending = FALSE;
    267 
    268    /* Call the callbacks */
    269    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
    270    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
    271 }
    272 
    273 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
    274                                              phNfc_sData_t                    *psData,
    275                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
    276                                              void                             *pContext)
    277 {
    278    NFCSTATUS status = NFCSTATUS_SUCCESS;
    279 
    280    if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
    281    {
    282       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    283    }
    284    else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
    285    {
    286       /*Previous callback is pending */
    287       status = NFCSTATUS_REJECTED;
    288    }
    289    else
    290    {
    291       /* Save the LlcpMacSend_Cb */
    292       LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
    293       LlcpMac->MacSend_Context = pContext;
    294 
    295       switch(LlcpMac->PeerRemoteDevType)
    296       {
    297       case phFriNfc_LlcpMac_ePeerTypeInitiator:
    298          {
    299             if(LlcpMac->RecvPending)
    300             {
    301                /*set the completion routines for the LLCP Transceive function*/
    302                 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
    303                 LlcpMac->MacCompletionInfo.Context = LlcpMac;
    304 
    305                 /* set the command type*/
    306                 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
    307 
    308                 /* set the Additional Info*/
    309                 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    310                 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    311                 LlcpMac->SendPending = TRUE;
    312 
    313                 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
    314                                                     &LlcpMac->MacCompletionInfo,
    315                                                     LlcpMac->psRemoteDevInfo,
    316                                                     LlcpMac->Cmd,
    317                                                     &LlcpMac->psDepAdditionalInfo,
    318                                                     psData->buffer,
    319                                                     (uint16_t)psData->length,
    320                                                     LlcpMac->psReceiveBuffer->buffer,
    321                                                     (uint16_t*)&LlcpMac->psReceiveBuffer->length);
    322             }
    323             else
    324             {
    325                LlcpMac->SendPending = TRUE;
    326                LlcpMac->psSendBuffer = psData;
    327                return status = NFCSTATUS_PENDING;
    328             }
    329          }break;
    330       case phFriNfc_LlcpMac_ePeerTypeTarget:
    331          {
    332             if(!LlcpMac->RecvPending)
    333             {
    334                LlcpMac->SendPending = TRUE;
    335                LlcpMac->psSendBuffer = psData;
    336                return status = NFCSTATUS_PENDING;
    337             }
    338             else
    339             {
    340                /*set the completion routines for the LLCP Send function*/
    341                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
    342                LlcpMac->MacCompletionInfo.Context = LlcpMac;
    343                status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
    344                                              &LlcpMac->MacCompletionInfo,
    345                                              LlcpMac->psRemoteDevInfo,
    346                                              psData->buffer,
    347                                              (uint16_t)psData->length);
    348             }
    349          }break;
    350       default:
    351          {
    352             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
    353          }break;
    354       }
    355    }
    356    return status;
    357 }
    358 
    359 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t               *LlcpMac,
    360                                                 phNfc_sData_t                    *psData,
    361                                                 phFriNfc_LlcpMac_Reveive_CB_t    LlcpMacReceive_Cb,
    362                                                 void                             *pContext)
    363 {
    364    NFCSTATUS status = NFCSTATUS_SUCCESS;
    365    if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
    366    {
    367       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    368    }
    369    else if(LlcpMac->MacReceive_Cb != NULL)
    370    {
    371       /*Previous callback is pending */
    372       status = NFCSTATUS_REJECTED;
    373    }
    374    else
    375    {
    376       /* Save the LlcpMacReceive_Cb */
    377       LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
    378       LlcpMac->MacReceive_Context = pContext;
    379 
    380       /* Save the pointer to the receive buffer */
    381       LlcpMac->psReceiveBuffer= psData;
    382 
    383       switch(LlcpMac->PeerRemoteDevType)
    384       {
    385       case phFriNfc_LlcpMac_ePeerTypeInitiator:
    386          {
    387             if(LlcpMac->SendPending)
    388             {
    389                /*set the completion routines for the LLCP Transceive function*/
    390                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
    391                LlcpMac->MacCompletionInfo.Context = LlcpMac;
    392                /* set the command type*/
    393                LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
    394                /* set the Additional Info*/
    395                LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    396                LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    397                LlcpMac->RecvPending = TRUE;
    398 
    399                status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
    400                                                    &LlcpMac->MacCompletionInfo,
    401                                                    LlcpMac->psRemoteDevInfo,
    402                                                    LlcpMac->Cmd,
    403                                                    &LlcpMac->psDepAdditionalInfo,
    404                                                    LlcpMac->psSendBuffer->buffer,
    405                                                    (uint16_t)LlcpMac->psSendBuffer->length,
    406                                                    psData->buffer,
    407                                                    (uint16_t*)&psData->length);
    408             }
    409             else
    410             {
    411                LlcpMac->RecvPending = TRUE;
    412                return status = NFCSTATUS_PENDING;
    413             }
    414          }break;
    415       case phFriNfc_LlcpMac_ePeerTypeTarget:
    416          {
    417              /*set the completion routines for the LLCP Receive function*/
    418             LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
    419             /* save the context of LlcpMacNfcip */
    420             LlcpMac->MacCompletionInfo.Context = LlcpMac;
    421             LlcpMac->RecvPending = TRUE;
    422 
    423             status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
    424                                              &LlcpMac->MacCompletionInfo,
    425                                              LlcpMac->psRemoteDevInfo,
    426                                              LlcpMac->psReceiveBuffer->buffer,
    427                                              (uint16_t*)&LlcpMac->psReceiveBuffer->length);
    428          }break;
    429       default:
    430          {
    431             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
    432          }break;
    433       }
    434    }
    435    return status;
    436 }
    437 
    438 
    439 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
    440 {
    441    NFCSTATUS status = NFCSTATUS_SUCCESS;
    442 
    443    if(NULL != LlcpMac)
    444    {
    445       LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
    446       LlcpMac->LlcpMacInterface.activate   = phFriNfc_LlcpMac_Nfcip_Activate;
    447       LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
    448       LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
    449       LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;
    450 
    451       return NFCSTATUS_SUCCESS;
    452    }
    453    else
    454    {
    455       return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
    456    }
    457 }
    458