phFriNfc_SmtCrdFmt.c revision 5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a
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_SmtCrdFmt.c
19 * \brief This component encapsulates different smart and simple tag formatting functionalities,
20 *        for the mapping layer.
21 *
22 * Project: NFC-FRI
23 *
24 * $Date: Wed Sep 23 14:41:56 2009 $
25 * $Author: ing07336 $
26 * $Revision: 1.8 $
27 * $Aliases: NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $
28 *
29 */
30
31#ifndef PH_FRINFC_CARD_FORMAT_DISABLED
32
33#include <phNfcTypes.h>
34#include <phFriNfc_OvrHal.h>
35#include <phFriNfc_SmtCrdFmt.h>
36#ifdef DISABLE_FORMAT
37#include <phFriNfc_TopazFormat.h>
38#endif /* #ifdef DISABLE_FORMAT */
39#include <phFriNfc_MifULFormat.h>
40#include <phFriNfc_DesfireFormat.h>
41#include <phFriNfc_MifStdFormat.h>
42
43
44/*! \ingroup grp_file_attributes
45 *  \name NDEF Mapping
46 *
47 * File: \ref phFriNfc_CardFormatFunctions.c
48 *
49 */
50/*@{*/
51// file versions
52/*@}*/
53
54
55
56
57void phFriNfc_SmtCrdFmt_HCrHandler(phFriNfc_sNdefSmtCrdFmt_t  *NdefSmtCrdFmt,
58                                       NFCSTATUS            Status)
59{
60    /* set the state back to the Reset_Init state*/
61    NdefSmtCrdFmt->State =  PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;
62
63    /* set the completion routine*/
64    NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_FORMAT].
65        CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context, Status);
66}
67
68/*!
69 * \brief Used to Reset the context variables , before the actual smart card formatting
70 *        procedure.
71 *
72 */
73NFCSTATUS phFriNfc_NdefSmtCrd_Reset(phFriNfc_sNdefSmtCrdFmt_t       *NdefSmtCrdFmt,
74                                    void                            *LowerDevice,
75                                    phHal_sRemoteDevInformation_t   *psRemoteDevInfo,
76                                    phHal_sDevInputParam_t          *psDevInputParam,
77                                    uint8_t                         *SendRecvBuffer,
78                                    uint16_t                        *SendRecvBuffLen)
79{
80    NFCSTATUS   result = NFCSTATUS_SUCCESS;
81    uint8_t     index;
82
83    if (    (SendRecvBuffLen == NULL) || (NdefSmtCrdFmt == NULL) || (psRemoteDevInfo == NULL) ||
84            (SendRecvBuffer == NULL) ||  (LowerDevice == NULL) ||
85            (*SendRecvBuffLen == 0) ||  (psDevInputParam == NULL) ||
86            (*SendRecvBuffLen < PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE) )
87    {
88        result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER);
89    }
90    else
91    {
92        /* Initialise the state to Init */
93        NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;
94
95        for(index = 0;index<PH_FRINFC_SMTCRDFMT_CR;index++)
96        {
97            /* Initialise the NdefMap Completion Routine to Null */
98            NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL;
99            /* Initialise the NdefMap Completion Routine context to Null  */
100            NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL;
101        }
102
103        /* Lower Device(Always Overlapped HAL Struct initialised in application
104            is registred in NdefMap Lower Device) */
105        NdefSmtCrdFmt->LowerDevice = LowerDevice;
106
107        /* Remote Device info received from Manual Device Discovery is registered here */
108        NdefSmtCrdFmt->psRemoteDevInfo = psRemoteDevInfo;
109
110        /* Trx Buffer registered */
111        NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer;
112
113        /* Trx Buffer Size */
114        NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen;
115
116        /* Register Transfer Buffer Length */
117        NdefSmtCrdFmt->SendLength = 0;
118
119        /* Initialise the Format status flag*/
120        NdefSmtCrdFmt->FmtProcStatus = 0;
121
122        /* Reset the Card Type */
123        NdefSmtCrdFmt->CardType = 0;
124
125        /* Reset MapCompletion Info*/
126        NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL;
127        NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL;
128
129#ifndef PH_FRINFC_FMT_TOPAZ_DISABLED
130        phFriNfc_Topaz_Reset(NdefSmtCrdFmt);
131
132#endif  /* PH_FRINFC_FMT_TOPAZ_DISABLED */
133
134#ifndef PH_FRINFC_FMT_DESFIRE_DISABLED
135        /*Reset Desfire Cap Container elements*/
136        phFriNfc_Desfire_Reset(NdefSmtCrdFmt);
137#endif  /* PH_FRINFC_FMT_DESFIRE_DISABLED */
138
139#ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED
140        /*Reset Mifare Standard Container elements*/
141        NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam = psDevInputParam;
142        phFriNfc_MfStd_Reset(NdefSmtCrdFmt);
143#endif  /* PH_FRINFC_MAP_MIFARESTD_DISABLED */
144
145#ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED
146        phFriNfc_MfUL_Reset(NdefSmtCrdFmt);
147#endif /* #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED */
148
149#ifdef PHFRINFC_OVRHAL_MOCKUP
150        /*Reset Desfire Cap Container elements*/
151  //      phFriNfc_Mockup_H_Reset(NdefSmtCrdFmt);
152#endif  /* PHFRINFC_OVRHAL_MOCKUP */
153
154    }
155    return (result);
156
157}
158
159/*!
160 * \brief Completion Routine initialisation
161 *
162 */
163NFCSTATUS phFriNfc_NdefSmtCrd_SetCR(phFriNfc_sNdefSmtCrdFmt_t     *NdefSmtCrdFmt,
164                                    uint8_t                       FunctionID,
165                                    pphFriNfc_Cr_t                CompletionRoutine,
166                                    void                          *CompletionRoutineContext)
167{
168    NFCSTATUS   status = NFCSTATUS_SUCCESS;
169
170    if ((NdefSmtCrdFmt == NULL) || (FunctionID >= PH_FRINFC_SMTCRDFMT_CR) ||
171        (CompletionRoutine == NULL) || (CompletionRoutineContext == NULL))
172    {
173        status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER);
174    }
175    else
176    {
177        /* Register the application callback with the NdefMap Completion Routine */
178        NdefSmtCrdFmt->CompletionRoutine[FunctionID].CompletionRoutine = CompletionRoutine;
179
180        /* Register the application context with the NdefMap Completion Routine context */
181        NdefSmtCrdFmt->CompletionRoutine[FunctionID].Context = CompletionRoutineContext;
182    }
183
184    return status;
185}
186
187
188/*!
189 * \brief Used to format the different smart cards.
190 *
191 */
192NFCSTATUS phFriNfc_NdefSmtCrd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB )
193{
194    /* Component ID needs to be changed */
195    NFCSTATUS   Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
196                                    NFCSTATUS_INVALID_PARAMETER);
197    uint8_t     sak = 0;
198
199    /* Check for the correct context structure */
200    if((NdefSmtCrdFmt != NULL) &&
201        (NdefSmtCrdFmt->CompletionRoutine->CompletionRoutine != NULL) &&
202        (NdefSmtCrdFmt->CompletionRoutine->Context != NULL))
203    {
204#ifdef PH_HAL4_ENABLE
205        /* SAK (Select response) */
206        sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
207
208        /* Depending on the Opmodes, call the respective card functions */
209        switch ( NdefSmtCrdFmt->psRemoteDevInfo->RemDevType )
210#else
211        /* SAK (Select response) */
212        sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.CardInfo106.
213                Startup106.SelRes;
214
215        /* Depending on the Opmodes, call the respective card functions */
216        switch ( NdefSmtCrdFmt->psRemoteDevInfo->OpMode )
217#endif /* #ifdef PH_HAL4_ENABLE */
218        {
219#ifdef PH_HAL4_ENABLE
220            case phHal_eMifare_PICC :
221#else
222            case phHal_eOpModesMifare :
223#endif /* #ifdef PH_HAL4_ENABLE */
224                /*  Remote device is Mifare card . Check for Mifare
225                NDEF compliance */
226                if(0x00 == sak)
227                {
228#ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED
229                    /*  The SAK/Sel_Res says the card is of the type
230                        Mifare UL */
231                   NdefSmtCrdFmt->CardType = PH_FRINFC_SMTCRDFMT_MIFARE_UL_CARD;
232					if (NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength == 7 &&
233						NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0] == 0x04)
234					{
235
236	                    Result = phFriNfc_MfUL_Format( NdefSmtCrdFmt);
237					}
238					else
239					{
240						Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
241                                    NFCSTATUS_INVALID_REMOTE_DEVICE);
242					}
243#else
244                    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
245                                    NFCSTATUS_INVALID_REMOTE_DEVICE);
246#endif /* #ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED */
247                }
248                else if((0x08 == (sak & 0x18)) ||
249                        (0x18 == (sak & 0x18)))
250                {
251#ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED
252                    NdefSmtCrdFmt->CardType = (uint8_t)
253                        (((sak & 0x18) == 0x08)?
254                        PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD:
255                        PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD);
256
257                    /*  The SAK/Sel_Res says the card is of the type
258                        Mifare standard */
259                    Result = phFriNfc_MfStd_Format( NdefSmtCrdFmt, ScrtKeyB);
260#else
261                    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
262                                    NFCSTATUS_INVALID_REMOTE_DEVICE);
263#endif /* #ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED */
264                }
265                else
266                {
267                    /*  Invalid Mifare card, as the remote device
268                        info - opmode says its a Mifare card but,
269                        The SAK/Sel_Res is wrong */
270                    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
271                                        NFCSTATUS_INVALID_REMOTE_DEVICE);
272                }
273            break;
274#ifdef PH_HAL4_ENABLE
275            case phHal_eISO14443_A_PICC :
276#else
277            case phHal_eOpModesISO14443_4A :
278#endif /* #ifdef PH_HAL4_ENABLE */
279                /*  Remote device is Desfire card . Check for Desfire
280                NDEF compliancy */
281                 if(0x20 == (sak & 0xFF))
282                {
283#ifndef PH_FRINFC_FMT_DESFIRE_DISABLED
284                    NdefSmtCrdFmt->CardType = PH_FRINFC_SMTCRDFMT_ISO14443_4A_CARD;
285                    /*  The SAK/Sel_Res says the card is of the type
286                        ISO14443_4A */
287
288                    Result = phFriNfc_Desfire_Format(NdefSmtCrdFmt);
289#else
290                    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
291                                        NFCSTATUS_INVALID_REMOTE_DEVICE);
292#endif /* #ifndef PH_FRINFC_FMT_DESFIRE_DISABLED */
293                }
294                else
295                {
296                    /*  Invalid Desfire card, as the remote device
297                        info - opmode says its a desfire card but,
298                        The SAK/Sel_Res is wrong */
299                    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
300                                        NFCSTATUS_INVALID_REMOTE_DEVICE);
301                }
302            break;
303#ifdef PH_HAL4_ENABLE
304            case phHal_eJewel_PICC :
305#else
306            case phHal_eOpModesJewel :
307#endif /* #ifdef PH_HAL4_ENABLE */
308                /*  Remote device is Topaz card . Check for Topaz
309                NDEF compliancy */
310                if(0xC2 == sak)
311                {
312#ifndef PH_FRINFC_FMT_TOPAZ_DISABLED
313                    NdefSmtCrdFmt->CardType = PH_FRINFC_SMTCRDFMT_TOPAZ_CARD;
314                    /*  The SAK/Sel_Res says the card is of the type
315                        ISO14443_4A */
316                    Result = phFriNfc_Topaz_Format(NdefSmtCrdFmt);
317#else
318                    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
319                                        NFCSTATUS_INVALID_REMOTE_DEVICE);
320#endif /* #ifndef PH_FRINFC_FMT_TOPAZ_DISABLED */
321
322                }
323                else
324                {
325                    /*  Invalid Topaz card, as the remote device
326                        info - opmode says its a desfire card but,
327                        The SAK/Sel_Res is wrong */
328                    Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
329                                        NFCSTATUS_INVALID_REMOTE_DEVICE);
330                }
331            break;
332
333#ifdef PHFRINFC_OVRHAL_MOCKUP
334            case phHal_eOpModesMockup :
335                    /*Set the OpMode Ttype Flag*/
336                    NdefSmtCrdFmt->OpModeType[0] = phHal_eOpModesMockup;
337                    NdefSmtCrdFmt->OpModeType[1] = phHal_eOpModesArrayTerminator;
338                    //Result = phFriNfc_Mockup_ChkNdef(NdefSmtCrdFmt);
339            break;
340#endif  /* PHFRINFC_OVRHAL_MOCKUP */
341
342            default :
343                /*  Remote device is not recognised.
344                Probably not NDEF compliant */
345                Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
346                                    NFCSTATUS_INVALID_REMOTE_DEVICE);
347            break;
348        }
349    }
350    return Result;
351}
352/*!
353 * \brief Handles different request and responses from the integration layer.
354 *
355 */
356void phFriNfc_NdefSmtCrd_Process(void        *Context,
357                                 NFCSTATUS    Status)
358{
359    if ( Context != NULL )
360    {
361        phFriNfc_sNdefSmtCrdFmt_t  *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
362#ifdef PH_HAL4_ENABLE
363        switch ( NdefSmtCrdFmt->psRemoteDevInfo->RemDevType )
364#else
365        switch ( NdefSmtCrdFmt->psRemoteDevInfo->OpMode )
366#endif /* #ifdef PH_HAL4_ENABLE */
367        {
368#ifdef PH_HAL4_ENABLE
369            case phHal_eMifare_PICC :
370#else
371            case  phHal_eOpModesMifare :
372#endif /* #ifdef PH_HAL4_ENABLE */
373                if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) ||
374                    (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD))
375                {
376#ifndef PH_FRINFC_FMT_MIFARESTD_DISABLED
377                    /*  Remote device is Mifare Standard card */
378                    phFriNfc_MfStd_Process(NdefSmtCrdFmt,Status);
379
380#else   /* PH_FRINFC_FMT_MIFARESTD_DISABLED*/
381                        Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
382                                            NFCSTATUS_INVALID_REMOTE_DEVICE);
383#endif  /* PH_FRINFC_FMT_MIFARESTD_DISABLED*/
384                }
385                else
386                {
387#ifndef PH_FRINFC_FMT_MIFAREUL_DISABLED
388                    /*  Remote device is Mifare UL card */
389                    phFriNfc_MfUL_Process(NdefSmtCrdFmt,Status);
390#else   /* PH_FRINFC_FMT_MIFAREUL_DISABLED*/
391                    Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
392                                         NFCSTATUS_INVALID_REMOTE_DEVICE);
393#endif  /* PH_FRINFC_FMT_MIFAREUL_DISABLED*/
394                }
395            break;
396
397#ifdef PH_HAL4_ENABLE
398            case phHal_eISO14443_A_PICC :
399#else
400            case phHal_eOpModesISO14443_4A :
401#endif /* #ifdef PH_HAL4_ENABLE */
402#ifndef PH_FRINFC_FMT_DESFIRE_DISABLED
403                /*  Remote device is Desfire card */
404                phFriNfc_Desf_Process(NdefSmtCrdFmt, Status);
405#else   /* PH_FRINFC_FMT_DESFIRE_DISABLED*/
406                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
407                                            NFCSTATUS_INVALID_REMOTE_DEVICE);
408#endif  /* PH_FRINFC_FMT_DESFIRE_DISABLED*/
409            break;
410#ifdef PH_HAL4_ENABLE
411            case phHal_eJewel_PICC :
412#else
413            case phHal_eOpModesJewel:
414#endif /* #ifdef PH_HAL4_ENABLE */
415#ifndef PH_FRINFC_FMT_TOPAZ_DISABLED
416                /*  Remote device is Topaz Smart card */
417               phFriNfc_Topaz_Process(NdefSmtCrdFmt, Status);
418#else   /* PH_FRINFC_FMT_TOPAZ_DISABLED*/
419               Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
420                                            NFCSTATUS_INVALID_REMOTE_DEVICE);
421#endif  /* PH_FRINFC_FMT_TOPAZ_DISABLED*/
422            break;
423
424#ifdef PHFRINFC_OVRHAL_MOCKUP
425            case phHal_eOpModesMockup:
426                /*  Remote device is Desfire card */
427                //phFriNfc_Mockup_Process(NdefSmtCrdFmt, Status);
428            break;
429#endif  /* PHFRINFC_OVRHAL_MOCKUP*/
430            default :
431                /*  Remote device opmode not recognised.
432                    Probably not NDEF compliant */
433                Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
434                                    NFCSTATUS_INVALID_REMOTE_DEVICE);
435                /* set the state back to the Reset_Init state*/
436                NdefSmtCrdFmt->State =  PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT;
437
438                /* set the completion routine*/
439                NdefSmtCrdFmt->CompletionRoutine[PH_FRINFC_SMTCRDFMT_CR_INVALID_OPE].
440                CompletionRoutine(NdefSmtCrdFmt->CompletionRoutine->Context, Status);
441            break;
442        }
443    }
444    else
445    {
446        Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,\
447                            NFCSTATUS_INVALID_PARAMETER);
448        /* The control should not come here. As Context itself is NULL ,
449           Can't call the CR*/
450    }
451}
452
453#endif  /* PH_FRINFC_CARD_FORMAT_DISABLED */
454
455