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