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  phFriNfc_OvrHal.c
     19  * \brief Overlapped HAL
     20  *
     21  * Project: NFC-FRI
     22  * Creator: Gerald Kersch
     23  *
     24  * $Date: Wed May  5 10:47:27 2010 $
     25  * Changed by: $Author: ing02260 $
     26  * $Revision: 1.37 $
     27  * $Aliases: NFC_FRI1.1_WK1017_R34_3,NFC_FRI1.1_WK1023_R35_1 $
     28  *
     29  */
     30 
     31 #include <phFriNfc_OvrHal.h>
     32 #include <phOsalNfc.h>
     33 #include <phFriNfc_NdefMap.h>
     34 #include <phFriNfc_SmtCrdFmt.h>
     35 
     36 
     37 #ifdef PHFRINFC_OVRHAL_MOCKUP  /* */
     38 //#include <phLibNfc_Gen.h>
     39 #endif /* PHFRINFC_OVRHAL_MOCKUP */
     40 /*
     41 *
     42 
     43 */
     44 #define MAX_MIF_PACKET_LEN                      0x0FU
     45 #define MIFARE_PLUS_UID_INDEX_TO_COPY           0x03U
     46 #define MIFARE_PLUS_UID_LENGTH                  0x07U
     47 #define MIFARE_CLASSIC_UID_LENGTH               0x04U
     48 #define MIFARE_UID_LEN_TO_COPY                  0x04U
     49 
     50 static void phFriNfc_OvrHal_CB_Send(void *context,
     51                                     NFCSTATUS status);
     52 static void phFriNfc_OvrHal_CB_Receive(void *context,
     53                                        phNfc_sData_t *pDataInfo,
     54                                        NFCSTATUS status);
     55 static void phFriNfc_OvrHal_CB_Transceive(void *context,
     56                                phHal_sRemoteDevInformation_t *RemoteDevHandle,
     57                                phNfc_sData_t  *pRecvdata,
     58                                NFCSTATUS status
     59                                );
     60 static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
     61                                phHal_sRemoteDevInformation_t *RemoteDevHandle,
     62                                NFCSTATUS status
     63                                );
     64 
     65 static void  phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
     66                                    phFriNfc_CplRt_t  *CompletionInfo,
     67                                    uint8_t            Operation);
     68 
     69 NFCSTATUS phFriNfc_OvrHal_Transceive(phFriNfc_OvrHal_t              *OvrHal,
     70                                      phFriNfc_CplRt_t               *CompletionInfo,
     71                                      phHal_sRemoteDevInformation_t  *RemoteDevInfo,
     72                                      phHal_uCmdList_t                Cmd,
     73                                      phHal_sDepAdditionalInfo_t     *DepAdditionalInfo,
     74                                      uint8_t                        *SendBuf,
     75                                      uint16_t                        SendLength,
     76                                      uint8_t                        *RecvBuf,
     77                                      uint16_t                       *RecvLength)
     78 {
     79     NFCSTATUS status = NFCSTATUS_PENDING;
     80     uint8_t i = 0;
     81     uint32_t length = SendLength;
     82 
     83     /* To remove "warning (VS C4100) : unreferenced formal parameter" */
     84     PHNFC_UNUSED_VARIABLE(DepAdditionalInfo);
     85 
     86     /* Check the Input Parameters */
     87     if ((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo)
     88         || (NULL == (void*)SendBuf) || (NULL == RecvBuf) || (NULL == RecvLength)
     89         || ((phHal_eJewel_PICC != RemoteDevInfo->RemDevType) && (0 == SendLength)))
     90 
     91     {
     92         status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL, NFCSTATUS_INVALID_PARAMETER);
     93     }
     94     else
     95     {
     96         /* 16 is the maximum data, that can be sent to the mifare standard */
     97         static uint8_t      mif_send_buf[MAX_MIF_PACKET_LEN] = {0};
     98         /* Populate the Transfer info structure */
     99         OvrHal->TranceiveInfo.cmd = Cmd;
    100 
    101         /* Populate the Send Buffer Info */
    102         if((phHal_eMifare_PICC == RemoteDevInfo->RemDevType)
    103             || (phHal_eISO14443_3A_PICC == RemoteDevInfo->RemDevType))
    104         {
    105             OvrHal->TranceiveInfo.addr = SendBuf[i++];
    106             length = (SendLength - i);
    107 
    108             if ((phHal_eMifareAuthentA == Cmd.MfCmd)
    109                 || (phHal_eMifareAuthentB == Cmd.MfCmd))
    110             {
    111                 uint8_t     uid_index = 0;
    112                 /* Authentication requires UID in the send buffer */
    113                 uint8_t     uid_len =
    114                         RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength;
    115                 OvrHal->TranceiveInfo.sSendData.buffer = mif_send_buf;
    116 
    117                 switch (uid_len)
    118                 {
    119                     case MIFARE_PLUS_UID_LENGTH:
    120                     {
    121                         uid_index = MIFARE_PLUS_UID_INDEX_TO_COPY;
    122                         uid_len = MIFARE_UID_LEN_TO_COPY;
    123                         break;
    124                     }
    125 
    126                     case MIFARE_CLASSIC_UID_LENGTH:
    127                     {
    128                         uid_index = 0;
    129                         break;
    130                     }
    131 
    132                     default:
    133                     {
    134                         status = PHNFCSTVAL (CID_FRI_NFC_OVR_HAL,
    135                                             NFCSTATUS_READ_FAILED);
    136                         break;
    137                     }
    138                 }
    139 
    140                 if (NFCSTATUS_PENDING == status)
    141                 {
    142                     /* copy uid to the send buffer for the authentication */
    143                     (void)memcpy ((void *)mif_send_buf,
    144                         (void *)&RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[uid_index],
    145                         uid_len);
    146 
    147                     (void)memcpy((mif_send_buf + uid_len), &(SendBuf[i]), length);
    148                     length += uid_len;
    149                 }
    150             }
    151             else
    152             {
    153                 OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++];
    154             }
    155             OvrHal->TranceiveInfo.sSendData.length = length;
    156         }
    157         else
    158         {
    159             OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++];
    160             OvrHal->TranceiveInfo.sSendData.length = length;
    161         }
    162 
    163         if (NFCSTATUS_PENDING == status)
    164         {
    165             /* Populate the Receive buffer */
    166             OvrHal->TranceiveInfo.sRecvData.buffer = RecvBuf;
    167             OvrHal->TranceiveInfo.sRecvData.length = *RecvLength;
    168             OvrHal->pndef_recv_length = RecvLength;
    169             phFriNfc_OvrHal_SetComplInfo(OvrHal,CompletionInfo, PH_FRINFC_OVRHAL_TRX);
    170 
    171             /* Call the HAL 4.0 Transceive Function */
    172             status = phHal4Nfc_Transceive (OvrHal->psHwReference,
    173                                             &OvrHal->TranceiveInfo, RemoteDevInfo,
    174                                             phFriNfc_OvrHal_CB_Transceive, (void *)OvrHal);
    175         }
    176 
    177     }
    178     return status;
    179 
    180 }
    181 
    182 NFCSTATUS phFriNfc_OvrHal_Receive(phFriNfc_OvrHal_t              *OvrHal,
    183                                   phFriNfc_CplRt_t               *CompletionInfo,
    184                                   phHal_sRemoteDevInformation_t  *RemoteDevInfo,
    185                                   uint8_t                        *RecvBuf,
    186                                   uint16_t                       *RecvLength)
    187 {
    188    NFCSTATUS status = NFCSTATUS_PENDING;
    189 
    190    /* Check the Input Parameters */
    191    if(   (NULL==OvrHal)  || (NULL==CompletionInfo) || (NULL==RemoteDevInfo)
    192       || (NULL==RecvBuf) || (NULL==RecvLength) )
    193    {
    194       status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
    195    }
    196    else
    197    {
    198       /* Get the remote dev type */
    199       OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType;
    200       /* Save the receive buffer for use in callback */
    201       OvrHal->sReceiveData.buffer = RecvBuf;
    202       OvrHal->sReceiveData.length = *RecvLength;
    203 
    204       OvrHal->pndef_recv_length = RecvLength;
    205 
    206       /* Set the callback */
    207       phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_RCV);
    208 
    209       /* Call the HAL 4.0 Receive Function */
    210       status = phHal4Nfc_Receive( OvrHal->psHwReference,
    211                                   &OvrHal->TransactInfo,
    212                                   phFriNfc_OvrHal_CB_Receive,
    213                                   (void *)OvrHal);
    214    }
    215    return status;
    216 }
    217 
    218 NFCSTATUS phFriNfc_OvrHal_Send(phFriNfc_OvrHal_t              *OvrHal,
    219                                phFriNfc_CplRt_t               *CompletionInfo,
    220                                phHal_sRemoteDevInformation_t  *RemoteDevInfo,
    221                                uint8_t                        *SendBuf,
    222                                uint16_t                       SendLength)
    223 {
    224    NFCSTATUS status = NFCSTATUS_PENDING;
    225 
    226    /* Check the Input Parameters */
    227    if(   (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo) || (NULL==SendBuf)  )
    228    {
    229       status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
    230    }
    231    else
    232    {
    233       /* Get the remote dev type */
    234       OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType;
    235       /* Save the receive buffer for use in callback */
    236       OvrHal->sSendData.buffer = SendBuf;
    237       OvrHal->sSendData.length = SendLength;
    238 
    239       /* Set the callback */
    240       phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_SND);
    241 
    242       /* Call the HAL 4.0 Receive Function */
    243       status = phHal4Nfc_Send( OvrHal->psHwReference,
    244                                &OvrHal->TransactInfo,
    245                                OvrHal->sSendData,
    246                                phFriNfc_OvrHal_CB_Send,
    247                                (void *)OvrHal);
    248    }
    249    return status;
    250 }
    251 
    252 #ifndef PH_FRINFC_MAP_MIFARESTD_DISABLED
    253 
    254 
    255 NFCSTATUS phFriNfc_OvrHal_Reconnect(phFriNfc_OvrHal_t              *OvrHal,
    256                                      phFriNfc_CplRt_t               *CompletionInfo,
    257                                      phHal_sRemoteDevInformation_t  *RemoteDevInfo)
    258 {
    259     NFCSTATUS status = NFCSTATUS_PENDING;
    260 
    261     /* Check the Input Parameters */
    262     if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo))
    263     {
    264         status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
    265     }
    266     else
    267     {
    268          phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_DIS);
    269 
    270          status = phHal4Nfc_Connect(
    271                              OvrHal->psHwReference,
    272                              RemoteDevInfo,
    273                              phFriNfc_OvrHal_CB_ConnectDisconnect,
    274                              (void *)OvrHal);
    275     }
    276 
    277     return status;
    278 }
    279 
    280 
    281 
    282 NFCSTATUS phFriNfc_OvrHal_Connect(phFriNfc_OvrHal_t              *OvrHal,
    283                                         phFriNfc_CplRt_t               *CompletionInfo,
    284                                         phHal_sRemoteDevInformation_t  *RemoteDevInfo,
    285                                         phHal_sDevInputParam_t         *DevInputParam)
    286 {
    287     NFCSTATUS status = NFCSTATUS_PENDING;
    288 
    289     /* Check the Input Parameters */
    290     if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo) ||
    291         (NULL == DevInputParam))
    292     {
    293         status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
    294     }
    295     else
    296     {
    297         phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_CON);
    298 
    299         status = phHal4Nfc_Connect(
    300                                     OvrHal->psHwReference,
    301                                     RemoteDevInfo,
    302                                     phFriNfc_OvrHal_CB_ConnectDisconnect,
    303                                     (void *)OvrHal
    304                                     );
    305     }
    306 
    307     return status;
    308 }
    309 
    310 #endif
    311 
    312 static void phFriNfc_OvrHal_CB_Transceive(void *context,
    313                                           phHal_sRemoteDevInformation_t *RemoteDevHandle,
    314                                           phNfc_sData_t  *pRecvdata,
    315                                           NFCSTATUS status
    316                                           )
    317 
    318 {
    319     phFriNfc_OvrHal_t       *OvrHal = (phFriNfc_OvrHal_t *)context;
    320 
    321     if (NULL != OvrHal)
    322     {
    323         if(NULL != pRecvdata && OvrHal->TranceiveInfo.sRecvData.buffer != NULL && pRecvdata->buffer != NULL)
    324         {
    325            /* Work-around for the NFCIP Tranceive API */
    326             if (OvrHal->TranceiveInfo.sRecvData.buffer != pRecvdata->buffer)
    327             {
    328                 memcpy(OvrHal->TranceiveInfo.sRecvData.buffer, pRecvdata->buffer, pRecvdata->length);
    329             }
    330             if (OvrHal->pndef_recv_length != NULL)
    331             {
    332                *OvrHal->pndef_recv_length = (uint16_t) pRecvdata->length;
    333             }
    334         }
    335         if(NULL != RemoteDevHandle)
    336         {
    337             /* Fix for Warning 4100 */
    338             RemoteDevHandle=RemoteDevHandle;
    339         }
    340 
    341         if (NULL != OvrHal->TemporaryCompletionInfo.CompletionRoutine)
    342         {
    343             OvrHal->TemporaryCompletionInfo.CompletionRoutine(
    344                 OvrHal->TemporaryCompletionInfo.Context,
    345                 status);
    346         }
    347     }
    348 }
    349 
    350 static void phFriNfc_OvrHal_CB_Send(void *context,
    351                                     NFCSTATUS status)
    352 {
    353     phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
    354 
    355     if (NULL != OvrHal)
    356     {
    357         if (NULL != OvrHal->TemporarySndCompletionInfo.CompletionRoutine)
    358         {
    359             OvrHal->TemporarySndCompletionInfo.CompletionRoutine(
    360                 OvrHal->TemporarySndCompletionInfo.Context,
    361                 status);
    362         }
    363     }
    364 }
    365 
    366 static void phFriNfc_OvrHal_CB_Receive(void *context,
    367                                        phNfc_sData_t *pDataInfo,
    368                                        NFCSTATUS status)
    369 {
    370     phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
    371 
    372     if (NULL != OvrHal)
    373     {
    374         /* Copy the received buffer */
    375         if(NULL != pDataInfo && OvrHal->sReceiveData.buffer != NULL && pDataInfo->buffer != NULL)
    376         {
    377             memcpy(OvrHal->sReceiveData.buffer, pDataInfo->buffer, pDataInfo->length);
    378             *OvrHal->pndef_recv_length = (uint16_t) pDataInfo->length;
    379         }
    380 
    381         if (NULL != OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine)
    382         {
    383             OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine(
    384                 OvrHal->TemporaryRcvCompletionInfo.Context,
    385                 status);
    386         }
    387     }
    388 }
    389 
    390 static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
    391                                phHal_sRemoteDevInformation_t *RemoteDevHandle,
    392                                NFCSTATUS status
    393                                )
    394 
    395 {
    396     phFriNfc_OvrHal_t   *OvrHal = (phFriNfc_OvrHal_t *)context;
    397 
    398     if (NULL != OvrHal)
    399     {
    400         if (RemoteDevHandle != NULL)
    401         {
    402             /* Fix for Warning 4100 */
    403             RemoteDevHandle = RemoteDevHandle;
    404         }
    405         else
    406         {
    407             status = NFCSTATUS_FAILED;
    408         }
    409 
    410         OvrHal->TemporaryCompletionInfo.CompletionRoutine(
    411                 OvrHal->TemporaryCompletionInfo.Context, status);
    412     }
    413 
    414 }
    415 
    416 static void  phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
    417                                    phFriNfc_CplRt_t  *CompletionInfo,
    418                                    uint8_t            Operation)
    419 
    420 {
    421    OvrHal->Operation = Operation;
    422    switch(Operation)
    423    {
    424       case PH_FRINFC_OVRHAL_RCV:
    425       {
    426          OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
    427          OvrHal->TemporaryRcvCompletionInfo.Context = CompletionInfo->Context;
    428          break;
    429       }
    430       case PH_FRINFC_OVRHAL_SND:
    431       {
    432          OvrHal->TemporarySndCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
    433          OvrHal->TemporarySndCompletionInfo.Context = CompletionInfo->Context;
    434          break;
    435       }
    436       default:
    437       {
    438          OvrHal->TemporaryCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
    439          OvrHal->TemporaryCompletionInfo.Context = CompletionInfo->Context;
    440          break;
    441       }
    442    }
    443 }
    444