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 */ 48 static 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 */ 55 static 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 */ 61 static 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 */ 68 static 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 */ 75 static 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 */ 82 static 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 */ 88 static 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 */ 94 static 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 */ 100 static 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 */ 106 static 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 */ 112 static 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 */ 121 static 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 */ 127 static 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 */ 134 static 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 */ 140 static 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 */ 146 static 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 */ 152 static 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 */ 158 static 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 */ 164 static 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 */ 170 static void phFriNfc_MfStd_H_BlkNoToWrTLV(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 171 172 static int phFriNfc_MfStd_MemCompare ( void *s1, void *s2, unsigned int n ); 173 174 175 void 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 218 NFCSTATUS 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 246 void 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 328 static 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 518 static 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 546 static 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 570 static 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 595 static 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 619 static 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 641 static 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 756 static 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 } 777 static 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 820 static 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 857 static 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 877 static 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 889 static 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 908 static 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 979 static 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 1033 static 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 1078 static 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 1138 static 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 1206 static 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 1229 static 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 1280 static 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