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
50static void phFriNfc_OvrHal_CB_Send(void *context,
51                                    NFCSTATUS status);
52static void phFriNfc_OvrHal_CB_Receive(void *context,
53                                       phNfc_sData_t *pDataInfo,
54                                       NFCSTATUS status);
55static void phFriNfc_OvrHal_CB_Transceive(void *context,
56                               phHal_sRemoteDevInformation_t *RemoteDevHandle,
57                               phNfc_sData_t  *pRecvdata,
58                               NFCSTATUS status
59                               );
60static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
61                               phHal_sRemoteDevInformation_t *RemoteDevHandle,
62                               NFCSTATUS status
63                               );
64
65static void  phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
66                                   phFriNfc_CplRt_t  *CompletionInfo,
67                                   uint8_t            Operation);
68
69NFCSTATUS 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
182NFCSTATUS 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
218NFCSTATUS 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
255NFCSTATUS 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
282NFCSTATUS 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
312static 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            memcpy(OvrHal->TranceiveInfo.sRecvData.buffer, pRecvdata->buffer, pRecvdata->length);
327            if (OvrHal->pndef_recv_length != NULL)
328            {
329               *OvrHal->pndef_recv_length = (uint16_t) pRecvdata->length;
330            }
331        }
332        if(NULL != RemoteDevHandle)
333        {
334            /* Fix for Warning 4100 */
335            RemoteDevHandle=RemoteDevHandle;
336        }
337
338        if (NULL != OvrHal->TemporaryCompletionInfo.CompletionRoutine)
339        {
340            OvrHal->TemporaryCompletionInfo.CompletionRoutine(
341                OvrHal->TemporaryCompletionInfo.Context,
342                status);
343        }
344    }
345}
346
347static void phFriNfc_OvrHal_CB_Send(void *context,
348                                    NFCSTATUS status)
349{
350    phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
351
352    if (NULL != OvrHal)
353    {
354        if (NULL != OvrHal->TemporarySndCompletionInfo.CompletionRoutine)
355        {
356            OvrHal->TemporarySndCompletionInfo.CompletionRoutine(
357                OvrHal->TemporarySndCompletionInfo.Context,
358                status);
359        }
360    }
361}
362
363static void phFriNfc_OvrHal_CB_Receive(void *context,
364                                       phNfc_sData_t *pDataInfo,
365                                       NFCSTATUS status)
366{
367    phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
368
369    if (NULL != OvrHal)
370    {
371        /* Copy the received buffer */
372        if(NULL != pDataInfo && OvrHal->sReceiveData.buffer != NULL && pDataInfo->buffer != NULL)
373        {
374            memcpy(OvrHal->sReceiveData.buffer, pDataInfo->buffer, pDataInfo->length);
375            *OvrHal->pndef_recv_length = (uint16_t) pDataInfo->length;
376        }
377
378        if (NULL != OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine)
379        {
380            OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine(
381                OvrHal->TemporaryRcvCompletionInfo.Context,
382                status);
383        }
384    }
385}
386
387static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
388                               phHal_sRemoteDevInformation_t *RemoteDevHandle,
389                               NFCSTATUS status
390                               )
391
392{
393    phFriNfc_OvrHal_t   *OvrHal = (phFriNfc_OvrHal_t *)context;
394
395    if (NULL != OvrHal)
396    {
397        if (RemoteDevHandle != NULL)
398        {
399            /* Fix for Warning 4100 */
400            RemoteDevHandle = RemoteDevHandle;
401        }
402        else
403        {
404            status = NFCSTATUS_FAILED;
405        }
406
407        OvrHal->TemporaryCompletionInfo.CompletionRoutine(
408                OvrHal->TemporaryCompletionInfo.Context, status);
409    }
410
411}
412
413static void  phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
414                                   phFriNfc_CplRt_t  *CompletionInfo,
415                                   uint8_t            Operation)
416
417{
418   OvrHal->Operation = Operation;
419   switch(Operation)
420   {
421      case PH_FRINFC_OVRHAL_RCV:
422      {
423         OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
424         OvrHal->TemporaryRcvCompletionInfo.Context = CompletionInfo->Context;
425         break;
426      }
427      case PH_FRINFC_OVRHAL_SND:
428      {
429         OvrHal->TemporarySndCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
430         OvrHal->TemporarySndCompletionInfo.Context = CompletionInfo->Context;
431         break;
432      }
433      default:
434      {
435         OvrHal->TemporaryCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
436         OvrHal->TemporaryCompletionInfo.Context = CompletionInfo->Context;
437         break;
438      }
439   }
440}
441