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       ChkLlcpMac_Cb(pContext,status);
    108    }
    109 
    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       if (LlcpMac->SendPending)
    147       {
    148          /* Reset Flag */
    149          LlcpMac->SendPending = FALSE;
    150          phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED);
    151       }
    152 
    153       if (LlcpMac->RecvPending)
    154       {
    155          /* Reset Flag */
    156          LlcpMac->RecvPending = FALSE;
    157          phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED);
    158       }
    159 
    160       LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
    161                              LlcpMac->LinkState,
    162                              NULL,
    163                              LlcpMac->PeerRemoteDevType);
    164    }
    165 
    166    return status;
    167 }
    168 
    169 static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void       *pContext,
    170                                            NFCSTATUS   Status)
    171 {
    172    phFriNfc_LlcpMac_t            *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    173 
    174 #ifdef LLCP_CHANGES
    175    if(gpphLibContext->LibNfcState.next_state
    176                                == eLibNfcHalStateShutdown)
    177    {
    178       phLibNfc_Pending_Shutdown();
    179       Status = NFCSTATUS_SHUTDOWN;
    180    }
    181 #endif /* #ifdef LLCP_CHANGES */
    182 
    183    /* Reset Send and Receive Flag */
    184    LlcpMac->SendPending = FALSE;
    185    LlcpMac->RecvPending = FALSE;
    186 
    187    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
    188 
    189 }
    190 
    191 static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void       *pContext,
    192                                               NFCSTATUS   Status)
    193 {
    194    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    195 #ifdef LLCP_CHANGES
    196 
    197    phFriNfc_LlcpMac_Send_CB_t       pfSendCB;
    198    void                             *pSendContext;
    199 
    200 
    201    if(gpphLibContext->LibNfcState.next_state
    202                                == eLibNfcHalStateShutdown)
    203    {
    204       phLibNfc_Pending_Shutdown();
    205       Status = NFCSTATUS_SHUTDOWN;
    206    }
    207 
    208    if (NFCSTATUS_SHUTDOWN == Status)
    209    {
    210       /* Save context in local variables */
    211       pfSendCB = LlcpMac->MacSend_Cb;
    212       pSendContext = LlcpMac->MacSend_Context;
    213 
    214       /* Reset the pointer to the Send Callback */
    215       LlcpMac->MacSend_Cb = NULL;
    216       LlcpMac->MacSend_Context = NULL;
    217 
    218       /* Reset Send and Receive Flag */
    219       LlcpMac->SendPending = FALSE;
    220       LlcpMac->RecvPending = FALSE;
    221    }
    222 
    223 #endif /* #ifdef LLCP_CHANGES */
    224 
    225    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
    226 
    227 #ifdef LLCP_CHANGES
    228 
    229    if (NFCSTATUS_SHUTDOWN == Status)
    230    {
    231        if ((LlcpMac->SendPending) && (NULL != pfSendCB))
    232        {
    233            pfSendCB(pSendContext, Status);
    234       }
    235    }
    236    else
    237 
    238 #endif /* #ifdef LLCP_CHANGES */
    239    {
    240    /* Test if a send is pending */
    241    if(LlcpMac->SendPending)
    242    {
    243       Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context);
    244    }
    245 }
    246 }
    247 
    248 static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void       *pContext,
    249                                                  NFCSTATUS   Status)
    250 {
    251    phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
    252 
    253 #ifdef LLCP_CHANGES
    254    if(gpphLibContext->LibNfcState.next_state
    255                                == eLibNfcHalStateShutdown)
    256    {
    257       phLibNfc_Pending_Shutdown();
    258       Status = NFCSTATUS_SHUTDOWN;
    259    }
    260 #endif /* #ifdef LLCP_CHANGES */
    261 
    262    /* Reset Send and Receive Flag */
    263    LlcpMac->SendPending = FALSE;
    264    LlcpMac->RecvPending = FALSE;
    265 
    266    /* Call the callbacks */
    267    phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
    268    phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
    269 }
    270 
    271 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
    272                                              phNfc_sData_t                    *psData,
    273                                              phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
    274                                              void                             *pContext)
    275 {
    276    NFCSTATUS status = NFCSTATUS_SUCCESS;
    277 
    278    if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
    279    {
    280       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    281    }
    282    else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
    283    {
    284       /*Previous callback is pending */
    285       status = NFCSTATUS_REJECTED;
    286    }
    287    else
    288    {
    289       /* Save the LlcpMacSend_Cb */
    290       LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
    291       LlcpMac->MacSend_Context = pContext;
    292 
    293       switch(LlcpMac->PeerRemoteDevType)
    294       {
    295       case phFriNfc_LlcpMac_ePeerTypeInitiator:
    296          {
    297             if(LlcpMac->RecvPending)
    298             {
    299                /*set the completion routines for the LLCP Transceive function*/
    300                 LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
    301                 LlcpMac->MacCompletionInfo.Context = LlcpMac;
    302 
    303                 /* set the command type*/
    304                 LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
    305 
    306                 /* set the Additional Info*/
    307                 LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    308                 LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    309                 LlcpMac->SendPending = TRUE;
    310 
    311                 status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
    312                                                     &LlcpMac->MacCompletionInfo,
    313                                                     LlcpMac->psRemoteDevInfo,
    314                                                     LlcpMac->Cmd,
    315                                                     &LlcpMac->psDepAdditionalInfo,
    316                                                     psData->buffer,
    317                                                     (uint16_t)psData->length,
    318                                                     LlcpMac->psReceiveBuffer->buffer,
    319                                                     (uint16_t*)&LlcpMac->psReceiveBuffer->length);
    320             }
    321             else
    322             {
    323                LlcpMac->SendPending = TRUE;
    324                LlcpMac->psSendBuffer = psData;
    325                return status = NFCSTATUS_PENDING;
    326             }
    327          }break;
    328       case phFriNfc_LlcpMac_ePeerTypeTarget:
    329          {
    330             if(!LlcpMac->RecvPending)
    331             {
    332                LlcpMac->SendPending = TRUE;
    333                LlcpMac->psSendBuffer = psData;
    334                return status = NFCSTATUS_PENDING;
    335             }
    336             else
    337             {
    338                /*set the completion routines for the LLCP Send function*/
    339                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
    340                LlcpMac->MacCompletionInfo.Context = LlcpMac;
    341                status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
    342                                              &LlcpMac->MacCompletionInfo,
    343                                              LlcpMac->psRemoteDevInfo,
    344                                              psData->buffer,
    345                                              (uint16_t)psData->length);
    346             }
    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 static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t               *LlcpMac,
    358                                                 phNfc_sData_t                    *psData,
    359                                                 phFriNfc_LlcpMac_Reveive_CB_t    LlcpMacReceive_Cb,
    360                                                 void                             *pContext)
    361 {
    362    NFCSTATUS status = NFCSTATUS_SUCCESS;
    363    if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
    364    {
    365       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
    366    }
    367    else if(LlcpMac->MacReceive_Cb != NULL)
    368    {
    369       /*Previous callback is pending */
    370       status = NFCSTATUS_REJECTED;
    371    }
    372    else
    373    {
    374       /* Save the LlcpMacReceive_Cb */
    375       LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
    376       LlcpMac->MacReceive_Context = pContext;
    377 
    378       /* Save the pointer to the receive buffer */
    379       LlcpMac->psReceiveBuffer= psData;
    380 
    381       switch(LlcpMac->PeerRemoteDevType)
    382       {
    383       case phFriNfc_LlcpMac_ePeerTypeInitiator:
    384          {
    385             if(LlcpMac->SendPending)
    386             {
    387                /*set the completion routines for the LLCP Transceive function*/
    388                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
    389                LlcpMac->MacCompletionInfo.Context = LlcpMac;
    390                /* set the command type*/
    391                LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
    392                /* set the Additional Info*/
    393                LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
    394                LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
    395                LlcpMac->RecvPending = TRUE;
    396 
    397                status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
    398                                                    &LlcpMac->MacCompletionInfo,
    399                                                    LlcpMac->psRemoteDevInfo,
    400                                                    LlcpMac->Cmd,
    401                                                    &LlcpMac->psDepAdditionalInfo,
    402                                                    LlcpMac->psSendBuffer->buffer,
    403                                                    (uint16_t)LlcpMac->psSendBuffer->length,
    404                                                    psData->buffer,
    405                                                    (uint16_t*)&psData->length);
    406             }
    407             else
    408             {
    409                LlcpMac->RecvPending = TRUE;
    410                return status = NFCSTATUS_PENDING;
    411             }
    412          }break;
    413       case phFriNfc_LlcpMac_ePeerTypeTarget:
    414          {
    415              /*set the completion routines for the LLCP Receive function*/
    416             LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
    417             /* save the context of LlcpMacNfcip */
    418             LlcpMac->MacCompletionInfo.Context = LlcpMac;
    419             LlcpMac->RecvPending = TRUE;
    420 
    421             status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
    422                                              &LlcpMac->MacCompletionInfo,
    423                                              LlcpMac->psRemoteDevInfo,
    424                                              LlcpMac->psReceiveBuffer->buffer,
    425                                              (uint16_t*)&LlcpMac->psReceiveBuffer->length);
    426          }break;
    427       default:
    428          {
    429             status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
    430          }break;
    431       }
    432    }
    433    return status;
    434 }
    435 
    436 
    437 NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
    438 {
    439    NFCSTATUS status = NFCSTATUS_SUCCESS;
    440 
    441    if(NULL != LlcpMac)
    442    {
    443       LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
    444       LlcpMac->LlcpMacInterface.activate   = phFriNfc_LlcpMac_Nfcip_Activate;
    445       LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
    446       LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
    447       LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;
    448 
    449       return NFCSTATUS_SUCCESS;
    450    }
    451    else
    452    {
    453       return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
    454    }
    455 }
    456