Initialize Tizen 2.3
[adaptation/devices/nfc-plugin-nxp.git] / src / phFriNfc_MifULFormat.c
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_T;
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