/*
 * Copyright (C) 2010 NXP Semiconductors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*!
 * \file  phFriNfc_OvrHal.c
 * \brief Overlapped HAL
 *
 * Project: NFC-FRI
 * Creator: Gerald Kersch
 *
 * $Date: Wed May  5 10:47:27 2010 $
 * Changed by: $Author: ing02260 $
 * $Revision: 1.37 $
 * $Aliases: NFC_FRI1.1_WK1017_R34_3,NFC_FRI1.1_WK1023_R35_1 $
 *
 */

#include <phFriNfc_OvrHal.h>
#include <phOsalNfc.h>
#include <phFriNfc_NdefMap.h>
#include <phFriNfc_SmtCrdFmt.h>


#ifdef PHFRINFC_OVRHAL_MOCKUP  /* */
//#include <phLibNfc_Gen.h>
#endif /* PHFRINFC_OVRHAL_MOCKUP */
/*
*   

*/
#define MAX_MIF_PACKET_LEN                      0x0FU
#define MIFARE_PLUS_UID_INDEX_TO_COPY           0x03U
#define MIFARE_PLUS_UID_LENGTH                  0x07U
#define MIFARE_CLASSIC_UID_LENGTH               0x04U
#define MIFARE_UID_LEN_TO_COPY                  0x04U

static void phFriNfc_OvrHal_CB_Send(void *context,
                                    NFCSTATUS status);
static void phFriNfc_OvrHal_CB_Receive(void *context,
                                       phNfc_sData_t *pDataInfo,
                                       NFCSTATUS status);
static void phFriNfc_OvrHal_CB_Transceive(void *context,
                               phHal_sRemoteDevInformation_t *RemoteDevHandle,
                               phNfc_sData_t  *pRecvdata,
                               NFCSTATUS status
                               );
static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
                               phHal_sRemoteDevInformation_t *RemoteDevHandle,
                               NFCSTATUS status
                               );

static void  phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
                                   phFriNfc_CplRt_t  *CompletionInfo,
                                   uint8_t            Operation);

NFCSTATUS phFriNfc_OvrHal_Transceive(phFriNfc_OvrHal_t              *OvrHal,
                                     phFriNfc_CplRt_t               *CompletionInfo,
                                     phHal_sRemoteDevInformation_t  *RemoteDevInfo,
                                     phHal_uCmdList_t                Cmd,
                                     phHal_sDepAdditionalInfo_t     *DepAdditionalInfo,
                                     uint8_t                        *SendBuf,
                                     uint16_t                        SendLength,
                                     uint8_t                        *RecvBuf,
                                     uint16_t                       *RecvLength)
{
    NFCSTATUS status = NFCSTATUS_PENDING;
    uint8_t i = 0;
    uint32_t length = SendLength;

    /* To remove "warning (VS C4100) : unreferenced formal parameter" */
    PHNFC_UNUSED_VARIABLE(DepAdditionalInfo);

    /* Check the Input Parameters */
    if ((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo)
        || (NULL == (void*)SendBuf) || (NULL == RecvBuf) || (NULL == RecvLength) 
        || ((phHal_eJewel_PICC != RemoteDevInfo->RemDevType) && (0 == SendLength)))

    {
        status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        /* 16 is the maximum data, that can be sent to the mifare standard */
        static uint8_t      mif_send_buf[MAX_MIF_PACKET_LEN] = {0};
        /* Populate the Transfer info structure */
        OvrHal->TranceiveInfo.cmd = Cmd;
     
        /* Populate the Send Buffer Info */
        if((phHal_eMifare_PICC == RemoteDevInfo->RemDevType) 
            || (phHal_eISO14443_3A_PICC == RemoteDevInfo->RemDevType))
        {
            OvrHal->TranceiveInfo.addr = SendBuf[i++];
            length = (SendLength - i);

            if ((phHal_eMifareAuthentA == Cmd.MfCmd) 
                || (phHal_eMifareAuthentB == Cmd.MfCmd))
            {
                uint8_t     uid_index = 0;
                /* Authentication requires UID in the send buffer */
                uint8_t     uid_len = 
                        RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength;
                OvrHal->TranceiveInfo.sSendData.buffer = mif_send_buf;

                switch (uid_len)
                {
                    case MIFARE_PLUS_UID_LENGTH:
                    {
                        uid_index = MIFARE_PLUS_UID_INDEX_TO_COPY;
                        uid_len = MIFARE_UID_LEN_TO_COPY;
                        break;
                    }

                    case MIFARE_CLASSIC_UID_LENGTH:
                    {
                        uid_index = 0;
                        break;
                    }

                    default:
                    {
                        status = PHNFCSTVAL (CID_FRI_NFC_OVR_HAL, 
                                            NFCSTATUS_READ_FAILED);                                            
                        break;
                    }
                }

                if (NFCSTATUS_PENDING == status)
                {
                    /* copy uid to the send buffer for the authentication */
                    (void)memcpy ((void *)mif_send_buf, 
                        (void *)&RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[uid_index], 
                        uid_len);

                    (void)memcpy((mif_send_buf + uid_len), &(SendBuf[i]), length);
                    length += uid_len;
                }
            }
            else
            {
                OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++];         
            }           
            OvrHal->TranceiveInfo.sSendData.length = length;
        }
        else
        {
            OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++];
            OvrHal->TranceiveInfo.sSendData.length = length;
        }
        
        if (NFCSTATUS_PENDING == status)
        {
            /* Populate the Receive buffer */
            OvrHal->TranceiveInfo.sRecvData.buffer = RecvBuf;
            OvrHal->TranceiveInfo.sRecvData.length = *RecvLength;
            OvrHal->pndef_recv_length = RecvLength;
            phFriNfc_OvrHal_SetComplInfo(OvrHal,CompletionInfo, PH_FRINFC_OVRHAL_TRX);
            
            /* Call the HAL 4.0 Transceive Function */
            status = phHal4Nfc_Transceive (OvrHal->psHwReference, 
                                            &OvrHal->TranceiveInfo, RemoteDevInfo, 
                                            phFriNfc_OvrHal_CB_Transceive, (void *)OvrHal);
        }

    }
    return status;  

}

