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 
     36 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
     37                                              phNfc_sData_t                    *psData,
     38                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
     39                                              void                             *pContext);
     40 
     41 
     42 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t                   *LlcpMac,
     43                                             phFriNfc_LlcpMac_Chk_CB_t            ChkLlcpMac_Cb,
     44                                             void                                 *pContext)
     45 {
     46    NFCSTATUS status = NFCSTATUS_SUCCESS;
     47    uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D};
     48 
     49    if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext)
     50    {
     51       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
     52    }
     53    else
     54    {
     55       status = (NFCSTATUS)memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3);
     56       if(!status)
     57       {
     58          LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ;
     59          LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3);
     60          status = NFCSTATUS_SUCCESS;
     61       }
     62       else
     63       {
     64          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
     65       }
     66    }
     67 
     68    ChkLlcpMac_Cb(pContext,status);
     69    return status;
     70 }
     71 
     72 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t   *LlcpMac)
     73 {
     74    NFCSTATUS status  = NFCSTATUS_SUCCESS;
     75 
     76    if(LlcpMac == NULL)
     77    {
     78       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
     79    }
     80    else
     81    {
     82       LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated;
     83       LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
     84                              LlcpMac->LinkState,
     85                              &LlcpMac->sConfigParam,
     86                              LlcpMac->PeerRemoteDevType);
     87    }
     88 
     89    return status;
     90 }
     91 
     92 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t   *LlcpMac)
     93 {
     94    NFCSTATUS status  = NFCSTATUS_SUCCESS;
     95 
     96    if(NULL == LlcpMac)
     97    {
     98       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
     99    }
    100    else
    101    {
    102       /* Set the flag of LinkStatus to deactivate */
    103       LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated;
    104    }
    105 
    106    LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
    107                           LlcpMac->LinkState,
    108                           NULL,
    109                           LlcpMac->PeerRemoteDevType);
    110 
    111    return status;
    112 }
    113 
    114 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void       *pContext,
    115                                            NFCSTATUS   Status)
    116 {
    117    phFriNfc_LlcpMac_t            *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    118    phFriNfc_LlcpMac_Send_CB_t    pfSendCB;
    119    void                          *pSendContext;
    120 
    121    /* Reset Send and Receive Flag */
    122    LlcpMac->SendPending = FALSE;
    123    LlcpMac->RecvPending = FALSE;
    124 
    125    /* Save context in local variables */
    126    pfSendCB = LlcpMac->MacSend_Cb;
    127    pSendContext = LlcpMac->MacSend_Context;
    128 
    129    /* Reset the pointer to the Send Callback */
    130    LlcpMac->MacSend_Cb = NULL;
    131    LlcpMac->MacSend_Context = NULL;
    132 
    133    /* Call Send callback */
    134    pfSendCB(pSendContext, Status);
    135 }
    136 
    137 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void       *pContext,
    138                                               NFCSTATUS   Status)
    139 {
    140    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    141    phFriNfc_LlcpMac_Reveive_CB_t    pfReceiveCB;
    142    void                             *pReceiveContext;
    143 
    144    /* Save callback params */
    145    pfReceiveCB = LlcpMac->MacReceive_Cb;
    146    pReceiveContext = LlcpMac->MacReceive_Context;
    147 
    148    /* Reset the pointer to the Receive Callback and Context*/
    149    LlcpMac->MacReceive_Cb = NULL;
    150    LlcpMac->MacReceive_Context = NULL;
    151 
    152    /* Call the receive callback */
    153    pfReceiveCB(pReceiveContext, Status, LlcpMac->psReceiveBuffer);
    154 
    155    /* Test if a send is pending */
    156    if(LlcpMac->SendPending)
    157    {
    158       Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacReceive_Context);
    159    }
    160 }
    161 
    162 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void       *pContext,
    163                                                  NFCSTATUS   Status)
    164 {
    165    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    166    phFriNfc_LlcpMac_Reveive_CB_t    pfReceiveCB;
    167    void                             *pReceiveContext;
    168    phFriNfc_LlcpMac_Send_CB_t       pfSendCB;
    169    void                             *pSendContext;
    170 
    171    /* Save context in local variables */
    172    pfReceiveCB = LlcpMac->MacReceive_Cb;
    173    pReceiveContext = LlcpMac->MacReceive_Context;
    174    pfSendCB = LlcpMac->MacSend_Cb;
    175    pSendContext = LlcpMac->MacSend_Context;
    176 
    177    /* Reset the poniters to the Receive and Send Callback */
    178    LlcpMac->MacReceive_Cb = NULL;
    179    LlcpMac->MacReceive_Context = NULL;
    180    LlcpMac->MacSend_Cb = NULL;
    181    LlcpMac->MacSend_Context = NULL;
    182 
    183    /* Reset Send and Receive Flag */
    184    LlcpMac->SendPending = FALSE;
    185    LlcpMac->RecvPending = FALSE;
    186 
    187    /* Call the callbacks */
    188    pfSendCB(pSendContext, Status);
    189    pfReceiveCB(pReceiveContext, Status, LlcpMac->psReceiveBuffer);
    190 }
    191 
    192 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
    193                                              phNfc_sData_t                    *psData,
    194                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
    195                                              void                             *pContext)
    196 {
    197    NFCSTATUS status = NFCSTATUS_SUCCESS;
    198 
    199    if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
    200    {
    201       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    202    }
    203    else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
    204    {
    205       /*Previous callback is pending */
    206       status = NFCSTATUS_REJECTED;
    207    }
    208    else
    209    {
    210       /* Save the LlcpMacSend_Cb */
    211       LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
    212       LlcpMac->MacSend_Context = pContext;
    213 
    214       switch(LlcpMac->PeerRemoteDevType)
    215       {
    216       case phFriNfc_LlcpMac_ePeerTypeInitiator:
    217          {
    218             if(LlcpMac->RecvPending)
    219             {
    220                /*set the completion routines for the LLCP Transceive function*/
    221                 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
    222                 LlcpMac->MacCompletionInfo.Context = LlcpMac;
    223 
    224                 /* set the command type*/
    225                 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
    226 
    227                 /* set the Additional Info*/
    228                 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    229                 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    230                 LlcpMac->SendPending = TRUE;
    231 
    232                 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
    233                                                     &LlcpMac->MacCompletionInfo,
    234                                                     LlcpMac->psRemoteDevInfo,
    235                                                     LlcpMac->Cmd,
    236                                                     &LlcpMac->psDepAdditionalInfo,
    237                                                     psData->buffer,
    238                                                     (uint16_t)psData->length,
    239                                                     LlcpMac->psReceiveBuffer->buffer,
    240                                                     (uint16_t*)&LlcpMac->psReceiveBuffer->length);
    241             }
    242             else
    243             {
    244                LlcpMac->SendPending = TRUE;
    245                LlcpMac->psSendBuffer = psData;
    246                return status = NFCSTATUS_PENDING;
    247             }
    248          }break;
    249       case phFriNfc_LlcpMac_ePeerTypeTarget:
    250          {
    251             if(!LlcpMac->RecvPending)
    252             {
    253                LlcpMac->SendPending = TRUE;
    254                LlcpMac->psSendBuffer = psData;
    255                return status = NFCSTATUS_PENDING;
    256             }
    257             else
    258             {
    259                /*set the completion routines for the LLCP Send function*/
    260                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
    261                LlcpMac->MacCompletionInfo.Context = LlcpMac;
    262                status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
    263                                              &LlcpMac->MacCompletionInfo,
    264                                              LlcpMac->psRemoteDevInfo,
    265                                              psData->buffer,
    266                                              (uint16_t)psData->length);
    267             }
    268          }break;
    269       default:
    270          {
    271             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
    272          }break;
    273       }
    274    }
    275    return status;
    276 }
    277 
    278 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t               *LlcpMac,
    279                                                 phNfc_sData_t                    *psData,
    280                                                 phFriNfc_LlcpMac_Reveive_CB_t    LlcpMacReceive_Cb,
    281                                                 void                             *pContext)
    282 {
    283    NFCSTATUS status = NFCSTATUS_SUCCESS;
    284    if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
    285    {
    286       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    287    }
    288    else if(LlcpMac->MacReceive_Cb != NULL)
    289    {
    290       /*Previous callback is pending */
    291       status = NFCSTATUS_REJECTED;
    292    }
    293    else
    294    {
    295       /* Save the LlcpMacReceive_Cb */
    296       LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
    297       LlcpMac->MacReceive_Context = pContext;
    298 
    299       /* Save the pointer to the receive buffer */
    300       LlcpMac->psReceiveBuffer= psData;
    301 
    302       switch(LlcpMac->PeerRemoteDevType)
    303       {
    304       case phFriNfc_LlcpMac_ePeerTypeInitiator:
    305          {
    306             if(LlcpMac->SendPending)
    307             {
    308                /*set the completion routines for the LLCP Transceive function*/
    309                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
    310                LlcpMac->MacCompletionInfo.Context = LlcpMac;
    311                /* set the command type*/
    312                LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
    313                /* set the Additional Info*/
    314                LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    315                LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    316                LlcpMac->RecvPending = TRUE;
    317 
    318                status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
    319                                                    &LlcpMac->MacCompletionInfo,
    320                                                    LlcpMac->psRemoteDevInfo,
    321                                                    LlcpMac->Cmd,
    322                                                    &LlcpMac->psDepAdditionalInfo,
    323                                                    LlcpMac->psSendBuffer->buffer,
    324                                                    (uint16_t)LlcpMac->psSendBuffer->length,
    325                                                    psData->buffer,
    326                                                    (uint16_t*)&psData->length);
    327             }
    328             else
    329             {
    330                LlcpMac->RecvPending = TRUE;
    331                return status = NFCSTATUS_PENDING;
    332             }
    333          }break;
    334       case phFriNfc_LlcpMac_ePeerTypeTarget:
    335          {
    336              /*set the completion routines for the LLCP Receive function*/
    337             LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
    338             /* save the context of LlcpMacNfcip */
    339             LlcpMac->MacCompletionInfo.Context = LlcpMac;
    340             LlcpMac->RecvPending = TRUE;
    341 
    342             status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
    343                                              &LlcpMac->MacCompletionInfo,
    344                                              LlcpMac->psRemoteDevInfo,
    345                                              LlcpMac->psReceiveBuffer->buffer,
    346                                              (uint16_t*)&LlcpMac->psReceiveBuffer->length);
    347          }break;
    348       default:
    349          {
    350             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
    351          }break;
    352       }
    353    }
    354    return status;
    355 }
    356 
    357 
    358 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
    359 {
    360    NFCSTATUS status = NFCSTATUS_SUCCESS;
    361 
    362    if(NULL != LlcpMac)
    363    {
    364       LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
    365       LlcpMac->LlcpMacInterface.activate   = phFriNfc_LlcpMac_Nfcip_Activate;
    366       LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
    367       LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
    368       LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;
    369 
    370       return NFCSTATUS_SUCCESS;
    371    }
    372    else
    373    {
    374       return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
    375    }
    376 }
    377