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