NFCSTATUS phFriNfc_OvrHal_Receive(phFriNfc_OvrHal_t              *OvrHal,
                                  phFriNfc_CplRt_t               *CompletionInfo,
                                  phHal_sRemoteDevInformation_t  *RemoteDevInfo,
                                  uint8_t                        *RecvBuf,
                                  uint16_t                       *RecvLength)
{
   NFCSTATUS status = NFCSTATUS_PENDING;

   /* Check the Input Parameters */
   if(   (NULL==OvrHal)  || (NULL==CompletionInfo) || (NULL==RemoteDevInfo)
      || (NULL==RecvBuf) || (NULL==RecvLength) )
   {
      status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      /* Get the remote dev type */
      OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType;
      /* Save the receive buffer for use in callback */
      OvrHal->sReceiveData.buffer = RecvBuf;
      OvrHal->sReceiveData.length = *RecvLength;

      OvrHal->pndef_recv_length = RecvLength;
      
      /* Set the callback */
      phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_RCV);

      /* Call the HAL 4.0 Receive Function */
      status = phHal4Nfc_Receive( OvrHal->psHwReference,
                                  &OvrHal->TransactInfo,
                                  phFriNfc_OvrHal_CB_Receive,
                                  (void *)OvrHal);               
   }
   return status;  
}

NFCSTATUS phFriNfc_OvrHal_Send(phFriNfc_OvrHal_t              *OvrHal,
                               phFriNfc_CplRt_t               *CompletionInfo,
                               phHal_sRemoteDevInformation_t  *RemoteDevInfo,
                               uint8_t                        *SendBuf,
                               uint16_t                       SendLength)
{
   NFCSTATUS status = NFCSTATUS_PENDING;

   /* Check the Input Parameters */
   if(   (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo) || (NULL==SendBuf)  )
   {
      status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      /* Get the remote dev type */
      OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType;
      /* Save the receive buffer for use in callback */
      OvrHal->sSendData.buffer = SendBuf;
      OvrHal->sSendData.length = SendLength;
      
      /* Set the callback */
      phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_SND);

      /* Call the HAL 4.0 Receive Function */
      status = phHal4Nfc_Send( OvrHal->psHwReference,
                               &OvrHal->TransactInfo,
                               OvrHal->sSendData,
                               phFriNfc_OvrHal_CB_Send,
                               (void *)OvrHal);
   }
   return status;
}

#ifndef PH_FRINFC_MAP_MIFARESTD_DISABLED


NFCSTATUS phFriNfc_OvrHal_Reconnect(phFriNfc_OvrHal_t              *OvrHal,
                                     phFriNfc_CplRt_t               *CompletionInfo,
                                     phHal_sRemoteDevInformation_t  *RemoteDevInfo)
{
    NFCSTATUS status = NFCSTATUS_PENDING;
     
    /* Check the Input Parameters */
    if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo))
    {
        status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
         phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_DIS);

         status = phHal4Nfc_Connect(                                   
                             OvrHal->psHwReference,
                             RemoteDevInfo,                     
                             phFriNfc_OvrHal_CB_ConnectDisconnect,
                             (void *)OvrHal);       
    }

    return status;
}



