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_MifULFormat.c 19 * \brief NFC Ndef Formatting For Mifare ultralight card. 20 * 21 * Project: NFC-FRI 22 * 23 * $Date: Mon Dec 13 14:14:12 2010 $ 24 * $Author: ing02260 $ 25 * $Revision: 1.9 $ 26 * $Aliases: $ 27 * 28 */ 29 30 #include <phFriNfc_MifULFormat.h> 31 #include <phFriNfc_OvrHal.h> 32 33 /*! \ingroup grp_file_attributes 34 * \name NDEF Mapping 35 * 36 * File: \ref phFriNfc_MifULFormat.c 37 * 38 */ 39 /*@{*/ 40 #define PHFRINFCMIFULFORMAT_FILEREVISION "$Revision: 1.9 $" 41 #define PHFRINFCMIFULFORMAT_FILEALIASES "$Aliases: $" 42 /*@}*/ 43 44 #ifdef FRINFC_READONLY_NDEF 45 /* Mifare UL OTP block number is 3 */ 46 #define RD_LOCK_OTP_BLOCK_NUMBER 0x02U 47 #define OTP_BLOCK_NUMBER 0x03U 48 /* READ ONLY value that shall be written in the OTP to make the card read only */ 49 #define READ_ONLY_VALUE_IN_OTP 0x0FU 50 /* Mifare UL OTP block number is 3 */ 51 #define MIFARE_UL_READ_MAX_SIZE 16U 52 /* 1st Lock byte value */ 53 #define MIFARE_UL_LOCK_BYTE1_VALUE 0xF8U 54 /* 2nd Lock byte value */ 55 #define MIFARE_UL_LOCK_BYTE2_VALUE 0xFFU 56 /* Mifare ULC dynamic lock byte address */ 57 #define MIFARE_ULC_DYNAMIC_LOCK_BYTES_ADDR 0x28U 58 /* Type 2 STATIC CARD memory value in the OTP */ 59 #define TYPE_2_STATIC_MEM_SIZE_VALUE 0x06U 60 /* Type 2 DYNAMIC CARD memory value in the OTP */ 61 #define TYPE_2_DYNAMIC_MEM_SIZE_VALUE 0x12U 62 /* Lock byte 3 value to be ORed with the existing value */ 63 #define MIFARE_UL_LOCK_BYTE3_VALUE 0xEEU 64 /* Posiiton of the memory information in the stored OTP bytes */ 65 #define TYPE_2_MEM_SIZE_POSITION 0x02U 66 /* 3rd Lock byte position after reading the block number 0x28 */ 67 #define TYPE_2_LOCK_BYTE3_POS_RD_BLK28 0x00U 68 69 #ifdef PH_NDEF_MIFARE_ULC 70 71 /* Lock control TLVs, TYPE identifier */ 72 #define LOCK_CTRL_TYPE_IN_TLV 0x01U 73 /* Lock control TLVs, Length expected */ 74 #define LOCK_CTRL_LEN_IN_TLV 0x03U 75 76 /* NDEF message TLVs, TYPE identifier */ 77 #define NDEF_TYPE_IN_TLV 0x03U 78 79 #define MFUL_NULL_TLV 0x00U 80 #define THREE_BYTE_LENGTH_FIELD 0xFFU 81 #define TERMINATOR_TLV 0xFEU 82 #define MIFARE_ULC_SIZE 0xC0U 83 #define MFUL_NIBBLE_SIZE 0x04U 84 #define MFUL_NIBBLE_MASK 0x0FU 85 #define MFUL_BYTE_SIZE_IN_BITS 0x08U 86 #define MFUL_BLOCK_SIZE_IN_BYTES 0x04U 87 /* Initial (0 to 3 blocks) 4 blocks are ignored, i.e., 16 bytes */ 88 #define MFUL_INITIAL_BYTES_IGNORED 0x10U 89 90 #define MFUL_CONVERT_BITS_TO_BYTES(bits_to_bytes) \ 91 (((bits_to_bytes % MFUL_BYTE_SIZE_IN_BITS) > 0) ? \ 92 ((bits_to_bytes / MFUL_BYTE_SIZE_IN_BITS) + 1) : \ 93 (bits_to_bytes / MFUL_BYTE_SIZE_IN_BITS)) 94 95 typedef enum phFriNfc_MfUL_Parse 96 { 97 LOCK_TLV_T, 98 LOCK_TLV_L, 99 LOCK_TLV_V, 100 NDEF_TLV_T, 101 NDEF_TLV_L, 102 NDEF_TLV_V 103 }phFriNfc_MfUL_Parse_t; 104 105 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 106 107 #endif /* #ifdef FRINFC_READONLY_NDEF */ 108 /*! 109 * \brief \copydoc page_ovr Helper function for Mifare UL. This function calls the 110 * transceive function 111 */ 112 static NFCSTATUS phFriNfc_MfUL_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 113 114 /*! 115 * \brief \copydoc page_ovr Helper function for Mifare UL. This function calls the 116 * read or write operation 117 */ 118 static NFCSTATUS phFriNfc_MfUL_H_WrRd(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 119 120 /*! 121 * \brief \copydoc page_ovr Helper function for Mifare UL. This function fills the 122 * send buffer for transceive function 123 */ 124 static void phFriNfc_MfUL_H_fillSendBuf(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, 125 uint8_t BlockNo); 126 127 /*! 128 * \brief \copydoc page_ovr Helper function for Mifare UL. This function shall process 129 * the read bytes 130 */ 131 static NFCSTATUS phFriNfc_MfUL_H_ProRd16Bytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 132 133 /*! 134 * \brief \copydoc page_ovr Helper function for Mifare UL. This function shall process the 135 * OTP bytes written 136 */ 137 static NFCSTATUS phFriNfc_MfUL_H_ProWrOTPBytes(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 138 139 #ifdef FRINFC_READONLY_NDEF 140 141 #ifdef PH_NDEF_MIFARE_ULC 142 143 static 144 NFCSTATUS 145 phFriNfc_MfUL_ParseTLVs ( 146 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, 147 uint8_t *data_to_parse, 148 uint8_t size_to_parse); 149 150 static 151 NFCSTATUS 152 phFriNfc_MfUL_GetLockBytesInfo ( 153 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 154 155 static 156 NFCSTATUS 157 phFriNfc_MfUL_GetDefaultLockBytesInfo ( 158 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 159 160 static 161 uint8_t 162 phFriNfc_MfUL_GetSkipSize ( 163 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, 164 uint8_t block_number, 165 uint8_t byte_number); 166 167 static 168 NFCSTATUS 169 phFriNfc_MfUL_ReadWriteLockBytes ( 170 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 171 172 static 173 NFCSTATUS 174 phFriNfc_MfUL_UpdateAndWriteLockBits ( 175 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 176 177 static 178 uint8_t 179 phFriNfc_MfUL_CalcRemainingLockBits ( 180 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt); 181 182 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 183 184 #endif /* #ifdef FRINFC_READONLY_NDEF */ 185 186 static int MemCompare1 ( void *s1, void *s2, unsigned int n ); 187 /*The function does a comparision of two strings and returns a non zero value 188 if two strings are unequal*/ 189 static int MemCompare1 ( void *s1, void *s2, unsigned int n ) 190 { 191 int8_t diff = 0; 192 int8_t *char_1 =(int8_t *)s1; 193 int8_t *char_2 =(int8_t *)s2; 194 if(NULL == s1 || NULL == s2) 195 { 196 PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare"); 197 } 198 else 199 { 200 for(;((n>0)&&(diff==0));n--,char_1++,char_2++) 201 { 202 diff = *char_1 - *char_2; 203 } 204 } 205 return (int)diff; 206 } 207 208 void phFriNfc_MfUL_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 209 { 210 uint8_t OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES; 211 212 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0; 213 (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 214 OTPByte, 215 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); 216 #ifdef FRINFC_READONLY_NDEF 217 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[0] = 0; 218 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[1] = 0; 219 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] = 0; 220 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[3] = 0; 221 #endif /* #ifdef FRINFC_READONLY_NDEF */ 222 } 223 224 NFCSTATUS phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 225 { 226 NFCSTATUS Result = NFCSTATUS_SUCCESS; 227 uint8_t OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES; 228 229 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0; 230 (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 231 OTPByte, 232 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); 233 234 /* Set the state */ 235 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RD_16BYTES; 236 /* Initialise current block to the lock bits block */ 237 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_2; 238 239 /* Start authentication */ 240 Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt); 241 return Result; 242 } 243 244 #ifdef FRINFC_READONLY_NDEF 245 246 NFCSTATUS 247 phFriNfc_MfUL_ConvertToReadOnly ( 248 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 249 { 250 NFCSTATUS result = NFCSTATUS_SUCCESS; 251 252 NdefSmtCrdFmt->AddInfo.Type2Info.DefaultLockBytesFlag = TRUE; 253 NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = 0; 254 255 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_RD_16BYTES; 256 257 result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 258 259 return result; 260 } 261 262 #endif /* #ifdef FRINFC_READONLY_NDEF */ 263 264 void phFriNfc_MfUL_Process(void *Context, 265 NFCSTATUS Status) 266 { 267 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context; 268 269 if(Status == NFCSTATUS_SUCCESS) 270 { 271 switch(NdefSmtCrdFmt->State) 272 { 273 case PH_FRINFC_MFUL_FMT_RD_16BYTES: 274 Status = phFriNfc_MfUL_H_ProRd16Bytes(NdefSmtCrdFmt); 275 break; 276 277 case PH_FRINFC_MFUL_FMT_WR_OTPBYTES: 278 Status = phFriNfc_MfUL_H_ProWrOTPBytes(NdefSmtCrdFmt); 279 break; 280 281 case PH_FRINFC_MFUL_FMT_WR_TLV: 282 #ifdef PH_NDEF_MIFARE_ULC 283 if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) 284 { 285 /* Write NDEF TLV in block number 5 */ 286 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 287 PH_FRINFC_MFUL_FMT_VAL_5; 288 /* Card already have the OTP bytes so write TLV */ 289 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV1; 290 291 Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 292 } 293 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 294 295 break; 296 297 #ifdef FRINFC_READONLY_NDEF 298 299 case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES: 300 { 301 if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength) 302 { 303 uint8_t otp_lock_page_size = 0; 304 uint8_t i = 0; 305 306 otp_lock_page_size = sizeof (NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes); 307 (void)memcpy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes, 308 (void *)NdefSmtCrdFmt->SendRecvBuf, 309 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes)); 310 311 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] = (uint8_t) 312 (NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] 313 | MIFARE_UL_LOCK_BYTE1_VALUE); 314 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[3] = MIFARE_UL_LOCK_BYTE2_VALUE; 315 i = (uint8_t)(i + otp_lock_page_size); 316 317 otp_lock_page_size = sizeof (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes); 318 319 (void)memcpy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 320 (void *)(NdefSmtCrdFmt->SendRecvBuf + i), 321 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); 322 323 NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[(otp_lock_page_size - 1)] = 324 READ_ONLY_VALUE_IN_OTP; 325 326 switch (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION]) 327 { 328 case TYPE_2_STATIC_MEM_SIZE_VALUE: 329 { 330 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES; 331 Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 332 break; 333 } 334 335 #ifdef PH_NDEF_MIFARE_ULC 336 case TYPE_2_DYNAMIC_MEM_SIZE_VALUE: 337 { 338 NdefSmtCrdFmt->State = 339 PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES; 340 341 /* Start reading from block 4 */ 342 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 4; 343 Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 344 break; 345 } 346 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 347 348 default: 349 { 350 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 351 NFCSTATUS_INVALID_DEVICE_REQUEST); 352 break; 353 } 354 } 355 } 356 else 357 { 358 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 359 NFCSTATUS_INVALID_RECEIVE_LENGTH); 360 } 361 break; 362 } 363 364 case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES: 365 { 366 switch (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION]) 367 { 368 case TYPE_2_STATIC_MEM_SIZE_VALUE: 369 #ifdef PH_NDEF_MIFARE_ULC 370 case TYPE_2_DYNAMIC_MEM_SIZE_VALUE: 371 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 372 { 373 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES; 374 Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 375 break; 376 } 377 378 default: 379 { 380 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 381 NFCSTATUS_INVALID_DEVICE_REQUEST); 382 break; 383 } 384 } 385 break; 386 } 387 388 #ifdef PH_NDEF_MIFARE_ULC 389 390 case PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES: 391 { 392 if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength) 393 { 394 Status = phFriNfc_MfUL_ParseTLVs (NdefSmtCrdFmt, 395 NdefSmtCrdFmt->SendRecvBuf, 396 (uint8_t)*NdefSmtCrdFmt->SendRecvLength); 397 398 if (!Status) 399 { 400 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 401 NdefSmtCrdFmt->AddInfo.Type2Info.LockBlockNumber; 402 Status = phFriNfc_MfUL_ReadWriteLockBytes (NdefSmtCrdFmt); 403 } 404 } 405 else 406 { 407 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 408 NFCSTATUS_INVALID_RECEIVE_LENGTH); 409 } 410 break; 411 } 412 413 case PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES: 414 { 415 if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength) 416 { 417 (void)memcpy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.ReadData, 418 (void *)NdefSmtCrdFmt->SendRecvBuf, 419 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.ReadData)); 420 421 NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = 0; 422 423 Status = phFriNfc_MfUL_UpdateAndWriteLockBits (NdefSmtCrdFmt); 424 425 } 426 else 427 { 428 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 429 NFCSTATUS_INVALID_RECEIVE_LENGTH); 430 } 431 break; 432 } 433 434 case PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES: 435 { 436 NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = (uint8_t) 437 (NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex + 438 MFUL_BLOCK_SIZE_IN_BYTES); 439 440 if (!phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt)) 441 { 442 /* There is no lock bits to write, then write OTP bytes */ 443 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES; 444 Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 445 } 446 else if ((NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex < 447 MIFARE_UL_READ_MAX_SIZE) 448 && (phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt))) 449 { 450 /* If remaining lock bits has to be written and the data is already read */ 451 Status = phFriNfc_MfUL_UpdateAndWriteLockBits (NdefSmtCrdFmt); 452 } 453 else 454 { 455 /* Increment current block by 4 because if a data is read then 16 456 bytes will be given which is 4 blocks */ 457 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = (uint8_t) 458 (NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock + 4); 459 Status = phFriNfc_MfUL_ReadWriteLockBytes (NdefSmtCrdFmt); 460 } 461 break; 462 } 463 464 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 465 466 case PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES: 467 { 468 /* Do nothing */ 469 break; 470 } 471 472 #endif /* #ifdef FRINFC_READONLY_NDEF */ 473 474 #ifdef PH_NDEF_MIFARE_ULC 475 case PH_FRINFC_MFUL_FMT_WR_TLV1: 476 477 break; 478 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 479 480 default: 481 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 482 NFCSTATUS_INVALID_DEVICE_REQUEST); 483 break; 484 } 485 } 486 /* Status is not success then call completion routine */ 487 if(Status != NFCSTATUS_PENDING) 488 { 489 phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status); 490 } 491 } 492 493 #ifdef FRINFC_READONLY_NDEF 494 495 #ifdef PH_NDEF_MIFARE_ULC 496 497 static 498 uint8_t 499 phFriNfc_MfUL_GetSkipSize ( 500 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, 501 uint8_t block_number, 502 uint8_t byte_number) 503 { 504 uint8_t skip_size = 0; 505 phFriNfc_Type2_AddInfo_t *ps_type2_info = 506 &NdefSmtCrdFmt->AddInfo.Type2Info; 507 508 /* This check is added, because the default lock bits is always 509 present after the DATA AREA. 510 So, default lock bytes doesnt have any skip size */ 511 if (!ps_type2_info->DefaultLockBytesFlag) 512 { 513 /* Only check for the lock control TLV */ 514 if ((block_number == ps_type2_info->LockBlockNumber) 515 && (byte_number == ps_type2_info->LockByteNumber)) 516 { 517 skip_size = MFUL_CONVERT_BITS_TO_BYTES(ps_type2_info->NoOfLockBits); 518 } 519 } 520 521 return skip_size; 522 } 523 524 static 525 NFCSTATUS 526 phFriNfc_MfUL_GetLockBytesInfo ( 527 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 528 { 529 NFCSTATUS result = NFCSTATUS_SUCCESS; 530 phFriNfc_Type2_AddInfo_t *ps_type2_info = 531 &(NdefSmtCrdFmt->AddInfo.Type2Info); 532 uint8_t page_address = 0; 533 uint8_t bytes_offset = 0; 534 uint8_t lock_index = 0; 535 536 537 page_address = (uint8_t)(ps_type2_info->DynLockBytes[lock_index] >> MFUL_NIBBLE_SIZE); 538 bytes_offset = (uint8_t)(ps_type2_info->DynLockBytes[lock_index] & MFUL_NIBBLE_MASK); 539 540 lock_index = (lock_index + 1); 541 ps_type2_info->NoOfLockBits = ps_type2_info->DynLockBytes[lock_index]; 542 543 lock_index = (lock_index + 1); 544 ps_type2_info->LockBytesPerPage = 545 (ps_type2_info->DynLockBytes[lock_index] & MFUL_NIBBLE_MASK); 546 ps_type2_info->BytesLockedPerLockBit = 547 (ps_type2_info->DynLockBytes[lock_index] >> MFUL_NIBBLE_SIZE); 548 549 /* Apply the formula to calculate byte address 550 ByteAddr = ((PageAddr * (2 ^ BytesPerPage)) + ByteOffset) 551 */ 552 ps_type2_info->LockByteNumber = (uint8_t)((page_address 553 * (1 << ps_type2_info->LockBytesPerPage)) 554 + bytes_offset); 555 556 ps_type2_info->LockBlockNumber = (uint8_t)(ps_type2_info->LockByteNumber / 557 MFUL_BLOCK_SIZE_IN_BYTES); 558 ps_type2_info->LockByteNumber = (uint8_t)(ps_type2_info->LockByteNumber % 559 MFUL_BLOCK_SIZE_IN_BYTES); 560 561 #if 0 562 if ( 563 /* Out of bound memory check */ 564 ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size) > 565 (uint16_t)(psNdefMap->TopazContainer.CCByteBuf[2] * 566 TOPAZ_BYTES_PER_BLOCK)) || 567 568 /* Check the static lock and reserved areas memory blocks */ 569 ((ps_locktlv_info->ByteAddr >= TOPAZ_STATIC_LOCK_RES_START) && 570 (ps_locktlv_info->ByteAddr < TOPAZ_STATIC_LOCK_RES_END)) || 571 (((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) >= 572 TOPAZ_STATIC_LOCK_RES_START) && 573 ((ps_locktlv_info->ByteAddr + ps_locktlv_info->Size - 1) < 574 TOPAZ_STATIC_LOCK_RES_END)) 575 ) 576 { 577 ps_locktlv_info->ByteAddr = 0; 578 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, 579 NFCSTATUS_NO_NDEF_SUPPORT); 580 } 581 else 582 { 583 ps_locktlv_info->BlkNum = (ps_locktlv_info->ByteAddr / 584 TOPAZ_BYTES_PER_BLOCK); 585 ps_locktlv_info->ByteNum = (ps_locktlv_info->ByteAddr % 586 TOPAZ_BYTES_PER_BLOCK); 587 } 588 #endif /* #if 0 */ 589 590 return result; 591 } 592 593 static 594 uint8_t 595 phFriNfc_MfUL_CalcRemainingLockBits ( 596 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 597 { 598 uint8_t lock_bits_remaining = 0; 599 phFriNfc_Type2_AddInfo_t *ps_type2_info = 600 &(NdefSmtCrdFmt->AddInfo.Type2Info); 601 602 lock_bits_remaining = (uint8_t)(ps_type2_info->NoOfLockBits - 603 ps_type2_info->LockBitsWritten); 604 605 return lock_bits_remaining; 606 } 607 608 static 609 NFCSTATUS 610 phFriNfc_MfUL_UpdateAndWriteLockBits ( 611 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 612 { 613 NFCSTATUS result = NFCSTATUS_SUCCESS; 614 phFriNfc_Type2_AddInfo_t *ps_type2_info = 615 &(NdefSmtCrdFmt->AddInfo.Type2Info); 616 uint8_t byte_index = 0; 617 uint8_t no_of_bits_left_in_block = 0; 618 uint8_t remaining_lock_bits = 0; 619 uint8_t remaining_lock_bytes = 0; 620 /* Array of 3 is used because the lock bits with 4 bytes in a block 621 is handled in the function phFriNfc_MfUL_ReadWriteLockBytes 622 So use this function only if lock bytes doesnt use the entire block */ 623 uint8_t lock_bytes_value[MFUL_BLOCK_SIZE_IN_BYTES] = {0}; 624 uint8_t lock_byte_index = 0; 625 626 (void)memcpy ((void *)lock_bytes_value, 627 (void*)(ps_type2_info->ReadData + ps_type2_info->ReadDataIndex), 628 sizeof (ps_type2_info->DynLockBytes)); 629 remaining_lock_bits = phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt); 630 631 if (ps_type2_info->CurrentBlock == ps_type2_info->LockBlockNumber) 632 { 633 /* 1st write to lock bits, so byte_index is updated */ 634 byte_index = ps_type2_info->LockByteNumber; 635 } 636 637 no_of_bits_left_in_block = (uint8_t)((MFUL_BLOCK_SIZE_IN_BYTES - byte_index) * 638 MFUL_BYTE_SIZE_IN_BITS); 639 640 if (no_of_bits_left_in_block >= remaining_lock_bits) 641 { 642 /* Entire lock bits can be written 643 if block size is more than number of lock bits. 644 so allocate the lock bits with value 1b and 645 dont change the remaining bits */ 646 if (remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS) 647 { 648 /* mod operation has resulted in a value, means lock bits ends in between a byte */ 649 uint8_t mod_value = 0; 650 651 remaining_lock_bytes = ((remaining_lock_bits / 652 MFUL_BYTE_SIZE_IN_BITS) + 1); 653 654 /* mod_value is used to fill the only partial bits and 655 remaining bits shall be untouched */ 656 mod_value = (uint8_t)(remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS); 657 if (remaining_lock_bits > MFUL_BYTE_SIZE_IN_BITS) 658 { 659 /* lock bits to write is greater than 8 bits */ 660 while (lock_byte_index < (remaining_lock_bytes - 1)) 661 { 662 /* Set 1b to all bits left in the block */ 663 lock_bytes_value[byte_index] = 0xFF; 664 lock_byte_index = (uint8_t)(lock_byte_index + 1); 665 byte_index = (uint8_t)(byte_index + 1); 666 } 667 /* Last byte of the lock bits shall be filled partially, 668 Set only the remaining lock bits and dont change 669 the other bit value */ 670 lock_bytes_value[byte_index] = 0; 671 lock_bytes_value[byte_index] = (uint8_t) 672 SET_BITS8 (lock_bytes_value[byte_index], 0, 673 mod_value, 1); 674 } 675 else 676 { 677 /* lock bits to write is less than 8 bits, so 678 there is only one byte to write. 679 Set only the remaining lock bits and dont change 680 the other bit value */ 681 lock_bytes_value[0] = (uint8_t)SET_BITS8 (lock_bytes_value[0], 0, 682 mod_value, 1); 683 } 684 } /* if (remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS) */ 685 else 686 { 687 /* MOD operation is 00, that means entire byte value shall be 0xFF, means 688 every bit shall be to 1 */ 689 remaining_lock_bytes = (remaining_lock_bits / 690 MFUL_BYTE_SIZE_IN_BITS); 691 692 while (lock_byte_index < remaining_lock_bytes) 693 { 694 /* Set 1b to all bits left in the block */ 695 lock_bytes_value[byte_index] = 0xFF; 696 lock_byte_index = (uint8_t)(lock_byte_index + 1); 697 byte_index = (uint8_t)(byte_index + 1); 698 } 699 } /* else of if (remaining_lock_bits % MFUL_BYTE_SIZE_IN_BITS) */ 700 ps_type2_info->LockBitsWritten = (uint8_t)(ps_type2_info->LockBitsWritten + 701 remaining_lock_bits); 702 } /* if (no_of_bits_left_in_block >= remaining_lock_bits) */ 703 else 704 { 705 /* Update till the left bits in the block and then carry 706 out next operation after this write */ 707 while (lock_byte_index < (no_of_bits_left_in_block / MFUL_BYTE_SIZE_IN_BITS)) 708 { 709 /* Set 1b to all bits left in the block */ 710 lock_bytes_value[byte_index] = 0xFF; 711 lock_byte_index = (uint8_t)(lock_byte_index + 1); 712 byte_index = (uint8_t)(byte_index + 1); 713 } 714 ps_type2_info->LockBitsWritten = (uint8_t)(ps_type2_info->LockBitsWritten + 715 no_of_bits_left_in_block); 716 } /* else of if (no_of_bits_left_in_block >= remaining_lock_bits) */ 717 718 719 /* Copy the values back to the DynLockBytes structure member */ 720 (void)memcpy ((void*)ps_type2_info->DynLockBytes, 721 (void *)lock_bytes_value, 722 sizeof (ps_type2_info->DynLockBytes)); 723 724 725 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES; 726 result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 727 728 return result; 729 } 730 731 static 732 NFCSTATUS 733 phFriNfc_MfUL_ReadWriteLockBytes ( 734 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 735 { 736 NFCSTATUS result = NFCSTATUS_SUCCESS; 737 phFriNfc_Type2_AddInfo_t *ps_type2_info = 738 &(NdefSmtCrdFmt->AddInfo.Type2Info); 739 uint8_t write_flag = FALSE; 740 741 if (/* Lock bytes starts from the beginning of the block */ 742 (0 == ps_type2_info->LockByteNumber) 743 /* To make sure this is the first read */ 744 && (ps_type2_info->CurrentBlock == ps_type2_info->LockBlockNumber) 745 /* Lock bytes are greater than or equal to the block size, i.e., 4 bytes */ 746 && (phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt) 747 >= (MFUL_BLOCK_SIZE_IN_BYTES * MFUL_BYTE_SIZE_IN_BITS))) 748 { 749 /* Then directly write the lock bytes, dont waste time for read */ 750 (void)memset ((void *)ps_type2_info->DynLockBytes, 0xFF, 751 sizeof (ps_type2_info->DynLockBytes)); 752 write_flag = TRUE; 753 } 754 else if (ps_type2_info->CurrentBlock == ps_type2_info->LockBlockNumber) 755 { 756 /* Read is mandatory, First read and then update the block, 757 because chances are there that lock byte may start in between 758 the block */ 759 } 760 else if (/* check if remaining bytes exceeds or same as the block size */ 761 (phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt) 762 >= (MFUL_BLOCK_SIZE_IN_BYTES * MFUL_BYTE_SIZE_IN_BITS))) 763 { 764 /* Then directly write the lock bytes, dont waste time for read */ 765 (void)memset ((void *)ps_type2_info->DynLockBytes, 0xFF, 766 sizeof (ps_type2_info->DynLockBytes)); 767 write_flag = TRUE; 768 } 769 else 770 { 771 /* Read is mandatory, First read and then update the block */ 772 } 773 774 if (write_flag) 775 { 776 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES; 777 result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 778 } 779 else 780 { 781 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES; 782 result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 783 } 784 785 return result; 786 } 787 788 static 789 NFCSTATUS 790 phFriNfc_MfUL_GetDefaultLockBytesInfo ( 791 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 792 { 793 NFCSTATUS result = NFCSTATUS_SUCCESS; 794 phFriNfc_Type2_AddInfo_t *ps_type2_info = 795 &(NdefSmtCrdFmt->AddInfo.Type2Info); 796 uint16_t lock_byte_start_addr = 0; 797 798 /* The position of the dynamic lock bits starts from 799 the first byte after the data area */ 800 lock_byte_start_addr = (uint16_t)(MFUL_INITIAL_BYTES_IGNORED + 801 (ps_type2_info->OTPBytes[TYPE_2_MEM_SIZE_POSITION] * 8)); 802 803 ps_type2_info->LockBlockNumber = (uint8_t)(lock_byte_start_addr / 804 MFUL_BLOCK_SIZE_IN_BYTES); 805 ps_type2_info->LockByteNumber = (uint8_t)(lock_byte_start_addr % 806 MFUL_BLOCK_SIZE_IN_BYTES); 807 /* Default settings 808 NoOfLockBits = [(DataAreaSize - 48)/8] */ 809 ps_type2_info->NoOfLockBits = (uint8_t) 810 (((ps_type2_info->OTPBytes[TYPE_2_MEM_SIZE_POSITION] * 8) - 48)/8); 811 812 return result; 813 } 814 815 static 816 NFCSTATUS 817 phFriNfc_MfUL_ParseTLVs ( 818 phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, 819 uint8_t *data_to_parse, 820 uint8_t size_to_parse) 821 { 822 NFCSTATUS result = NFCSTATUS_SUCCESS; 823 static uint8_t lock_mem_ndef_index = 0; 824 static uint8_t skip_lock_mem_size = 0; 825 static uint16_t card_size_remaining = 0; 826 static uint16_t ndef_data_size = 0; 827 static phFriNfc_MfUL_Parse_t parse_tlv = LOCK_TLV_T; 828 uint8_t parse_index = 0; 829 830 if ((0 == card_size_remaining) && (0 == parse_index)) 831 { 832 /* card size is calculated only once */ 833 card_size_remaining = (uint16_t) 834 (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION] * 8); 835 } 836 837 while ((parse_index < size_to_parse) 838 && (NFCSTATUS_SUCCESS == result) 839 && (NDEF_TLV_V != parse_tlv) 840 && (0 != card_size_remaining)) 841 { 842 if (0 == skip_lock_mem_size) 843 { 844 /* Skip the lock TLVs, so get the lock bits */ 845 skip_lock_mem_size = phFriNfc_MfUL_GetSkipSize (NdefSmtCrdFmt, 846 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock, 847 parse_index); 848 } 849 850 if (0 != skip_lock_mem_size) 851 { 852 if (skip_lock_mem_size >= (size_to_parse - parse_index)) 853 { 854 /* if skip size is more than the size to parse, then */ 855 card_size_remaining = (uint16_t)(card_size_remaining - 856 (size_to_parse - parse_index)); 857 skip_lock_mem_size = (uint8_t)(skip_lock_mem_size - 858 ((size_to_parse - parse_index))); 859 parse_index = size_to_parse; 860 } 861 else 862 { 863 card_size_remaining = (uint16_t)(card_size_remaining - 864 skip_lock_mem_size); 865 866 parse_index = (uint8_t)(parse_index + skip_lock_mem_size); 867 skip_lock_mem_size = 0; 868 } 869 } 870 else 871 { 872 switch (parse_tlv) 873 { 874 case LOCK_TLV_T: 875 { 876 switch (*(data_to_parse + parse_index)) 877 { 878 case MFUL_NULL_TLV: 879 { 880 /* Do nothing, parse further */ 881 break; 882 } 883 884 case LOCK_CTRL_TYPE_IN_TLV: 885 { 886 parse_tlv = LOCK_TLV_L; 887 break; 888 } 889 890 case NDEF_TYPE_IN_TLV: 891 { 892 parse_tlv = NDEF_TLV_L; 893 /* Default lock bytes shall be taken */ 894 NdefSmtCrdFmt->AddInfo.Type2Info.DefaultLockBytesFlag = 895 TRUE; 896 result = phFriNfc_MfUL_GetDefaultLockBytesInfo (NdefSmtCrdFmt); 897 break; 898 } 899 900 default: 901 { 902 parse_tlv = LOCK_TLV_T; 903 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 904 NFCSTATUS_NO_NDEF_SUPPORT); 905 break; 906 } 907 } 908 break; 909 } 910 911 case LOCK_TLV_L: 912 { 913 if (LOCK_CTRL_LEN_IN_TLV == *(data_to_parse + parse_index)) 914 { 915 parse_tlv = LOCK_TLV_V; 916 } 917 else 918 { 919 skip_lock_mem_size = 0; 920 parse_tlv = LOCK_TLV_T; 921 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 922 NFCSTATUS_NO_NDEF_SUPPORT); 923 } 924 break; 925 } 926 927 case LOCK_TLV_V: 928 { 929 switch (lock_mem_ndef_index) 930 { 931 case 0: 932 case 1: 933 { 934 NdefSmtCrdFmt->AddInfo.Type2Info.DefaultLockBytesFlag = 935 FALSE; 936 NdefSmtCrdFmt->AddInfo.Type2Info.DynLockBytes[lock_mem_ndef_index] = 937 *(data_to_parse + parse_index); 938 lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1); 939 break; 940 } 941 942 case 2: 943 { 944 NdefSmtCrdFmt->AddInfo.Type2Info.DynLockBytes[lock_mem_ndef_index] = 945 *(data_to_parse + parse_index); 946 parse_tlv = NDEF_TLV_T; 947 lock_mem_ndef_index = 0; 948 result = phFriNfc_MfUL_GetLockBytesInfo (NdefSmtCrdFmt); 949 break; 950 } 951 952 default: 953 { 954 skip_lock_mem_size = 0; 955 parse_tlv = LOCK_TLV_T; 956 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 957 NFCSTATUS_NO_NDEF_SUPPORT); 958 break; 959 } 960 } 961 break; 962 } /* switch (lock_mem_ndef_index) in case LOCK_TLV_V */ 963 964 case NDEF_TLV_T: 965 { 966 switch (*(data_to_parse + parse_index)) 967 { 968 case MFUL_NULL_TLV: 969 { 970 /* Do nothing, parse further */ 971 break; 972 } 973 974 case NDEF_TYPE_IN_TLV: 975 { 976 parse_tlv = NDEF_TLV_L; 977 break; 978 } 979 980 default: 981 { 982 skip_lock_mem_size = 0; 983 parse_tlv = LOCK_TLV_T; 984 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 985 NFCSTATUS_NO_NDEF_SUPPORT); 986 break; 987 } 988 } 989 break; 990 } /* switch (*(data_to_parse + parse_index)) in case NDEF_TLV_T */ 991 992 case NDEF_TLV_L: 993 { 994 switch (lock_mem_ndef_index) 995 { 996 case 0: 997 { 998 if (THREE_BYTE_LENGTH_FIELD == *(data_to_parse + parse_index)) 999 { 1000 lock_mem_ndef_index = (uint8_t)(lock_mem_ndef_index + 1); 1001 } 1002 else 1003 { 1004 ndef_data_size = *(data_to_parse + parse_index); 1005 parse_tlv = NDEF_TLV_V; 1006 lock_mem_ndef_index = 0; 1007 } 1008 break; 1009 } 1010 1011 case 1: 1012 { 1013 ndef_data_size = (uint16_t)(*(data_to_parse + parse_index) << 8); 1014 break; 1015 } 1016 1017 case 2: 1018 { 1019 ndef_data_size = (uint16_t)(ndef_data_size | 1020 *(data_to_parse + parse_index)); 1021 parse_tlv = NDEF_TLV_V; 1022 lock_mem_ndef_index = 0; 1023 break; 1024 } 1025 } /* switch (lock_mem_ndef_index) in case NDEF_TLV_L */ 1026 break; 1027 } 1028 1029 case NDEF_TLV_V: 1030 { 1031 break; 1032 } 1033 1034 default: 1035 { 1036 skip_lock_mem_size = 0; 1037 parse_tlv = LOCK_TLV_T; 1038 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 1039 NFCSTATUS_NO_NDEF_SUPPORT); 1040 break; 1041 } 1042 } /* switch (parse_tlv) */ 1043 1044 } /* else part of if (0 != skip_lock_mem_size) */ 1045 1046 if (0 == card_size_remaining) 1047 { 1048 skip_lock_mem_size = 0; 1049 parse_tlv = LOCK_TLV_T; 1050 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 1051 NFCSTATUS_NO_NDEF_SUPPORT); 1052 } 1053 else if (NDEF_TLV_V != parse_tlv) 1054 { 1055 /* Increment the index */ 1056 parse_index = (uint8_t)(parse_index + 1); 1057 /* card size is decremented as the memory area is parsed */ 1058 card_size_remaining = (uint16_t)(card_size_remaining - 1); 1059 } 1060 else 1061 { 1062 /* L field of the NDEF TLV 1063 L field can have 1 byte or also 3 bytes 1064 */ 1065 uint8_t length_to_deduct = 1; 1066 1067 if ((NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION] 1068 * 8) >= THREE_BYTE_LENGTH_FIELD) 1069 { 1070 length_to_deduct = 3; 1071 } 1072 /* parse_tlv has reached the VALUE field of the NDEF TLV */ 1073 if ((card_size_remaining - length_to_deduct) < ndef_data_size) 1074 { 1075 result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 1076 NFCSTATUS_NO_NDEF_SUPPORT); 1077 } 1078 1079 lock_mem_ndef_index = 0; 1080 skip_lock_mem_size = 0; 1081 card_size_remaining = 0; 1082 } 1083 } /* while ((parse_index < size_to_parse) 1084 && (NFCSTATUS_SUCCESS != result) 1085 && (NDEF_TLV_V != parse_tlv) 1086 && (0 != card_size_remaining)) */ 1087 1088 if ((NDEF_TLV_V == parse_tlv) || (NFCSTATUS_SUCCESS != result)) 1089 { 1090 parse_tlv = LOCK_TLV_T; 1091 } 1092 else 1093 { 1094 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES; 1095 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 1096 (NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock + 4); 1097 1098 result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); 1099 } 1100 1101 if (NFCSTATUS_PENDING != result) 1102 { 1103 lock_mem_ndef_index = 0; 1104 skip_lock_mem_size = 0; 1105 card_size_remaining = 0; 1106 } 1107 return result; 1108 } 1109 1110 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1111 1112 #endif /* #ifdef FRINFC_READONLY_NDEF */ 1113 1114 static NFCSTATUS phFriNfc_MfUL_H_WrRd( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) 1115 { 1116 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1117 1118 /* Fill the send buffer */ 1119 phFriNfc_MfUL_H_fillSendBuf(NdefSmtCrdFmt, 1120 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock); 1121 1122 /* Call transceive */ 1123 Result = phFriNfc_MfUL_H_Transceive (NdefSmtCrdFmt); 1124 1125 return Result; 1126 } 1127 1128 static NFCSTATUS phFriNfc_MfUL_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) 1129 { 1130 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1131 1132 /* set the data for additional data exchange*/ 1133 NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0; 1134 NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0; 1135 NdefSmtCrdFmt->psDepAdditionalInfo.NAD = 0; 1136 1137 /*set the completion routines for the card operations*/ 1138 NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process; 1139 NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt; 1140 1141 *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE; 1142 1143 /* Call the Overlapped HAL Transceive function */ 1144 Result = phFriNfc_OvrHal_Transceive( NdefSmtCrdFmt->LowerDevice, 1145 &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo, 1146 NdefSmtCrdFmt->psRemoteDevInfo, 1147 NdefSmtCrdFmt->Cmd, 1148 &NdefSmtCrdFmt->psDepAdditionalInfo, 1149 NdefSmtCrdFmt->SendRecvBuf, 1150 NdefSmtCrdFmt->SendLength, 1151 NdefSmtCrdFmt->SendRecvBuf, 1152 NdefSmtCrdFmt->SendRecvLength); 1153 return Result; 1154 } 1155 1156 static void phFriNfc_MfUL_H_fillSendBuf( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, 1157 uint8_t BlockNo) 1158 { 1159 #ifdef PH_NDEF_MIFARE_ULC 1160 uint8_t NDEFTLV1[4] = {0x01, 0x03, 0xA0, 0x10}; 1161 uint8_t NDEFTLV2[4] = {0x44, 0x03, 0x00, 0xFE}; 1162 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1163 uint8_t NDEFTLV[4] = {0x03, 0x00, 0xFE, 0x00}; 1164 1165 1166 1167 1168 /* First byte for send buffer is always the block number */ 1169 NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_0] = (uint8_t)BlockNo; 1170 switch(NdefSmtCrdFmt->State) 1171 { 1172 #ifdef FRINFC_READONLY_NDEF 1173 1174 case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES: 1175 { 1176 #ifdef PH_HAL4_ENABLE 1177 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; 1178 #else 1179 /* Read command */ 1180 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; 1181 #endif /* #ifdef PH_HAL4_ENABLE */ 1182 *NdefSmtCrdFmt->SendRecvBuf = RD_LOCK_OTP_BLOCK_NUMBER; 1183 /* Send length for read command is always one */ 1184 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; 1185 break; 1186 } 1187 1188 #ifdef PH_NDEF_MIFARE_ULC 1189 1190 case PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES: 1191 { 1192 #ifdef PH_HAL4_ENABLE 1193 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; 1194 #else 1195 /* Read command */ 1196 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; 1197 #endif /* #ifdef PH_HAL4_ENABLE */ 1198 *NdefSmtCrdFmt->SendRecvBuf = 1199 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock; 1200 /* Send length for read command is always one */ 1201 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; 1202 break; 1203 } 1204 1205 case PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES: 1206 { 1207 #ifdef PH_HAL4_ENABLE 1208 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; 1209 #else 1210 /* Read command */ 1211 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; 1212 #endif /* #ifdef PH_HAL4_ENABLE */ 1213 *NdefSmtCrdFmt->SendRecvBuf = NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock; 1214 /* Send length for read command is always one */ 1215 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; 1216 break; 1217 } 1218 1219 case PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES: 1220 { 1221 #ifdef PH_HAL4_ENABLE 1222 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; 1223 #else 1224 /* Write command */ 1225 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4; 1226 #endif /* #ifdef PH_HAL4_ENABLE */ 1227 1228 /* Send length for read command is always one */ 1229 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; 1230 *NdefSmtCrdFmt->SendRecvBuf = NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock; 1231 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1232 NdefSmtCrdFmt->AddInfo.Type2Info.DynLockBytes, 1233 PH_FRINFC_MFUL_FMT_VAL_4); 1234 break; 1235 } 1236 1237 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1238 1239 case PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES: 1240 { 1241 #ifdef PH_HAL4_ENABLE 1242 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; 1243 #else 1244 /* Read command */ 1245 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4; 1246 #endif /* #ifdef PH_HAL4_ENABLE */ 1247 1248 /* Send length for read command is always one */ 1249 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; 1250 *NdefSmtCrdFmt->SendRecvBuf = RD_LOCK_OTP_BLOCK_NUMBER; 1251 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1252 NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes, 1253 PH_FRINFC_MFUL_FMT_VAL_4); 1254 break; 1255 } 1256 1257 case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES: 1258 { 1259 #ifdef PH_HAL4_ENABLE 1260 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; 1261 #else 1262 /* Read command */ 1263 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4; 1264 #endif /* #ifdef PH_HAL4_ENABLE */ 1265 1266 /* Send length for read command is always one */ 1267 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; 1268 *NdefSmtCrdFmt->SendRecvBuf = OTP_BLOCK_NUMBER; 1269 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1270 NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 1271 PH_FRINFC_MFUL_FMT_VAL_4); 1272 break; 1273 } 1274 1275 #endif /* #ifdef FRINFC_READONLY_NDEF */ 1276 1277 case PH_FRINFC_MFUL_FMT_RD_16BYTES: 1278 #ifdef PH_HAL4_ENABLE 1279 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; 1280 #else 1281 /* Read command */ 1282 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareRead; 1283 #endif /* #ifdef PH_HAL4_ENABLE */ 1284 /* Send length for read command is always one */ 1285 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; 1286 break; 1287 1288 case PH_FRINFC_MFUL_FMT_WR_OTPBYTES: 1289 /* Send length for read command is always Five */ 1290 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; 1291 /* Write command */ 1292 #ifdef PH_HAL4_ENABLE 1293 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; 1294 #else 1295 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4; 1296 #endif /* #ifdef PH_HAL4_ENABLE */ 1297 /* Copy the OTP bytes */ 1298 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1299 NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 1300 PH_FRINFC_MFUL_FMT_VAL_4); 1301 break; 1302 1303 case PH_FRINFC_MFUL_FMT_WR_TLV: 1304 #ifndef PH_NDEF_MIFARE_ULC 1305 default: 1306 #endif /* #ifndef PH_NDEF_MIFARE_ULC */ 1307 /* Send length for read command is always Five */ 1308 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; 1309 /* Write command */ 1310 #ifdef PH_HAL4_ENABLE 1311 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; 1312 #else 1313 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite4; 1314 #endif /* #ifdef PH_HAL4_ENABLE */ 1315 /* Copy the NDEF TLV */ 1316 #ifdef PH_NDEF_MIFARE_ULC 1317 1318 if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) 1319 { 1320 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1321 NDEFTLV1, 1322 PH_FRINFC_MFUL_FMT_VAL_4); 1323 } 1324 else if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD) 1325 { 1326 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1327 NDEFTLV, 1328 PH_FRINFC_MFUL_FMT_VAL_4); 1329 } 1330 else 1331 { 1332 } 1333 #else 1334 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1335 NDEFTLV, 1336 PH_FRINFC_MFUL_FMT_VAL_4); 1337 1338 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1339 1340 break; 1341 1342 #ifdef PH_NDEF_MIFARE_ULC 1343 case PH_FRINFC_MFUL_FMT_WR_TLV1: 1344 if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) 1345 { 1346 /* Send length for write command is always Five */ 1347 NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; 1348 /* Write command */ 1349 NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; 1350 (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], 1351 NDEFTLV2, 1352 PH_FRINFC_MFUL_FMT_VAL_4); 1353 } 1354 break; 1355 default: 1356 break; 1357 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1358 1359 1360 } 1361 } 1362 1363 static NFCSTATUS phFriNfc_MfUL_H_ProRd16Bytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) 1364 { 1365 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, 1366 NFCSTATUS_FORMAT_ERROR); 1367 uint32_t memcompare = PH_FRINFC_MFUL_FMT_VAL_0; 1368 uint8_t ZeroBuf[] = {0x00, 0x00, 0x00, 0x00}; 1369 1370 #ifdef PH_NDEF_MIFARE_ULC 1371 uint8_t OTPByteUL[] = PH_FRINFC_MFUL_FMT_OTP_BYTES; 1372 uint8_t OTPByteULC[] = PH_FRINFC_MFULC_FMT_OTP_BYTES; 1373 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1374 1375 /* Check the lock bits (byte number 2 and 3 of block number 2) */ 1376 if ((NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_2] == 1377 PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL) && 1378 (NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_3] == 1379 PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL)) 1380 { 1381 1382 #ifdef PH_NDEF_MIFARE_ULC 1383 1384 if (NdefSmtCrdFmt->SendRecvBuf[8] == 0x02 && 1385 NdefSmtCrdFmt->SendRecvBuf[9] == 0x00) 1386 { 1387 NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD; 1388 1389 (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 1390 OTPByteULC, 1391 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); 1392 } 1393 else if (NdefSmtCrdFmt->SendRecvBuf[8] == 0xFF && 1394 NdefSmtCrdFmt->SendRecvBuf[9] == 0xFF) 1395 { 1396 NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; 1397 1398 (void)memcpy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 1399 OTPByteUL, 1400 sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); 1401 } 1402 else 1403 { 1404 NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; 1405 } 1406 1407 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1408 1409 memcompare = (uint32_t) 1410 MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4], 1411 NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, 1412 PH_FRINFC_MFUL_FMT_VAL_4); 1413 1414 if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0) 1415 { 1416 /* Write NDEF TLV in block number 4 */ 1417 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 1418 PH_FRINFC_MFUL_FMT_VAL_4; 1419 /* Card already have the OTP bytes so write TLV */ 1420 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV; 1421 } 1422 else 1423 { 1424 /* IS the card new, OTP bytes = {0x00, 0x00, 0x00, 0x00} */ 1425 memcompare = (uint32_t)MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4], 1426 ZeroBuf, 1427 PH_FRINFC_MFUL_FMT_VAL_4); 1428 /* If OTP bytes are Zero then the card is Zero */ 1429 if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0) 1430 { 1431 /* Write OTP bytes in block number 3 */ 1432 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 1433 PH_FRINFC_MFUL_FMT_VAL_3; 1434 /* Card already have the OTP bytes so write TLV */ 1435 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_OTPBYTES; 1436 } 1437 } 1438 } 1439 1440 1441 1442 #ifdef PH_NDEF_MIFARE_ULC 1443 if( 1444 ((NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_TLV) || 1445 (NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_OTPBYTES)) && 1446 ((NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) || 1447 (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD)) 1448 ) 1449 #else 1450 if((NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_TLV) || 1451 (NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_OTPBYTES)) 1452 #endif /* #ifdef PH_NDEF_MIFARE_ULC */ 1453 { 1454 Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt); 1455 } 1456 return Result; 1457 } 1458 1459 static NFCSTATUS phFriNfc_MfUL_H_ProWrOTPBytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) 1460 { 1461 NFCSTATUS Result = NFCSTATUS_SUCCESS; 1462 /* Card already have the OTP bytes so write TLV */ 1463 NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV; 1464 1465 /* Write NDEF TLV in block number 4 */ 1466 NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 1467 PH_FRINFC_MFUL_FMT_VAL_4; 1468 1469 Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt); 1470 return Result; 1471 } 1472 1473