/*
 * 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_LlcpMacNfcip.c
 * \brief NFC LLCP MAC Mappings For Different RF Technologies.
 *
 * Project: NFC-FRI
 *
 */


/*include files*/
#include <phFriNfc_LlcpMac.h>
#include <phLibNfcStatus.h>
#include <phLibNfc.h>
#include <phLibNfc_Internal.h>
#include <stdio.h>
#include <string.h>

static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
                                             phNfc_sData_t                    *psData,
                                             phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
                                             void                             *pContext);


static void phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(phFriNfc_LlcpMac_t  *LlcpMac,
                                                 NFCSTATUS           status)
{
   phFriNfc_LlcpMac_Reveive_CB_t pfReceiveCB;
   void                          *pReceiveContext;

   if (LlcpMac->MacReceive_Cb != NULL)
   {
      /* Save callback params */
      pfReceiveCB = LlcpMac->MacReceive_Cb;
      pReceiveContext = LlcpMac->MacReceive_Context;

      /* Reset the pointer to the Receive Callback and Context*/
      LlcpMac->MacReceive_Cb = NULL;
      LlcpMac->MacReceive_Context = NULL;

      /* Call the receive callback */
      pfReceiveCB(pReceiveContext, status, LlcpMac->psReceiveBuffer);
   }
}

static void phFriNfc_LlcpMac_Nfcip_TriggerSendCb(phFriNfc_LlcpMac_t  *LlcpMac,
                                                 NFCSTATUS           status)
{
   phFriNfc_LlcpMac_Send_CB_t pfSendCB;
   void                       *pSendContext;

   if (LlcpMac->MacSend_Cb != NULL)
   {
      /* Save context in local variables */
      pfSendCB     = LlcpMac->MacSend_Cb;
      pSendContext = LlcpMac->MacSend_Context;

      /* Reset the pointer to the Send Callback */
      LlcpMac->MacSend_Cb = NULL;
      LlcpMac->MacSend_Context = NULL;

      /* Call Send callback */
      pfSendCB(pSendContext, status);
   }
}

static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Chk(phFriNfc_LlcpMac_t                   *LlcpMac,
                                            phFriNfc_LlcpMac_Chk_CB_t            ChkLlcpMac_Cb,
                                            void                                 *pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   uint8_t Llcp_Magic_Number[] = {0x46,0x66,0x6D};

   if(NULL == LlcpMac || NULL == ChkLlcpMac_Cb || NULL == pContext)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      status = (NFCSTATUS)memcmp(Llcp_Magic_Number,LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo,3);
      if(!status)
      {
         LlcpMac->sConfigParam.buffer = &LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[3] ;
         LlcpMac->sConfigParam.length = (LlcpMac->psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length - 3);
         status = NFCSTATUS_SUCCESS;
      }
      else
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
      }
   }

   ChkLlcpMac_Cb(pContext,status);
   return status;
}

static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Activate (phFriNfc_LlcpMac_t   *LlcpMac)
{
   NFCSTATUS status  = NFCSTATUS_SUCCESS;

   if(LlcpMac == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkActivated;
      LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
                             LlcpMac->LinkState,
                             &LlcpMac->sConfigParam,
                             LlcpMac->PeerRemoteDevType);
   }

   return status;
}

static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Deactivate (phFriNfc_LlcpMac_t   *LlcpMac)
{
   NFCSTATUS status  = NFCSTATUS_SUCCESS;

   if(NULL == LlcpMac)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      /* Set the flag of LinkStatus to deactivate */
      LlcpMac->LinkState = phFriNfc_LlcpMac_eLinkDeactivated;
   }

   if (LlcpMac->SendPending)
   {
      /* Reset Flag */
      LlcpMac->SendPending = FALSE;

      phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, NFCSTATUS_FAILED);
   }

   if (LlcpMac->RecvPending)
   {
      /* Reset Flag */
      LlcpMac->RecvPending = FALSE;

      phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, NFCSTATUS_FAILED);
   }

   LlcpMac->LinkStatus_Cb(LlcpMac->LinkStatus_Context,
                          LlcpMac->LinkState,
                          NULL,
                          LlcpMac->PeerRemoteDevType);

   return status;
}

static void phFriNfc_LlcpMac_Nfcip_Send_Cb(void       *pContext,
                                           NFCSTATUS   Status)
{
   phFriNfc_LlcpMac_t            *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;

#ifdef LLCP_CHANGES
   if(gpphLibContext->LibNfcState.next_state
                               == eLibNfcHalStateShutdown)
   {
      phLibNfc_Pending_Shutdown();
      Status = NFCSTATUS_SHUTDOWN;
   }
#endif /* #ifdef LLCP_CHANGES */

   /* Reset Send and Receive Flag */
   LlcpMac->SendPending = FALSE;
   LlcpMac->RecvPending = FALSE;

   phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);

}

