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*/
MemCompare1(void * s1,void * s2,unsigned int n)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
phFriNfc_MfUL_Reset(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_ConvertToReadOnly(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_Process(void * Context,NFCSTATUS Status)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
phFriNfc_MfUL_GetSkipSize(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt,uint8_t block_number,uint8_t byte_number)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
phFriNfc_MfUL_GetLockBytesInfo(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_CalcRemainingLockBits(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_UpdateAndWriteLockBits(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_ReadWriteLockBytes(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_GetDefaultLockBytesInfo(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_ParseTLVs(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt,uint8_t * data_to_parse,uint8_t size_to_parse)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
phFriNfc_MfUL_H_WrRd(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_H_fillSendBuf(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt,uint8_t BlockNo)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
phFriNfc_MfUL_H_ProRd16Bytes(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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
phFriNfc_MfUL_H_ProWrOTPBytes(phFriNfc_sNdefSmtCrdFmt_t * NdefSmtCrdFmt)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