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 
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)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 
phFriNfc_OvrHal_Receive(phFriNfc_OvrHal_t * OvrHal,phFriNfc_CplRt_t * CompletionInfo,phHal_sRemoteDevInformation_t * RemoteDevInfo,uint8_t * RecvBuf,uint16_t * RecvLength)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 
phFriNfc_OvrHal_Send(phFriNfc_OvrHal_t * OvrHal,phFriNfc_CplRt_t * CompletionInfo,phHal_sRemoteDevInformation_t * RemoteDevInfo,uint8_t * SendBuf,uint16_t SendLength)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 
phFriNfc_OvrHal_Reconnect(phFriNfc_OvrHal_t * OvrHal,phFriNfc_CplRt_t * CompletionInfo,phHal_sRemoteDevInformation_t * RemoteDevInfo)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 
phFriNfc_OvrHal_Connect(phFriNfc_OvrHal_t * OvrHal,phFriNfc_CplRt_t * CompletionInfo,phHal_sRemoteDevInformation_t * RemoteDevInfo,phHal_sDevInputParam_t * DevInputParam)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 
phFriNfc_OvrHal_CB_Transceive(void * context,phHal_sRemoteDevInformation_t * RemoteDevHandle,phNfc_sData_t * pRecvdata,NFCSTATUS status)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 
phFriNfc_OvrHal_CB_Send(void * context,NFCSTATUS status)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 
phFriNfc_OvrHal_CB_Receive(void * context,phNfc_sData_t * pDataInfo,NFCSTATUS status)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 
phFriNfc_OvrHal_CB_ConnectDisconnect(void * context,phHal_sRemoteDevInformation_t * RemoteDevHandle,NFCSTATUS status)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 
phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t * OvrHal,phFriNfc_CplRt_t * CompletionInfo,uint8_t Operation)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