static void phFriNfc_LlcpMac_Nfcip_Receive_Cb(void       *pContext,
                                              NFCSTATUS   Status)
{
   phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;
#ifdef LLCP_CHANGES

   phFriNfc_LlcpMac_Send_CB_t       pfSendCB;
   void                             *pSendContext;


   if(gpphLibContext->LibNfcState.next_state
                               == eLibNfcHalStateShutdown)
   {
      phLibNfc_Pending_Shutdown();
      Status = NFCSTATUS_SHUTDOWN;
   }

   if (NFCSTATUS_SHUTDOWN == Status)
   {
      /* Save context in local variables */
      pfSendCB = LlcpMac->MacSend_Cb;
      pSendContext = LlcpMac->MacSend_Context;

      /* Reset the pointer to the Send Callback */
      LlcpMac->MacSend_Cb = NULL;
      LlcpMac->MacSend_Context = NULL;

      /* Reset Send and Receive Flag */
      LlcpMac->SendPending = FALSE;
      LlcpMac->RecvPending = FALSE;
   }

#endif /* #ifdef LLCP_CHANGES */

   phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);

#ifdef LLCP_CHANGES

   if (NFCSTATUS_SHUTDOWN == Status)
   {
       if ((LlcpMac->SendPending) && (NULL != pfSendCB))
       {
           pfSendCB(pSendContext, Status);
      }
   }
   else

#endif /* #ifdef LLCP_CHANGES */
   {
   /* Test if a send is pending */
   if(LlcpMac->SendPending)
   {
      Status = phFriNfc_LlcpMac_Nfcip_Send(LlcpMac,LlcpMac->psSendBuffer,LlcpMac->MacSend_Cb,LlcpMac->MacSend_Context);
   }
}
}

static void phFriNfc_LlcpMac_Nfcip_Transceive_Cb(void       *pContext,
                                                 NFCSTATUS   Status)
{
   phFriNfc_LlcpMac_t               *LlcpMac = (phFriNfc_LlcpMac_t *)pContext;

#ifdef LLCP_CHANGES
   if(gpphLibContext->LibNfcState.next_state
                               == eLibNfcHalStateShutdown)
   {
      phLibNfc_Pending_Shutdown();
      Status = NFCSTATUS_SHUTDOWN;
   }
#endif /* #ifdef LLCP_CHANGES */

   /* Reset Send and Receive Flag */
   LlcpMac->SendPending = FALSE;
   LlcpMac->RecvPending = FALSE;

   /* Call the callbacks */
   phFriNfc_LlcpMac_Nfcip_TriggerSendCb(LlcpMac, Status);
   phFriNfc_LlcpMac_Nfcip_TriggerRecvCb(LlcpMac, Status);
}

static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Send(phFriNfc_LlcpMac_t               *LlcpMac,
                                             phNfc_sData_t                    *psData,
                                             phFriNfc_LlcpMac_Send_CB_t       LlcpMacSend_Cb,
                                             void                             *pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   
   if(NULL == LlcpMac || NULL == psData || NULL == LlcpMacSend_Cb || NULL == pContext)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
   }
   else if(LlcpMac->MacSend_Cb != NULL && LlcpMac->PeerRemoteDevType == phFriNfc_LlcpMac_ePeerTypeInitiator)
   {
      /*Previous callback is pending */
      status = NFCSTATUS_REJECTED;
   }
   else
   {
      /* Save the LlcpMacSend_Cb */
      LlcpMac->MacSend_Cb = LlcpMacSend_Cb;
      LlcpMac->MacSend_Context = pContext;

      switch(LlcpMac->PeerRemoteDevType)
      {
      case phFriNfc_LlcpMac_ePeerTypeInitiator:
         {
            if(LlcpMac->RecvPending)
            {
               /*set the completion routines for the LLCP Transceive function*/
                LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
                LlcpMac->MacCompletionInfo.Context = LlcpMac;

                /* set the command type*/
                LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;

                /* set the Additional Info*/
                LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
                LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
                LlcpMac->SendPending = TRUE;

                status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
                                                    &LlcpMac->MacCompletionInfo,
                                                    LlcpMac->psRemoteDevInfo,
                                                    LlcpMac->Cmd,
                                                    &LlcpMac->psDepAdditionalInfo,
                                                    psData->buffer,
                                                    (uint16_t)psData->length,
                                                    LlcpMac->psReceiveBuffer->buffer,
                                                    (uint16_t*)&LlcpMac->psReceiveBuffer->length);
            }
            else
            {
               LlcpMac->SendPending = TRUE;
               LlcpMac->psSendBuffer = psData;
               return status = NFCSTATUS_PENDING;
            }
         }break;
      case phFriNfc_LlcpMac_ePeerTypeTarget:
         {
            if(!LlcpMac->RecvPending)
            {
               LlcpMac->SendPending = TRUE;
               LlcpMac->psSendBuffer = psData;
               return status = NFCSTATUS_PENDING;
            }
            else
            {
               /*set the completion routines for the LLCP Send function*/
               LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Send_Cb;
               LlcpMac->MacCompletionInfo.Context = LlcpMac;
               status = phFriNfc_OvrHal_Send(LlcpMac->LowerDevice,
                                             &LlcpMac->MacCompletionInfo,
                                             LlcpMac->psRemoteDevInfo,
                                             psData->buffer,
                                             (uint16_t)psData->length);
            }
         }break;
      default:
         {
            status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
         }break;
      }
   }
   return status;
}