NFCSTATUS phFriNfc_OvrHal_Connect(phFriNfc_OvrHal_t              *OvrHal,
                                        phFriNfc_CplRt_t               *CompletionInfo,
                                        phHal_sRemoteDevInformation_t  *RemoteDevInfo,
                                        phHal_sDevInputParam_t         *DevInputParam)
{
    NFCSTATUS status = NFCSTATUS_PENDING;
         
    /* Check the Input Parameters */
    if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo) ||
        (NULL == DevInputParam))
    {
        status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_CON);

        status = phHal4Nfc_Connect(
                                    OvrHal->psHwReference, 
                                    RemoteDevInfo,                                    
                                    phFriNfc_OvrHal_CB_ConnectDisconnect,
                                    (void *)OvrHal
                                    );
    }

    return status;
}

#endif

static void phFriNfc_OvrHal_CB_Transceive(void *context,
                                          phHal_sRemoteDevInformation_t *RemoteDevHandle,
                                          phNfc_sData_t  *pRecvdata,
                                          NFCSTATUS status
                                          )

{
    phFriNfc_OvrHal_t       *OvrHal = (phFriNfc_OvrHal_t *)context; 
    
    if (NULL != OvrHal)
    {        
        if(NULL != pRecvdata && OvrHal->TranceiveInfo.sRecvData.buffer != NULL && pRecvdata->buffer != NULL)
        {
           /* Work-around for the NFCIP Tranceive API */
            memcpy(OvrHal->TranceiveInfo.sRecvData.buffer, pRecvdata->buffer, pRecvdata->length);
            if (OvrHal->pndef_recv_length != NULL)
            {
               *OvrHal->pndef_recv_length = (uint16_t) pRecvdata->length;
            }
        }
        if(NULL != RemoteDevHandle)
        {   
            /* Fix for Warning 4100 */
            RemoteDevHandle=RemoteDevHandle;
        }

        if (NULL != OvrHal->TemporaryCompletionInfo.CompletionRoutine)
        {
            OvrHal->TemporaryCompletionInfo.CompletionRoutine(
                OvrHal->TemporaryCompletionInfo.Context,
                status);
        }
    }
}

static void phFriNfc_OvrHal_CB_Send(void *context,
                                    NFCSTATUS status)
{
    phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
    
    if (NULL != OvrHal)
    {
        if (NULL != OvrHal->TemporarySndCompletionInfo.CompletionRoutine)
        {
            OvrHal->TemporarySndCompletionInfo.CompletionRoutine(
                OvrHal->TemporarySndCompletionInfo.Context,
                status);
        }
    }
}

static void phFriNfc_OvrHal_CB_Receive(void *context,
                                       phNfc_sData_t *pDataInfo,
                                       NFCSTATUS status)
{
    phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; 
    
    if (NULL != OvrHal)
    {
        /* Copy the received buffer */
        if(NULL != pDataInfo && OvrHal->sReceiveData.buffer != NULL && pDataInfo->buffer != NULL)
        {
            memcpy(OvrHal->sReceiveData.buffer, pDataInfo->buffer, pDataInfo->length);
            *OvrHal->pndef_recv_length = (uint16_t) pDataInfo->length;
        }

        if (NULL != OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine)
        {
            OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine(
                OvrHal->TemporaryRcvCompletionInfo.Context,
                status);
        }
    }
}

static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
                               phHal_sRemoteDevInformation_t *RemoteDevHandle,
                               NFCSTATUS status
                               )

{
    phFriNfc_OvrHal_t   *OvrHal = (phFriNfc_OvrHal_t *)context;
    
    if (NULL != OvrHal)
    {
        if (RemoteDevHandle != NULL)
        {
            /* Fix for Warning 4100 */
            RemoteDevHandle = RemoteDevHandle;
        }
        else
        {
            status = NFCSTATUS_FAILED;
        }
        
        OvrHal->TemporaryCompletionInfo.CompletionRoutine(
                OvrHal->TemporaryCompletionInfo.Context, status);
    }

}

static void  phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
                                   phFriNfc_CplRt_t  *CompletionInfo,
                                   uint8_t            Operation)

{
   OvrHal->Operation = Operation;
   switch(Operation)
   {
      case PH_FRINFC_OVRHAL_RCV:
      {
         OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
         OvrHal->TemporaryRcvCompletionInfo.Context = CompletionInfo->Context;
         break;
      }
      case PH_FRINFC_OVRHAL_SND:
      {
         OvrHal->TemporarySndCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
         OvrHal->TemporarySndCompletionInfo.Context = CompletionInfo->Context;
         break;
      }
      default:
      {
         OvrHal->TemporaryCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
         OvrHal->TemporaryCompletionInfo.Context = CompletionInfo->Context;
         break;
      }
   }
}
