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_MifStdFormat.c
19 * \brief NFC Ndef Formatting For Mifare standard card.
20 *
21 * Project: NFC-FRI
22 *
23 * $Date: Tue Oct 20 20:13:03 2009 $
24 * $Author: ing02260 $
25 * $Revision: 1.9 $
26 * $Aliases: 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 $
27 *
28 */
29
30#include <phFriNfc_MifStdFormat.h>
31#include <phFriNfc_OvrHal.h>
32
33/*! \ingroup grp_file_attributes
34 *  \name NDEF Mapping
35 *
36 * File: \ref phFriNfc_MifStdFormat.c
37 *
38 */
39/*@{*/
40#define PHFRINFCMIFSTDFMT_FILEREVISION "$Revision: 1.9 $"
41#define PHFRINFCMIFSTDFMT_FILEALIASES  "$Aliases: 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 $"
42/*@}*/
43
44/*!
45 * \brief \copydoc page_ovr Helper function for Mifare standard. This function fills the
46 * send buffer for transceive function
47 */
48static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t      *NdefSmtCrdFmt,
49                                        uint16_t                         BlockNo);
50
51/*!
52 * \brief \copydoc page_ovr Helper function for Mifare standard. This function authenticates
53 *  a block or a sector from the card.
54 */
55static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
56
57/*!
58 * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
59 *  disconnect.
60 */
61static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt,
62                                             NFCSTATUS                    Status);
63
64/*!
65 * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
66 *  disconnect.
67 */
68static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
69
70#ifndef PH_HAL4_ENABLE
71/*!
72 * \brief \copydoc page_ovr Helper function for Mifare standard. This function calls
73 *  disconnect.
74 */
75static NFCSTATUS phFriNfc_MfStd_H_CallPoll(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
76#endif /* #ifndef PH_HAL4_ENABLE */
77
78/*!
79 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
80 * poll call.
81 */
82static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
83
84/*!
85 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
86 * authenticate call.
87 */
88static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
89
90/*!
91 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
92 * read access bit call.
93 */
94static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
95
96/*!
97 * \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process the
98 * write access bit call.
99 */
100static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
101
102/*!
103 * \brief \copydoc page_ovr Helper function for Mifare standard. This function writes the
104 * sector trailer using the block number.
105 */
106static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
107
108/*!
109 * \brief \copydoc page_ovr Helper function for Mifare standard. This function checks the
110 * access bits of each sector trailer.
111 */
112static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t                 BlockNo,
113                                           const uint8_t                    *RecvBuf,
114                                           const uint8_t            AcsBits1[],
115                                           const uint8_t            AcsBits2[]);
116
117/*!
118 * \brief \copydoc page_ovr Helper function for Mifare standard. This function change the
119 * authentication state and change the block number if required
120 */
121static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
122
123/*!
124 * \brief \copydoc page_ovr Helper function for Mifare standard. This function finds the
125 * contiguous ndef compliant blocks.
126 */
127static void phFriNfc_MfStd_H_NdefComplSect(uint8_t      CardTypes,
128                                           uint8_t      Sector[]);
129
130/*!
131 * \brief \copydoc page_ovr Helper function for Mifare standard. This function writes the
132 * MAD block values.
133 */
134static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
135
136/*!
137* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
138* the error status of the authentication
139*/
140static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
141
142/*!
143* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
144* the error status of the writing sector trailer
145*/
146static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
147
148/*!
149* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
150* the error status of the reading sector trailer
151*/
152static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
153
154/*!
155* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall process
156* the error status of the writing sector trailer
157*/
158static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
159
160/*!
161* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall store the
162* ndef compliant in the MAD array which will be later used for updating the MAD sector
163*/
164static void phFriNfc_MfStd_H_StrNdefData(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
165
166/*!
167* \brief \copydoc page_ovr Helper function for Mifare standard. This function shall find the ndef compliant
168* and calculate the block number to write the NDEF TLV
169*/
170static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt);
171
172static int phFriNfc_MfStd_MemCompare ( void *s1, void *s2, unsigned int n );
173
174
175void phFriNfc_MfStd_Reset(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
176{
177    uint8_t NfcForSectArray[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT,
178            MADSectArray[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K;
179
180    /* Authentication state */
181    NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_VAL_1;
182
183    /* Set default key for A or B */
184    (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.Default_KeyA_OR_B,
185                PH_FRINFC_MFSTD_FMT_DEFAULT_KEY, /* 0xFF */
186                PH_FRINFC_MFSTD_FMT_VAL_6);
187
188    /* MAD sector key A */
189    (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_KeyA,
190                MADSectArray, //PH_FRINFC_MFSTD_FMT_VAL_0,
191                PH_FRINFC_MFSTD_FMT_VAL_6);
192
193    /* Copy access bits for MAD sectors */
194    (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
195                &MADSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
196                PH_FRINFC_MFSTD_FMT_VAL_3);
197
198    /* NFC forum sector key A */
199    (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_KeyA,
200                NfcForSectArray, //PH_FRINFC_MFSTD_FMT_VAL_0,
201                PH_FRINFC_MFSTD_FMT_VAL_6);
202
203    /* Copy access bits for NFC forum sectors */
204    (void)memcpy(NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits,
205                &NfcForSectArray[PH_FRINFC_MFSTD_FMT_VAL_6],
206                PH_FRINFC_MFSTD_FMT_VAL_3);
207
208    /* Sector compliant array initialised to 0 */
209    (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
210                PH_FRINFC_MFSTD_FMT_VAL_0, /* 0x00 */
211                PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
212
213    NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_0;
214    NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
215
216}
217
218NFCSTATUS phFriNfc_MfStd_Format( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB )
219{
220    NFCSTATUS               Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
221                                                NFCSTATUS_INVALID_PARAMETER);
222    uint8_t                 index = PH_FRINFC_MFSTD_FMT_VAL_0;
223
224    if(ScrtKeyB != NULL)
225    {
226        NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
227            PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
228        /* Store Key B in the context */
229        while(index < PH_FRINFC_MFSTD_FMT_VAL_6)
230        {
231            NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB[index] = ScrtKeyB[index];
232            index++;
233        }
234        /* Set the state */
235        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
236        /* Initialise current block to the first sector trailer */
237        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = PH_FRINFC_MFSTD_FMT_VAL_3;
238        /* Set the authenticate state */
239        NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
240        /* Start authentication */
241        Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
242    }
243    return Result;
244}
245
246void phFriNfc_MfStd_Process(void        *Context,
247                            NFCSTATUS   Status)
248{
249    phFriNfc_sNdefSmtCrdFmt_t  *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context;
250    /* Copy the formatting status */
251    NdefSmtCrdFmt->FmtProcStatus = Status;
252    if(Status == NFCSTATUS_SUCCESS)
253    {
254        switch(NdefSmtCrdFmt->State)
255        {
256        case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
257            Status = phFriNfc_MfStd_H_ProAuth(NdefSmtCrdFmt);
258            break;
259
260        case PH_FRINFC_MFSTD_FMT_DIS_CON:
261#ifndef PH_HAL4_ENABLE
262            Status = phFriNfc_MfStd_H_CallPoll(NdefSmtCrdFmt);
263            break;
264
265        case PH_FRINFC_MFSTD_FMT_POLL:
266#endif /* #ifndef PH_HAL4_ENABLE */
267            Status = phFriNfc_MfStd_H_CallCon(NdefSmtCrdFmt);
268            break;
269
270        case PH_FRINFC_MFSTD_FMT_CON:
271            Status = phFriNfc_MfStd_H_ProCon(NdefSmtCrdFmt);
272            break;
273
274        case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
275            Status = phFriNfc_MfStd_H_ProRdSectTr(NdefSmtCrdFmt);
276            break;
277
278        case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
279            Status = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
280            break;
281
282        case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
283            Status = phFriNfc_MfStd_H_ProWrMADBlk(NdefSmtCrdFmt);
284            break;
285
286        case PH_FRINFC_MFSTD_FMT_WR_TLV:
287            break;
288
289        case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
290            Status = phFriNfc_MfStd_H_ProUpdMADBlk(NdefSmtCrdFmt);
291            break;
292
293        default:
294            Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT,
295                                NFCSTATUS_INVALID_DEVICE_REQUEST);
296            break;
297        }
298    }
299    else
300    {
301        switch(NdefSmtCrdFmt->State)
302        {
303        case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
304            Status = phFriNfc_MfStd_H_ProErrAuth(NdefSmtCrdFmt);
305            break;
306
307        case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
308            Status = phFriNfc_MfStd_H_ErrWrSectTr(NdefSmtCrdFmt);
309            break;
310
311        case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
312            Status = phFriNfc_MfStd_H_ErrRdSectTr(NdefSmtCrdFmt);
313            break;
314
315        default:
316            Status = NdefSmtCrdFmt->FmtProcStatus;
317            break;
318        }
319    }
320
321    /* Status is not success then call completion routine */
322    if(Status != NFCSTATUS_PENDING)
323    {
324        phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status);
325    }
326}
327
328static void phFriNfc_MfStd_H_FillSendBuf(phFriNfc_sNdefSmtCrdFmt_t      *NdefSmtCrdFmt,
329                                        uint16_t                         BlockNo)
330{
331    void        *mem = NULL;
332    uint8_t     MADSectTr1k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K, /* MAD key A,
333                                                                            Access bits and GPB of MAD sector */
334                MADSectTr4k[] = PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_4K, /* MAD key A,
335                                                                                    Access bits and GPB of MAD sector */
336                NFCSectTr[] = PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT, /* NFC forum key A,
337                                                                             Access bits and GPB of NFC sector */
338                NDEFMsgTLV[16] = {0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, /* NDEF message TLV (INITIALISED state) */
339                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340                                  0x00, 0x00, 0x00, 0x00},
341                MADBlk[16] = {0x0F, 0x00, 0x03, 0xE1, 0x03, 0xE1,
342                              0x03, 0xE1, 0x03, 0xE1,
343                              0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
344    /* Block number in send buffer */
345    NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_0] = (uint8_t)BlockNo;
346    /* Initialise send receive length */
347    *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_MFSTD_FMT_MAX_RECV_LENGTH;
348
349    /* Depending on the different state, fill the send buffer */
350    switch(NdefSmtCrdFmt->State)
351    {
352        case PH_FRINFC_MFSTD_FMT_AUTH_SECT:
353            /* Depending on the authentication state, fill the send buffer */
354            switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
355            {
356                case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
357                case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
358                    /* Fill send buffer with the default key */
359                    PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_DEF(mem);
360                break;
361
362                case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
363                    /* Fill send buffer with NFC forum sector key */
364                    PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_NFCSECT_KEYA(mem);
365                break;
366
367                case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
368                    /* Fill send buffer with NFC forum sector key */
369                    PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_SCRT_KEY(mem);
370                    break;
371
372                case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
373                default:
374                    /* Fill send buffer with MAD sector key */
375                    PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_MADSECT_KEYA(mem);
376                break;
377            }
378        break;
379
380        case PH_FRINFC_MFSTD_FMT_RD_SECT_TR:
381#ifdef PH_HAL4_ENABLE
382            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead;
383#else
384            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead;
385#endif /* #ifdef PH_HAL4_ENABLE */
386
387            /* Send length is always one for read operation */
388            NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_1;
389        break;
390
391        case PH_FRINFC_MFSTD_FMT_WR_SECT_TR:
392            /* Fill send buffer for writing sector trailer */
393#ifdef PH_HAL4_ENABLE
394            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
395#else
396            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
397#endif /* #ifdef PH_HAL4_ENABLE */
398            /* Copy the relevant sector trailer value in the buffer */
399            switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
400            {
401            case PH_FRINFC_MFSTD_FMT_VAL_3:
402                if (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)
403                {
404                    (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
405                                MADSectTr1k,
406                                sizeof(MADSectTr1k));
407                }
408                else
409                {
410                    (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
411                                MADSectTr4k,
412                                sizeof(MADSectTr4k));
413                }
414                break;
415            case 67:
416                (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
417                            MADSectTr4k,
418                            sizeof(MADSectTr4k));
419                break;
420            default:
421                (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
422                            NFCSectTr,
423                            sizeof(NFCSectTr));
424                break;
425            }
426            (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_11],
427                NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB,
428                sizeof(NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB));
429
430            /* Send length is always 17 for write operation */
431            NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
432        break;
433
434        case PH_FRINFC_MFSTD_FMT_WR_TLV:
435            /* Fill send buffer for writing TLV */
436#ifdef PH_HAL4_ENABLE
437            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
438#else
439            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
440#endif /* #ifdef PH_HAL4_ENABLE */
441            /* Copy the NDEF message TLV */
442            (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
443                        NDEFMsgTLV, sizeof(NDEFMsgTLV));
444            /* Send length is always 17 for write operation */
445            NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
446        break;
447
448        case PH_FRINFC_MFSTD_FMT_WR_MAD_BLK:
449            /* Fill send buffer for writing MAD block */
450#ifdef PH_HAL4_ENABLE
451            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
452#else
453            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
454#endif /* #ifdef PH_HAL4_ENABLE */
455
456            if((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_2) ||
457                (BlockNo == 65) || (BlockNo == 66))
458            {
459                /* MAD block number 2, 65 and 66 has 0x03, 0xE1 in the
460                    first two bytes */
461                MADBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x03;
462                MADBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0xE1;
463            }
464            /* Copy the MAD Block values */
465            (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
466                            MADBlk, sizeof(MADBlk));
467            /* Send length is always 17 for write operation */
468            NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
469        break;
470
471        case PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK:
472        default:
473            /* Fill send buffer for writing MAD block */
474#ifdef PH_HAL4_ENABLE
475            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite16;
476#else
477            NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
478#endif /* #ifdef PH_HAL4_ENABLE */
479            NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH;
480            switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
481            {
482            case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
483                (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
484                            NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
485                            (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
486                break;
487
488            case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
489                (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
490                    &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[16],
491                    (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
492                break;
493
494            case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
495                (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
496                    &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32],
497                    (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
498                break;
499
500            case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
501                (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
502                    &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[48],
503                    (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
504                break;
505
506            case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
507            default:
508                (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],
509                    &NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[64],
510                    (PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH - PH_FRINFC_MFSTD_FMT_VAL_1));
511                break;
512            }
513            break;
514    }
515    PHNFC_UNUSED_VARIABLE(mem);
516}
517
518static NFCSTATUS phFriNfc_MfStd_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
519{
520    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
521
522    /* set the data for additional data exchange*/
523    NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
524    NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0;
525    NdefSmtCrdFmt->psDepAdditionalInfo.NAD = 0;
526
527    /*set the completion routines for the card operations*/
528    NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process;
529    NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt;
530
531    *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE;
532
533    /* Call the Overlapped HAL Transceive function */
534    Result = phFriNfc_OvrHal_Transceive(    NdefSmtCrdFmt->LowerDevice,
535                                            &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
536                                            NdefSmtCrdFmt->psRemoteDevInfo,
537                                            NdefSmtCrdFmt->Cmd,
538                                            &NdefSmtCrdFmt->psDepAdditionalInfo,
539                                            NdefSmtCrdFmt->SendRecvBuf,
540                                            NdefSmtCrdFmt->SendLength,
541                                            NdefSmtCrdFmt->SendRecvBuf,
542                                            NdefSmtCrdFmt->SendRecvLength);
543    return Result;
544}
545
546static NFCSTATUS phFriNfc_MfStd_H_CallDisCon(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt,
547                                             NFCSTATUS                    Status)
548{
549    NFCSTATUS   Result = Status;
550
551    /*Set Ndef State*/
552    NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_DIS_CON;
553
554#ifdef PH_HAL4_ENABLE
555
556    /*Call the Overlapped HAL POLL function */
557    Result =  phFriNfc_OvrHal_Reconnect( NdefSmtCrdFmt->LowerDevice,
558                                    &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
559                                    NdefSmtCrdFmt->psRemoteDevInfo);
560#else
561    /*Call the Overlapped HAL POLL function */
562    Result =  phFriNfc_OvrHal_Disconnect( NdefSmtCrdFmt->LowerDevice,
563                                        &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
564                                        NdefSmtCrdFmt->psRemoteDevInfo);
565#endif /* #ifdef PH_HAL4_ENABLE */
566
567    return Result;
568}
569
570static NFCSTATUS phFriNfc_MfStd_H_CallCon(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
571{
572    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
573    /*Set Ndef State*/
574    NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_CON;
575
576    /*Call the Overlapped HAL POLL function */
577#ifdef PH_HAL4_ENABLE
578    Result =  phFriNfc_OvrHal_Connect(  NdefSmtCrdFmt->LowerDevice,
579                                        &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
580                                        NdefSmtCrdFmt->psRemoteDevInfo,
581                                        NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
582#else
583    Result =  phFriNfc_OvrHal_Connect(  NdefSmtCrdFmt->LowerDevice,
584                                        &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
585                                        phHal_eOpModesMifare,
586                                        NdefSmtCrdFmt->psRemoteDevInfo,
587                                        NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
588#endif /* #ifdef PH_HAL4_ENABLE */
589
590    return Result;
591}
592
593#ifndef PH_HAL4_ENABLE
594
595static NFCSTATUS phFriNfc_MfStd_H_CallPoll(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
596{
597    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
598    /*Set ndef State*/
599    NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_POLL;
600    /* Opmodes */
601    NdefSmtCrdFmt->OpModeType[PH_FRINFC_MFSTD_FMT_VAL_0] = phHal_eOpModesMifare;
602    NdefSmtCrdFmt->OpModeType[PH_FRINFC_MFSTD_FMT_VAL_1] = phHal_eOpModesArrayTerminator;
603
604    /* Number of devices to poll */
605    NdefSmtCrdFmt->AddInfo.MfStdInfo.NoOfDevices = PH_FRINFC_MFSTD_FMT_VAL_1;
606
607    /*Call the Overlapped HAL POLL function */
608    Result =  phFriNfc_OvrHal_Poll( NdefSmtCrdFmt->LowerDevice,
609                                    &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo,
610                                    NdefSmtCrdFmt->OpModeType,
611                                    NdefSmtCrdFmt->psRemoteDevInfo,
612                                    &NdefSmtCrdFmt->AddInfo.MfStdInfo.NoOfDevices,
613                                    NdefSmtCrdFmt->AddInfo.MfStdInfo.DevInputParam);
614    return Result;
615}
616
617#endif /* #ifndef PH_HAL4_ENABLE */
618
619static NFCSTATUS phFriNfc_MfStd_H_ProCon(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
620{
621    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
622    uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
623                index = PH_FRINFC_MFSTD_FMT_VAL_1;
624    uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
625
626    phFriNfc_MfStd_H_ChangeAuthSt(NdefSmtCrdFmt);
627    if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
628    {
629        PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
630    }
631    else
632    {
633        /* Set the state */
634        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
635        /* Start authentication */
636        Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
637    }
638    return Result;
639}
640
641static NFCSTATUS phFriNfc_MfStd_H_ProAuth(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
642{
643    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
644
645    /* Depending on the authentication key check the  */
646    switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)
647    {
648        case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:
649            if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
650                PH_FRINFC_MFSTD_FMT_VAL_3) &&
651                (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
652                PH_FRINFC_MFSTD_FMT_VAL_0))
653            {
654                /* Authenticate with default key for block 3 is successful,
655                    so fill the MAD block of sector 0 */
656                NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
657                                    PH_FRINFC_MFSTD_FMT_VAL_1;
658                /* Write the MAD block */
659                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
660            }
661            else if((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67)
662                && (NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag ==
663                PH_FRINFC_MFSTD_FMT_VAL_0))
664            {
665                /* Authenticate with default key for block 3 is successful,
666                so fill the MAD block of sector 64 */
667                NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 64;
668                /* Write the MAD block */
669                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
670            }
671            else
672            {
673                /* Not a MAD sector */
674                NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
675                                        PH_FRINFC_MFSTD_FMT_VAL_0;
676                /* Write the MAD block */
677                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
678            }
679        break;
680
681        case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:
682            if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
683                PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
684                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
685                PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
686                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
687                PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
688                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
689                PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
690                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
691                PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
692            {
693                NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
694                            NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
695                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
696            }
697            else
698            {
699                NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
700                                PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
701                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
702            }
703
704        break;
705
706        case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:
707            if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
708                PH_FRINFC_MFSTD_FMT_MAD_BLK_1) ||
709                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
710                PH_FRINFC_MFSTD_FMT_MAD_BLK_2) ||
711                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
712                PH_FRINFC_MFSTD_FMT_MAD_BLK_64) ||
713                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
714                PH_FRINFC_MFSTD_FMT_MAD_BLK_65) ||
715                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
716                PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
717            {
718                NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
719                    NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk;
720                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK;
721            }
722            else
723            {
724                NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
725                    PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
726                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
727            }
728            break;
729
730        case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:
731        case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:
732        default:
733            if((NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
734                PH_FRINFC_MFSTD_FMT_MAD_BLK_66) ||
735                (NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk ==
736                PH_FRINFC_MFSTD_FMT_MAD_BLK_2))
737            {
738                /* Updating the MAD block is complete */
739                NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk =
740                                PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK;
741                /* If Mifare 4k card, write the TLV */
742                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_TLV;
743            }
744            else
745            {
746                /* Depending on the sector trailer, check the access bit */
747                NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_RD_SECT_TR;
748            }
749        break;
750    }
751    /* Call read, write or authenticate */
752    Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
753    return Result;
754}
755
756static NFCSTATUS phFriNfc_MfStd_H_ErrWrSectTr( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
757{
758    NFCSTATUS   Result = NdefSmtCrdFmt->FmtProcStatus;
759    /* If default key A is used for authentication and if write fails, then try to
760    authenticate using key B*/
761    if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
762        PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
763    {
764        /* Change the state to authentication */
765        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
766        /* internal authenticate state = key B */
767        NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
768        /* Now call authenticate */
769        Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
770    }
771    else
772    {
773        Result = phFriNfc_MfStd_H_ProWrSectTr(NdefSmtCrdFmt);
774    }
775    return Result;
776}
777static NFCSTATUS phFriNfc_MfStd_H_ProRdSectTr(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
778{
779    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
780    uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
781                index = PH_FRINFC_MFSTD_FMT_VAL_1,
782                SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
783    uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
784
785    /* Calculate sector index */
786    SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
787
788    /* Depending on the sector trailer, check the access bit */
789    memcompare = phFriNfc_MfStd_H_ChkAcsBit(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock,
790                                            NdefSmtCrdFmt->SendRecvBuf,
791                                            NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_AccessBits,
792                                            NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_AccessBits);
793
794    /* Check the sector for ndef compliance */
795    NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
796                ((memcompare != PH_FRINFC_MFSTD_FMT_VAL_0)?
797                PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
798                PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
799
800    /* Increment the current block */
801    PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
802    SectIndex++;
803    if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
804    {
805       PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
806    }
807    else
808    {
809        /* Set the state */
810        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
811        /* Set the authenticate state */
812        NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
813                            PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
814        /* Start authentication */
815        Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
816    }
817    return Result;
818}
819
820static NFCSTATUS phFriNfc_MfStd_H_ProWrSectTr(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
821{
822    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
823    uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
824                index = PH_FRINFC_MFSTD_FMT_VAL_1,
825                SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
826    uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
827
828    /* Calculate sector index */
829    SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
830
831    /* Sector is ndef compliance */
832    NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
833                    ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
834                        PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
835                        PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
836
837    /* Increment the current block */
838    PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
839    SectIndex++;
840    if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
841    {
842        PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
843    }
844    else
845    {
846        /* Set the state */
847        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
848        /* Set the authenticate state */
849        NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
850                            PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
851        /* Start authentication */
852        Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
853    }
854    return Result;
855}
856
857static uint32_t phFriNfc_MfStd_H_ChkAcsBit(uint16_t                 BlockNo,
858                                           const uint8_t            *RecvBuf,
859                                           const uint8_t            AcsBits1[],
860                                           const uint8_t            AcsBits2[])
861{
862    uint32_t    mem = PH_FRINFC_MFSTD_FMT_VAL_0;
863
864    /* Compare the access bits read from the sector trailer */
865    mem = (uint32_t)(((BlockNo == PH_FRINFC_MFSTD_FMT_VAL_3) ||
866                    (BlockNo == 67))?
867                    phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
868                            (void*)AcsBits1,
869                            PH_FRINFC_MFSTD_FMT_VAL_3):
870                    phFriNfc_MfStd_MemCompare((void*)&RecvBuf[PH_FRINFC_MFSTD_FMT_VAL_6],
871                            (void*)AcsBits2,
872                            PH_FRINFC_MFSTD_FMT_VAL_3));
873
874    return mem;
875}
876
877static NFCSTATUS phFriNfc_MfStd_H_WrRdAuth(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
878{
879    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
880    /* Fill send buffer and send length */
881    phFriNfc_MfStd_H_FillSendBuf(NdefSmtCrdFmt,
882                                 NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock);
883    /* Call ovrhal transceive */
884    Result = phFriNfc_MfStd_H_Transceive(NdefSmtCrdFmt);
885
886    return Result;
887}
888
889static void phFriNfc_MfStd_H_ChangeAuthSt(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
890{
891    uint8_t     SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
892
893    if( NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
894        PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)
895    {
896        /* Calculate sector index */
897        SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
898
899        /* Check the sector for ndef compliance */
900        NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] =
901                    PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL;
902
903        PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
904    }
905    PH_FRINFC_MFSTD_FMT_NXT_AUTH_STATE();
906}
907
908static void phFriNfc_MfStd_H_NdefComplSect(uint8_t      CardTypes,
909                                           uint8_t      Sector[])
910{
911    uint8_t     count = PH_FRINFC_MFSTD_FMT_VAL_0,
912                NdefComplSectMax = PH_FRINFC_MFSTD_FMT_VAL_0,
913                NdefComplSectTemp = PH_FRINFC_MFSTD_FMT_VAL_1,
914                SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0,
915                MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0,
916                MaxSect = PH_FRINFC_MFSTD_FMT_VAL_0;
917
918    /* Get the maximum sector depending on the sector */
919    MaxSect = ((CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)?
920                PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K:
921                PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
922    /* Sector index */
923    NdefComplSectTemp = SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1;
924    /* Check the sector index depending on the card type */
925    while(((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
926        (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
927        ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
928        (CardTypes == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
929    {
930        if (Sector[SectIndex] ==
931            PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL)
932        {
933            if (MaxCont > count)
934            {
935                /* Store the maximum contiguous */
936                NdefComplSectMax = NdefComplSectTemp;
937                count = MaxCont;
938            }
939            MaxCont = PH_FRINFC_MFSTD_FMT_VAL_0;
940            /* Increment the sector index */
941            PH_FRINFC_MFSTD_FMT_INCR_SECT;
942            /* Get the next compliant sector */
943            NdefComplSectTemp = SectIndex;
944        }
945        else
946        {
947            /* Increment the sector index */
948            PH_FRINFC_MFSTD_FMT_INCR_SECT;
949        }
950        MaxCont ++;
951
952    }
953    if (MaxCont > count)
954    {
955        /* Store the maximum contiguous */
956        NdefComplSectMax = NdefComplSectTemp;
957        count = MaxCont;
958    }
959    /* Set the sector value has non ndef compliant which are not present with
960    contiguous ndef compliant sectors */
961    if((((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_1)) && (CardTypes
962        == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)) ||
963        ((count < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2)) && (CardTypes
964        == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD))) &&
965        ((NdefComplSectMax > PH_FRINFC_MFSTD_FMT_VAL_0) &&
966        (NdefComplSectMax < (MaxSect - PH_FRINFC_MFSTD_FMT_VAL_2))))
967    {
968        (void)memset(&Sector[PH_FRINFC_MFSTD_FMT_VAL_1],
969            PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
970            (NdefComplSectMax - PH_FRINFC_MFSTD_FMT_VAL_1));
971
972        (void)memset(&Sector[(NdefComplSectMax + count)],
973            PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
974            (MaxSect - (NdefComplSectMax + count)));
975    }
976}
977
978
979static NFCSTATUS phFriNfc_MfStd_H_ProWrMADBlk(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
980{
981    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
982
983    switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock)
984    {
985    case PH_FRINFC_MFSTD_FMT_VAL_1:
986        /* MAD blocks, still not completed */
987        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
988        /* MAD block number 2 */
989        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
990                            PH_FRINFC_MFSTD_FMT_VAL_2;
991        break;
992
993    case PH_FRINFC_MFSTD_FMT_VAL_2:
994        /* Now write to MAD block is completed */
995        NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
996                                        PH_FRINFC_MFSTD_FMT_VAL_1;
997        /* Now write the sector trailer, so change the state */
998        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
999        /* MAD block number 3 = Sector trailer */
1000        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1001                            PH_FRINFC_MFSTD_FMT_VAL_3;
1002        break;
1003
1004    case 64:
1005        /* MAD blocks, still not completed */
1006        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
1007        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 65;
1008        break;
1009
1010    case 65:
1011        /* MAD blocks, still not completed */
1012        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_MAD_BLK;
1013        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 66;
1014        break;
1015
1016    case 66:
1017    default:
1018        /* Now write to MAD block is completed */
1019        NdefSmtCrdFmt->AddInfo.MfStdInfo.WrMADBlkFlag =
1020                                        PH_FRINFC_MFSTD_FMT_VAL_1;
1021        /* Now write the sector trailer, so change the state */
1022        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_WR_SECT_TR;
1023        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = 67;
1024        break;
1025
1026    }
1027    /* Write the block */
1028    Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1029
1030    return Result;
1031}
1032
1033static NFCSTATUS phFriNfc_MfStd_H_ProErrAuth( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1034{
1035    NFCSTATUS   Result = NdefSmtCrdFmt->FmtProcStatus;
1036    uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
1037                index = PH_FRINFC_MFSTD_FMT_VAL_1;
1038    uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
1039
1040    if ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock == 67) &&
1041        (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
1042                    PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB))
1043    {
1044        /* Error in the MAD sector 16, so the remaining sector
1045        information cant be updated */
1046        (void)memset(&NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[16],
1047                    PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
1048                    (PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K - 16));
1049        PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
1050    }
1051    else if(((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >
1052        PH_FRINFC_MFSTD_FMT_VAL_3) &&
1053        (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState !=
1054        PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)) ||
1055        ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
1056        PH_FRINFC_MFSTD_FMT_VAL_3) &&
1057        (NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState <
1058        PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB)))
1059    {
1060        /* Authenticate failed, so disconnect, poll and connect */
1061        Result = phFriNfc_MfStd_H_CallDisCon(NdefSmtCrdFmt,
1062                                             Result);
1063    }
1064    else
1065    {
1066        if (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
1067            PH_FRINFC_MFSTD_FMT_VAL_3)
1068        {
1069            (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl,
1070                        PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL,
1071                        PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
1072        }
1073    }
1074
1075    return Result;
1076}
1077
1078static NFCSTATUS phFriNfc_MfStd_H_ProUpdMADBlk(phFriNfc_sNdefSmtCrdFmt_t    *NdefSmtCrdFmt)
1079{
1080    NFCSTATUS   Result = NFCSTATUS_SUCCESS;
1081    switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk)
1082    {
1083    case PH_FRINFC_MFSTD_FMT_MAD_BLK_1:
1084        /* Write the next MAD Block */
1085        NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1086                                PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
1087        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1088                                PH_FRINFC_MFSTD_FMT_MAD_BLK_2;
1089        break;
1090
1091    case PH_FRINFC_MFSTD_FMT_MAD_BLK_2:
1092    case PH_FRINFC_MFSTD_FMT_MAD_BLK_66:
1093        if((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) ||
1094           (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock ==
1095           PH_FRINFC_MFSTD_FMT_MAD_BLK_66))
1096        {
1097            /* Get the block from where the TLV has to be written */
1098            phFriNfc_MfStd_H_BlkNoToWrTLV(NdefSmtCrdFmt);
1099
1100            NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1101            NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
1102                                    PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY;
1103        }
1104        else
1105        {
1106            /* Write the next MAD Block */
1107            NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1108                            PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
1109                NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1110                            PH_FRINFC_MFSTD_FMT_MAD_BLK_64;
1111            NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1112            NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
1113                                PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB;
1114        }
1115        break;
1116
1117    case PH_FRINFC_MFSTD_FMT_MAD_BLK_64:
1118        /* Write the next MAD Block */
1119        NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1120                                PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
1121        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1122                                PH_FRINFC_MFSTD_FMT_MAD_BLK_65;
1123        break;
1124
1125    case PH_FRINFC_MFSTD_FMT_MAD_BLK_65:
1126    default:
1127        /* Write the next MAD Block */
1128        NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = (uint8_t)
1129                                    PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
1130        NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock =
1131                                    PH_FRINFC_MFSTD_FMT_MAD_BLK_66;
1132        break;
1133    }
1134    Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1135    return Result;
1136}
1137
1138static void phFriNfc_MfStd_H_StrNdefData( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1139{
1140    uint8_t     SectIndex = PH_FRINFC_MFSTD_FMT_VAL_1,
1141                index = PH_FRINFC_MFSTD_FMT_VAL_0;
1142
1143    (void)memset(NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk,
1144                0x00,
1145                PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K);
1146
1147    /* Zeroth sector of the Mifare card is MAD sector, CRC is 0x14 */
1148    NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_0] = 0x14;
1149    /* Info byte is 0x01, because the NDEF application is written and as per the MAD spec,
1150    the value for miscellaneous application is 0x01 */
1151    NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[PH_FRINFC_MFSTD_FMT_VAL_1] = 0x01;
1152
1153    if(NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)
1154    {
1155        /* If 4k card then sector number 16 is MAD sector, CRC is 0xE8 */
1156        NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[32] = 0xE8;
1157        /* Info byte is 0x01, because the NDEF application is written and
1158            as per the MAD spec,
1159        the value for miscellaneous application is 0x01 */
1160        NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[33] = 0x01;
1161    }
1162    /* NDEF information has to be updated from */
1163    index = PH_FRINFC_MFSTD_FMT_VAL_2;
1164    /* Depending on the card type, check the sector index */
1165    while (((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
1166        (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
1167        ((SectIndex < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
1168        (NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
1169    {
1170        /* Is the sector ndef compliant? */
1171        if(NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
1172            PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
1173        {
1174            /* Ndef compliant sector, update the MAD sector array
1175                in the context with values 0x03 and 0xE1
1176                0x03 and 0xE1 is NDEF information in MAD sector */
1177            NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
1178                                        PH_FRINFC_MFSTD_FMT_NDEF_INFO1;
1179            index++;
1180            NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] =
1181                                        PH_FRINFC_MFSTD_FMT_NDEF_INFO2;
1182            index++;
1183        }
1184        else
1185        {
1186            /* Not a Ndef compliant sector, update the MAD sector array
1187                in the context with values 0x00 and 0x00
1188                0x00 and 0x00 is NDEF information in MAD sector */
1189            NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
1190            index++;
1191            NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSectBlk[index] = 0x00;
1192            index++;
1193        }
1194        /* Go to next sector */
1195        SectIndex++;
1196        /* is the sector, a MAD sector 16? */
1197        if(SectIndex == PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K)
1198        {
1199            /* MAD sector number 16, so skip this sector */
1200            SectIndex = SectIndex + PH_FRINFC_MFSTD_FMT_VAL_1;
1201            index = index + PH_FRINFC_MFSTD_FMT_VAL_2;
1202        }
1203    }
1204}
1205
1206static void phFriNfc_MfStd_H_BlkNoToWrTLV( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1207{
1208    uint8_t     SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_1;
1209    while (((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) &&
1210        (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)) ||
1211        ((SectIndex < (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K) &&
1212        (NdefSmtCrdFmt->CardType == (uint8_t)PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD)))
1213    {
1214        if (NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] ==
1215            (uint8_t)PH_FRINFC_MFSTD_FMT_NDEF_COMPL)
1216        {
1217            /* Get the first NFC forum sector's block */
1218            NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = (uint16_t)
1219                                          (((SectIndex & 0xE0) >= 32)?
1220                                        (128 + ((SectIndex % 32) * 16)):
1221                                        (SectIndex * (uint8_t)PH_FRINFC_MFSTD_FMT_VAL_4));
1222            /* Break out of the loop */
1223            SectIndex += (uint8_t)PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K;
1224        }
1225        SectIndex++;
1226    }
1227}
1228
1229static NFCSTATUS phFriNfc_MfStd_H_ErrRdSectTr( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt )
1230{
1231    NFCSTATUS   Result = NdefSmtCrdFmt->FmtProcStatus;
1232    uint8_t     Buffer[1] = {PH_FRINFC_MFSTD_FMT_NDEF_COMPL},
1233                index = PH_FRINFC_MFSTD_FMT_VAL_1,
1234                SectIndex = PH_FRINFC_MFSTD_FMT_VAL_0;
1235    uint32_t    memcompare = PH_FRINFC_MFSTD_FMT_VAL_1;
1236    /* If default key A is used for authentication and if write fails, then try to
1237    authenticate using key B*/
1238    if(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState ==
1239        PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)
1240    {
1241        /* Change the state to authentication */
1242        NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1243        /* internal authenticate state = key B */
1244        NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = PH_FRINFC_MFSTD_FMT_AUTH_KEYB;
1245        /* Now call authenticate */
1246        Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1247    }
1248    else
1249    {
1250        /* Calculate sector index */
1251        SectIndex = (uint8_t)PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC;
1252
1253        /* Sector is ndef compliance */
1254        NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[SectIndex] = (uint8_t)
1255                            ((NdefSmtCrdFmt->FmtProcStatus != NFCSTATUS_SUCCESS)?
1256                            PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL:
1257                            PH_FRINFC_MFSTD_FMT_NDEF_COMPL);
1258
1259        /* Increment the current block */
1260        PH_FRINFC_MFSTD_FMT_CUR_BLK_INC();
1261        SectIndex++;
1262        if(PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK)
1263        {
1264            PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD();
1265        }
1266        else
1267        {
1268            /* Set the state */
1269            NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT;
1270            /* Set the authenticate state */
1271            NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState =
1272                PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;
1273            /* Start authentication */
1274            Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt);
1275        }
1276    }
1277    return Result;
1278}
1279
1280static int phFriNfc_MfStd_MemCompare( void *s1, void *s2, unsigned int n )
1281{
1282    int8_t   diff = 0;
1283    int8_t *char_1  =(int8_t *)s1;
1284    int8_t *char_2  =(int8_t *)s2;
1285    if(NULL == s1 || NULL == s2)
1286    {
1287        PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare");
1288    }
1289    else
1290    {
1291        for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
1292        {
1293            diff = *char_1 - *char_2;
1294        }
1295    }
1296    return (int)diff;
1297}
1298
1299
1300
1301#ifdef UNIT_TEST
1302#include <phUnitTestNfc_MifStdFormat_static.c>
1303#endif
1304