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