static NFCSTATUS phFriNfc_LlcpMac_Nfcip_Receive(phFriNfc_LlcpMac_t               *LlcpMac,
                                                phNfc_sData_t                    *psData,
                                                phFriNfc_LlcpMac_Reveive_CB_t    LlcpMacReceive_Cb,
                                                void                             *pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   if(NULL == LlcpMac || NULL==psData || NULL == LlcpMacReceive_Cb || NULL == pContext)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_PARAMETER);
   }
   else if(LlcpMac->MacReceive_Cb != NULL)
   {
      /*Previous callback is pending */
      status = NFCSTATUS_REJECTED;
   }
   else
   {
      /* Save the LlcpMacReceive_Cb */
      LlcpMac->MacReceive_Cb = LlcpMacReceive_Cb;
      LlcpMac->MacReceive_Context = pContext;

      /* Save the pointer to the receive buffer */
      LlcpMac->psReceiveBuffer= psData;

      switch(LlcpMac->PeerRemoteDevType)
      {
      case phFriNfc_LlcpMac_ePeerTypeInitiator:
         {
            if(LlcpMac->SendPending)
            {
               /*set the completion routines for the LLCP Transceive function*/
               LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Transceive_Cb;
               LlcpMac->MacCompletionInfo.Context = LlcpMac;
               /* set the command type*/
               LlcpMac->Cmd.NfcIP1Cmd = phHal_eNfcIP1_Raw;
               /* set the Additional Info*/
               LlcpMac->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
               LlcpMac->psDepAdditionalInfo.DepFlags.NADPresent = 0;
               LlcpMac->RecvPending = TRUE;

               status = phFriNfc_OvrHal_Transceive(LlcpMac->LowerDevice,
                                                   &LlcpMac->MacCompletionInfo,
                                                   LlcpMac->psRemoteDevInfo,
                                                   LlcpMac->Cmd,
                                                   &LlcpMac->psDepAdditionalInfo,
                                                   LlcpMac->psSendBuffer->buffer,
                                                   (uint16_t)LlcpMac->psSendBuffer->length,
                                                   psData->buffer,
                                                   (uint16_t*)&psData->length);
            }
            else
            {
               LlcpMac->RecvPending = TRUE;
               return status = NFCSTATUS_PENDING;
            }
         }break;
      case phFriNfc_LlcpMac_ePeerTypeTarget:
         {
             /*set the completion routines for the LLCP Receive function*/
            LlcpMac->MacCompletionInfo.CompletionRoutine = phFriNfc_LlcpMac_Nfcip_Receive_Cb;
            /* save the context of LlcpMacNfcip */
            LlcpMac->MacCompletionInfo.Context = LlcpMac;
            LlcpMac->RecvPending = TRUE;

            status = phFriNfc_OvrHal_Receive(LlcpMac->LowerDevice,
                                             &LlcpMac->MacCompletionInfo,
                                             LlcpMac->psRemoteDevInfo,
                                             LlcpMac->psReceiveBuffer->buffer,
                                             (uint16_t*)&LlcpMac->psReceiveBuffer->length);
         }break;
      default:
         {
            status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_INVALID_DEVICE);
         }break;
      }
   }
   return status;
}


NFCSTATUS phFriNfc_LlcpMac_Nfcip_Register (phFriNfc_LlcpMac_t *LlcpMac)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   if(NULL != LlcpMac)
   {
      LlcpMac->LlcpMacInterface.chk = phFriNfc_LlcpMac_Nfcip_Chk;
      LlcpMac->LlcpMacInterface.activate   = phFriNfc_LlcpMac_Nfcip_Activate;
      LlcpMac->LlcpMacInterface.deactivate = phFriNfc_LlcpMac_Nfcip_Deactivate;
      LlcpMac->LlcpMacInterface.send = phFriNfc_LlcpMac_Nfcip_Send;
      LlcpMac->LlcpMacInterface.receive = phFriNfc_LlcpMac_Nfcip_Receive;

      return NFCSTATUS_SUCCESS;
   }
   else
   {
      return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_MAC, NFCSTATUS_FAILED);
   }
}
