1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * NFC Ndef Mapping For Remote Devices.
19  *
20  */
21 
22 #include <phFriNfc_MifStdFormat.h>
23 #include <phFriNfc_MifareStdMap.h>
24 #include <phNfcCompId.h>
25 #include <phNxpExtns_MifareStd.h>
26 
27 /**************** local methods used in this file only ************************/
28 static NFCSTATUS phFriNfc_MifStd_H_RdABlock(phFriNfc_NdefMap_t* NdefMap);
29 static NFCSTATUS phFriNfc_MifStd_H_WrABlock(phFriNfc_NdefMap_t* NdefMap);
30 static NFCSTATUS phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t* NdefMap);
31 static NFCSTATUS phFriNfc_MifStd4k_H_CheckNdef(phFriNfc_NdefMap_t* NdefMap);
32 static void phFriNfc_MifStd_H_fillAIDarray(phFriNfc_NdefMap_t* NdefMap);
33 static uint8_t phFriNfc_MifStd_H_GetSect(uint8_t BlockNumber);
34 static NFCSTATUS phFriNfc_MifStd_H_BlkChk(phFriNfc_NdefMap_t* NdefMap);
35 static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit(phFriNfc_NdefMap_t* NdefMap);
36 static NFCSTATUS phFriNfc_MifStd_H_ChkAcsBit(phFriNfc_NdefMap_t* NdefMap);
37 static NFCSTATUS phFriNfc_MifStd_H_ChkRdWr(phFriNfc_NdefMap_t* NdefMap);
38 static void phFriNfc_MifStd_H_ChkNdefCmpltSects(phFriNfc_NdefMap_t* NdefMap);
39 static NFCSTATUS phFriNfc_MifStd_H_RemainTLV(phFriNfc_NdefMap_t* NdefMap,
40                                              uint8_t* Flag,
41                                              uint8_t* Temp16Bytes);
42 static NFCSTATUS phFriNfc_MifStd_H_ChkIntLen(phFriNfc_NdefMap_t* NdefMap);
43 static NFCSTATUS phFriNfc_MifStd_H_IntLenWioutNdef(phFriNfc_NdefMap_t* NdefMap,
44                                                    uint8_t* Flag,
45                                                    uint8_t* TempintBytes);
46 static uint8_t phFriNfc_MifStd_H_UpdateTLV(phFriNfc_NdefMap_t* NdefMap);
47 static NFCSTATUS phFriNfc_MifStd_H_WriteNdefLen(phFriNfc_NdefMap_t* NdefMap);
48 static void phFriNfc_MifStd_H_SetNdefBlkAuth(phFriNfc_NdefMap_t* NdefMap);
49 static void phFriNfc_MifStd_H_RdWrReset(phFriNfc_NdefMap_t* NdefMap);
50 static NFCSTATUS phFriNfc_MifStd_H_RdtoWrNdefLen(phFriNfc_NdefMap_t* NdefMap);
51 static NFCSTATUS phFriNfc_MifStd_H_GetActCardLen(phFriNfc_NdefMap_t* NdefMap);
52 static NFCSTATUS phFriNfc_MifStd_H_ChkTLVs(phFriNfc_NdefMap_t* NdefMap,
53                                            uint8_t* CRFlag);
54 static NFCSTATUS phFriNfc_MifStd_H_GetNxtTLV(phFriNfc_NdefMap_t* NdefMap,
55                                              uint16_t* TempLength,
56                                              uint8_t* TL4bytesFlag);
57 static NFCSTATUS phFriNfc_MifStd_H_Chk16Bytes(phFriNfc_NdefMap_t* NdefMap,
58                                               uint16_t TempLength);
59 static NFCSTATUS phFriNfc_MifStd_H_ChkRemainTLVs(phFriNfc_NdefMap_t* NdefMap,
60                                                  uint8_t* CRFlag,
61                                                  uint8_t* NDEFFlag);
62 static void phFriNfc_MifStd_H_Complete(phFriNfc_NdefMap_t* NdefMap,
63                                        NFCSTATUS Result);
64 static void phFriNfc_MifStd_H_Get1kStTrail(phFriNfc_NdefMap_t* NdefMap);
65 static void phFriNfc_MifStd_H_Get4kStTrail(phFriNfc_NdefMap_t* NdefMap);
66 static NFCSTATUS phFriNfc_MifStd_H_ProChkNdef(phFriNfc_NdefMap_t* NdefMap);
67 static NFCSTATUS phFriNfc_MifStd_H_ProAuth(phFriNfc_NdefMap_t* NdefMap);
68 static NFCSTATUS phFriNfc_MifStd_H_Rd16Bytes(phFriNfc_NdefMap_t* NdefMap,
69                                              uint8_t BlockNo);
70 static NFCSTATUS phFriNfc_MifStd_H_ProAcsBits(phFriNfc_NdefMap_t* NdefMap);
71 static NFCSTATUS phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t* NdefMap);
72 static NFCSTATUS phFriNfc_MifStd_H_ProStatNotValid(phFriNfc_NdefMap_t* NdefMap,
73                                                    NFCSTATUS status);
74 static NFCSTATUS phFriNfc_MifStd_H_RdBeforeWr(phFriNfc_NdefMap_t* NdefMap);
75 static NFCSTATUS phFriNfc_MifStd_H_ProBytesToWr(phFriNfc_NdefMap_t* NdefMap);
76 static NFCSTATUS phFriNfc_MifStd_H_fillSendBuf(phFriNfc_NdefMap_t* NdefMap,
77                                                uint8_t Length);
78 static NFCSTATUS phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t* NdefMap);
79 static NFCSTATUS phFriNfc_MifStd_H_ProWrTLV(phFriNfc_NdefMap_t* NdefMap);
80 static uint8_t phFriNfc_MifStd_H_UpdRemTLV(phFriNfc_NdefMap_t* NdefMap);
81 static void phFriNfc_MifStd_H_fillTLV1(phFriNfc_NdefMap_t* NdefMap);
82 static void phFriNfc_MifStd_H_fillTLV2(phFriNfc_NdefMap_t* NdefMap);
83 static NFCSTATUS phFriNfc_MifStd_H_CallWrNdefLen(phFriNfc_NdefMap_t* NdefMap);
84 static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t* NdefMap);
85 static void phFriNfc_MifStd_H_fillTLV1_1(phFriNfc_NdefMap_t* NdefMap);
86 static void phFriNfc_MifStd_H_fillTLV2_1(phFriNfc_NdefMap_t* NdefMap);
87 static NFCSTATUS phFriNfc_MifStd_H_RdTLV(phFriNfc_NdefMap_t* NdefMap);
88 static NFCSTATUS phFriNfc_MifStd_H_ProRdTLV(phFriNfc_NdefMap_t* NdefMap);
89 static NFCSTATUS phFriNfc_MifStd_H_WrTermTLV(phFriNfc_NdefMap_t* NdefMap);
90 static NFCSTATUS phFriNfc_MifStd_H_ProWrABlock(phFriNfc_NdefMap_t* NdefMap);
91 static NFCSTATUS phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t* NdefMap);
92 static NFCSTATUS phFriNfc_MifStd_H_CallDisCon(phFriNfc_NdefMap_t* NdefMap);
93 static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t* NdefMap,
94                                        uint8_t SectorID, uint8_t* callbreak);
95 static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo(uint8_t SectorID);
96 static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits(
97     phFriNfc_NdefMap_t* NdefMap);
98 static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock(
99     phFriNfc_NdefMap_t* NdefMap);
100 static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor(
101     phFriNfc_NdefMap_t* NdefMap);
102 static NFCSTATUS phFriNfc_MapTool_ChkSpcVer(const phFriNfc_NdefMap_t* NdefMap,
103                                             uint8_t VersionIndex)
104     __attribute__((unused));
105 
106 /* Mifare Standard Mapping - Constants */
107 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1 \
108   0xA0 /* internal Authenticate Command for MAD Sector */
109 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2 \
110   0xA1 /* internal Authenticate Command for MAD Sector */
111 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3 \
112   0xA2 /* internal Authenticate Command for MAD Sector */
113 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4 \
114   0xA3 /* internal Authenticate Command for MAD Sector */
115 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5 \
116   0xA4 /* internal Authenticate Command for MAD Sector */
117 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6 \
118   0xA5 /* internal Authenticate Command for MAD Sector */
119 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1 \
120   0xD3 /* internal Authenticate Command for NDEF Sectors 1 */
121 #define PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2 \
122   0xF7 /* internal Authenticate Command for NDEF Sectors 2 */
123 #define PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL2 \
124   0x03 /* internal Ndef Compliant command 1 */
125 #define PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL1 \
126   0xE1 /* internal Ndef Compliant command 2 */
127 
128 /* Enable access bits check for the MAD sector
129 #define ENABLE_ACS_BIT_CHK_FOR_MAD */
130 
131 #define PH_FRINFC_NDEFMAP_MFUL_VAL0 0
132 
133 /******************************************************************************
134  * Function         phFriNfc_MapTool_SetCardState
135  *
136  * Description      This function sets the appropriate card state.
137  *
138  * Returns          This function return NFCSTATUS_SUCCESS in case of success
139  *                  In case of failure returns other failure value.
140  *
141  ******************************************************************************/
phFriNfc_MapTool_SetCardState(phFriNfc_NdefMap_t * NdefMap,uint32_t Length)142 NFCSTATUS phFriNfc_MapTool_SetCardState(phFriNfc_NdefMap_t* NdefMap,
143                                         uint32_t Length) {
144   NFCSTATUS Result = NFCSTATUS_SUCCESS;
145 
146   if (Length == PH_FRINFC_NDEFMAP_MFUL_VAL0) {
147     /* As the NDEF LEN / TLV Len is Zero, irrespective of any state the card
148        shall be set to INITIALIZED STATE*/
149     NdefMap->CardState =
150         (uint8_t)(((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY) ||
151                    (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID))
152                       ? PH_NDEFMAP_CARD_STATE_INVALID
153                       : PH_NDEFMAP_CARD_STATE_INITIALIZED);
154   } else {
155     switch (NdefMap->CardState) {
156       case PH_NDEFMAP_CARD_STATE_INITIALIZED:
157         NdefMap->CardState =
158             (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID)
159                           ? NdefMap->CardState
160                           : PH_NDEFMAP_CARD_STATE_READ_WRITE);
161         break;
162 
163       case PH_NDEFMAP_CARD_STATE_READ_ONLY:
164         NdefMap->CardState =
165             (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID)
166                           ? NdefMap->CardState
167                           : PH_NDEFMAP_CARD_STATE_READ_ONLY);
168         break;
169 
170       case PH_NDEFMAP_CARD_STATE_READ_WRITE:
171         NdefMap->CardState =
172             (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID)
173                           ? NdefMap->CardState
174                           : PH_NDEFMAP_CARD_STATE_READ_WRITE);
175         if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD ||
176             NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD ||
177             NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) {
178           if (NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
179               NdefMap->StdMifareContainer.SectorTrailerBlockNo ==
180                   NdefMap->StdMifareContainer.currentBlock) {
181             NdefMap->CardState =
182                 (uint8_t)((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID)
183                               ? NdefMap->CardState
184                               : PH_NDEFMAP_CARD_STATE_READ_ONLY);
185           }
186         }
187         break;
188 
189       default:
190         NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
191         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
192         break;
193     }
194   }
195   Result = ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID)
196                 ? PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT)
197                 : Result);
198 
199   return Result;
200 }
201 
202 /******************************************************************************
203  * Function         phFriNfc_MifareStdMap_H_Reset
204  *
205  * Description      This function resets the component instance to the initial
206  *                  state and lets the component forget about the list of
207  *                  registered items. Moreover, the lower device is set.
208  *
209  * Returns          This function return NFCSTATUS_SUCCESS in case of success
210  *                  In case of failure returns other failure value.
211  *
212  ******************************************************************************/
phFriNfc_MifareStdMap_H_Reset(phFriNfc_NdefMap_t * NdefMap)213 NFCSTATUS phFriNfc_MifareStdMap_H_Reset(phFriNfc_NdefMap_t* NdefMap) {
214   NFCSTATUS status = NFCSTATUS_SUCCESS;
215   uint8_t index = PH_FRINFC_MIFARESTD_VAL0;
216 
217   if (NdefMap == NULL) {
218     status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
219   } else {
220     /* Current Block stores the present block accessed in the card */
221     NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_VAL0;
222 
223     for (index = PH_FRINFC_MIFARESTD_VAL0;
224          index < PH_FRINFC_NDEFMAP_MIFARESTD_ST15_BYTES; index++) {
225       /* internal buffer to store the odd bytes of length < 15 */
226       NdefMap->StdMifareContainer.internalBuf[index] = PH_FRINFC_MIFARESTD_VAL0;
227     }
228 
229     for (index = 0; index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK; index++) {
230       /* aid buffer reset to non ndef compliant */
231       NdefMap->StdMifareContainer.aid[index] =
232           PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
233     }
234 
235     /* odd bytes length stored in the internal buffer */
236     NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0;
237 
238     NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
239 
240     /* Flag to get that last few bytes are taken from the user buffer */
241     NdefMap->StdMifareContainer.RemainingBufFlag = PH_FRINFC_MIFARESTD_FLAG0;
242 
243     /* Flag to find that the read/write operation has reached the end of the
244        card. Further reading/writing is not possible */
245     NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
246         PH_FRINFC_MIFARESTD_FLAG0;
247 
248     /* Flag to get that last few bytes are taken from the internal buffer */
249     NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG0;
250 
251     /* Authentication Flag for every sector */
252     NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
253 
254     /* Used in Check Ndef for storing the sector ID */
255     NdefMap->StdMifareContainer.SectorIndex = PH_FRINFC_MIFARESTD_VAL0;
256 
257     NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL0;
258 
259     NdefMap->StdMifareContainer.NoOfNdefCompBlocks = PH_FRINFC_MIFARESTD_VAL0;
260 
261     NdefMap->StdMifareContainer.ReadAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG0;
262 
263     NdefMap->StdMifareContainer.remSizeUpdFlag = PH_FRINFC_MIFARESTD_FLAG0;
264 
265     NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0;
266 
267     NdefMap->TLVStruct.prevLenByteValue = PH_FRINFC_MIFARESTD_VAL0;
268 
269     NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0;
270 
271     NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_MIFARESTD_VAL0;
272 
273     NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0;
274 
275     NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
276 
277     NdefMap->StdMifareContainer.remainingSize = PH_FRINFC_MIFARESTD_VAL0;
278 
279     NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
280 
281     NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
282 
283     NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
284 
285     NdefMap->StdMifareContainer.aidCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0;
286 
287     NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0;
288 
289     NdefMap->StdMifareContainer.ProprforumSectFlag =
290         PH_FRINFC_MIFARESTD_PROP_1ST_CONFIG;
291 
292     NdefMap->StdMifareContainer.ReadCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0;
293 
294     NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0;
295 
296     NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL1;
297 
298     NdefMap->StdMifareContainer.ChkNdefCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0;
299 
300     NdefMap->StdMifareContainer.ReadOnlySectorIndex = PH_FRINFC_MIFARESTD_FLAG0;
301 
302     NdefMap->StdMifareContainer.TotalNoSectors = PH_FRINFC_MIFARESTD_FLAG0;
303 
304     NdefMap->StdMifareContainer.SectorTrailerBlockNo =
305         PH_FRINFC_MIFARESTD_FLAG0;
306   }
307 
308   return status;
309 }
310 
311 /******************************************************************************
312  * Function         phFriNfc_MifareStdMap_ChkNdef
313  *
314  * Description      The function checks whether the peer device is NDEF
315  *compliant.
316  *
317  * Returns          This function return NFCSTATUS_PENDING in case of success
318  *                  In case of failure returns other failure value.
319  *
320  ******************************************************************************/
phFriNfc_MifareStdMap_ChkNdef(phFriNfc_NdefMap_t * NdefMap)321 NFCSTATUS phFriNfc_MifareStdMap_ChkNdef(phFriNfc_NdefMap_t* NdefMap) {
322   NFCSTATUS status = NFCSTATUS_PENDING;
323   uint8_t atq, sak;
324 
325   if (NdefMap == NULL) {
326     status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
327   } else {
328     NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
329     NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
330 
331     /* Get the Select Response and Sense Response to get
332         the exact Card Type either Mifare 1k or 4k */
333     sak = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
334     atq = NdefMap->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0];
335 
336     if (0x08 == (sak & 0x18)) {
337       /* Total Number of Blocks in Mifare 1k Card */
338       NdefMap->StdMifareContainer.NoOfNdefCompBlocks =
339           PH_FRINFC_NDEFMAP_MIFARESTD_1KNDEF_COMPBLOCK;
340       NdefMap->StdMifareContainer.remainingSize =
341           ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0)
342                ? (PH_FRINFC_NDEFMAP_MIFARESTD_1KNDEF_COMPBLOCK *
343                   PH_FRINFC_MIFARESTD_BLOCK_BYTES)
344                : NdefMap->StdMifareContainer.remainingSize);
345       NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD;
346     } else if (0x19 == (sak & 0x19)) {
347       /* Total Number of Blocks in Mifare 2k Card */
348       NdefMap->StdMifareContainer.NoOfNdefCompBlocks =
349           PH_FRINFC_NDEFMAP_MIFARESTD_2KNDEF_COMPBLOCK;
350       NdefMap->StdMifareContainer.remainingSize =
351           ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0)
352                ? (PH_FRINFC_NDEFMAP_MIFARESTD_2KNDEF_COMPBLOCK *
353                   PH_FRINFC_MIFARESTD_BLOCK_BYTES)
354                : NdefMap->StdMifareContainer.remainingSize);
355       NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD;
356     } else {
357       /* Total Number of Blocks in Mifare 4k Card */
358       NdefMap->StdMifareContainer.NoOfNdefCompBlocks =
359           PH_FRINFC_NDEFMAP_MIFARESTD_4KNDEF_COMPBLOCK;
360       NdefMap->StdMifareContainer.remainingSize =
361           ((NdefMap->CardType == PH_FRINFC_MIFARESTD_VAL0)
362                ? (PH_FRINFC_NDEFMAP_MIFARESTD_4KNDEF_COMPBLOCK *
363                   PH_FRINFC_MIFARESTD_BLOCK_BYTES)
364                : NdefMap->StdMifareContainer.remainingSize);
365       NdefMap->CardType = PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD;
366     }
367 
368     /*  phFriNfc_MifareStdMap_ChkNdef should be called only
369         when currentBlock is 0 OR 64,65 and 66 (for Mifare 4k).
370         Otherwise return error */
371     /* and also Check the Authentication Flag */
372     if ((NdefMap->StdMifareContainer.currentBlock != 0) &&
373         (NdefMap->StdMifareContainer.currentBlock != 1) &&
374         (NdefMap->StdMifareContainer.currentBlock != 2) &&
375         (NdefMap->StdMifareContainer.currentBlock != 64) &&
376         (NdefMap->StdMifareContainer.currentBlock != 65) &&
377         (NdefMap->StdMifareContainer.currentBlock != 66)) {
378       status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
379     } else if (NdefMap->StdMifareContainer.AuthDone == 0) {
380       /*  Block 0 contains Manufacturer information and
381           also other informaton. So go for block 1 which
382           contains AIDs. Authenticating any of the block
383           in a sector, Authenticates the whole sector */
384       if (NdefMap->StdMifareContainer.currentBlock == 0) {
385         NdefMap->StdMifareContainer.currentBlock = 1;
386       }
387       status = phFriNfc_MifStd_H_AuthSector(NdefMap);
388     } else {
389       /**
390        * Mifare 1k, sak = 0x08 atq = 0x04
391        * Mifare 2k, sak = 0x19 atq = 0x02
392        * Mifare 4k, sak = 0x18 atq = 0x02
393        */
394       if ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) ||
395           (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) ||
396           (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) {
397         /* Change the state to Check Ndef Compliant */
398         NdefMap->State = PH_FRINFC_NDEFMAP_STATE_CHK_NDEF_COMP;
399         NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
400         NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG1;
401 
402         NdefMap->MapCompletionInfo.CompletionRoutine =
403             phFriNfc_MifareStdMap_Process;
404         NdefMap->MapCompletionInfo.Context = NdefMap;
405 
406         NdefMap->Cmd.MfCmd = phHal_eMifareRead;
407         *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
408         NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock;
409         NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ;
410 
411         /* Call the Overlapped HAL Transceive function */
412         status = phFriNfc_ExtnsTransceive(
413             NdefMap->pTransceiveInfo, NdefMap->Cmd, NdefMap->SendRecvBuf,
414             NdefMap->SendLength, NdefMap->SendRecvLength);
415       } else {
416         /* Since we have decided temporarily not to go
417             for any new error codes we are using
418             NFCSTATUS_INVALID_PARAMETER even though it is not
419             the relevant error code here TBD */
420         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
421       }
422     }
423   }
424 
425   return status;
426 }
427 
428 /******************************************************************************
429  * Function         phFriNfc_MifareStdMap_RdNdef
430  *
431  * Description      The function initiates the reading of NDEF information from
432  *                  a Remote Device. It performs a reset of the state and starts
433  *                  the action (state machine). A periodic call of the
434  *                  phFriNfcNdefMap_Process has to be done once the action
435  *                  has been triggered.
436  *
437  * Returns          This function return NFCSTATUS_PENDING in case of success
438  *                  In case of failure returns other failure value.
439  *
440  ******************************************************************************/
phFriNfc_MifareStdMap_RdNdef(phFriNfc_NdefMap_t * NdefMap,uint8_t * PacketData,uint32_t * PacketDataLength,uint8_t Offset)441 NFCSTATUS phFriNfc_MifareStdMap_RdNdef(phFriNfc_NdefMap_t* NdefMap,
442                                        uint8_t* PacketData,
443                                        uint32_t* PacketDataLength,
444                                        uint8_t Offset) {
445   NFCSTATUS status = NFCSTATUS_PENDING;
446 
447   NdefMap->ApduBufferSize = *PacketDataLength;
448   NdefMap->NumOfBytesRead = PacketDataLength;
449   *NdefMap->NumOfBytesRead = 0;
450   NdefMap->ApduBuffIndex = 0;
451   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
452   NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
453 
454   if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) ||
455       (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED)) {
456     /* Card state  is not correct */
457     status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
458   } else {
459     if ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
460         (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) {
461       phFriNfc_MifStd_H_RdWrReset(NdefMap);
462       NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG1;
463       NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
464     }
465     /* Offset = Current, but the read has reached the End of Card */
466     if ((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
467         (NdefMap->StdMifareContainer.ReadWriteCompleteFlag ==
468          PH_FRINFC_MIFARESTD_FLAG1)) {
469       status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
470                           NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
471     } else {
472       NdefMap->Offset =
473           (((Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) &&
474             (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE))
475                ? PH_FRINFC_NDEFMAP_SEEK_BEGIN
476                : Offset);
477       status = phFriNfc_MifStd_H_BlkChk(NdefMap);
478       if (status == NFCSTATUS_SUCCESS) {
479         NdefMap->ApduBuffer = PacketData;
480 
481         /* Read Operation in Progress */
482         NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
483             PH_FRINFC_MIFARESTD_FLAG0;
484 
485         /* Check Authentication Flag */
486         status =
487             ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1)
488                  ? phFriNfc_MifStd_H_RdABlock(NdefMap)
489                  : phFriNfc_MifStd_H_AuthSector(NdefMap));
490       }
491     }
492   }
493 
494   return status;
495 }
496 
497 /******************************************************************************
498  * Function         phFriNfc_MifareStdMap_WrNdef
499  *
500  * Description      The function initiates the writing of NDEF information to
501  *                  a Remote Device. It performs a reset of the state and starts
502  *                  the action (state machine). A periodic call of the
503  *                  phFriNfcNdefMap_Process has to be done once the action
504  *                  has been triggered.
505  *
506  * Returns          This function return NFCSTATUS_PENDING in case of success
507  *                  In case of failure returns other failure value.
508  *
509  ******************************************************************************/
phFriNfc_MifareStdMap_WrNdef(phFriNfc_NdefMap_t * NdefMap,uint8_t * PacketData,uint32_t * PacketDataLength,uint8_t Offset)510 NFCSTATUS phFriNfc_MifareStdMap_WrNdef(phFriNfc_NdefMap_t* NdefMap,
511                                        uint8_t* PacketData,
512                                        uint32_t* PacketDataLength,
513                                        uint8_t Offset) {
514   NFCSTATUS status = NFCSTATUS_PENDING;
515 
516   NdefMap->ApduBuffer = PacketData;
517   NdefMap->ApduBufferSize = *PacketDataLength;
518   NdefMap->ApduBuffIndex = PH_FRINFC_MIFARESTD_VAL0;
519   NdefMap->WrNdefPacketLength = PacketDataLength;
520   *NdefMap->WrNdefPacketLength = PH_FRINFC_MIFARESTD_VAL0;
521   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
522   NdefMap->StdMifareContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
523 
524   if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) ||
525       (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) {
526     /* Card state  is not correct */
527     status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
528   } else {
529     if ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
530         (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE)) {
531       NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
532       NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG1;
533       NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG1;
534       NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0;
535       NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
536       NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
537       NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
538       NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0;
539       NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0;
540       NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0;
541       NdefMap->StdMifareContainer.remainingSize =
542           (NdefMap->StdMifareContainer.NoOfNdefCompBlocks *
543            PH_FRINFC_MIFARESTD_BLOCK_BYTES);
544       NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4;
545       NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL1;
546       NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0;
547       /* This macro is added, to be compliant with the previous HAL 2.0
548           For HAL 2.0, polling is done before writing data to the mifare
549           std (if the offset is BEGIN), because if an error is reported
550           during read or write and again write is called, the PN531 state is
551           unchanged (so write will fail), to bring the PN531 to the correct
552           state, polling is done.
553           Changed on 13th Jan 2009
554       */
555       NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG0;
556       NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL0;
557       NdefMap->StdMifareContainer.FirstWriteFlag = PH_FRINFC_MIFARESTD_FLAG1;
558     }
559 
560     if (((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
561          (NdefMap->StdMifareContainer.ReadWriteCompleteFlag ==
562           PH_FRINFC_MIFARESTD_FLAG1)) ||
563         ((NdefMap->StdMifareContainer.PollFlag == PH_FRINFC_MIFARESTD_FLAG1) &&
564          (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR))) {
565       /* Offset = Current, but the read has reached the End of Card */
566       status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
567                           NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
568     } else {
569       NdefMap->Offset =
570           (((Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) &&
571             (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))
572                ? PH_FRINFC_NDEFMAP_SEEK_BEGIN
573                : Offset);
574       NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
575       status = phFriNfc_MifStd_H_BlkChk(NdefMap);
576       NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
577           PH_FRINFC_MIFARESTD_FLAG0;
578       if (status == NFCSTATUS_SUCCESS) {
579         if (NdefMap->StdMifareContainer.PollFlag == PH_FRINFC_MIFARESTD_FLAG1) {
580           /* if poll flag is set then call disconnect because the authentication
581               has failed so reactivation of card is required */
582           status = phFriNfc_MifStd_H_CallDisCon(NdefMap);
583         }
584         /* Check Authentication Flag */
585         else if (NdefMap->StdMifareContainer.AuthDone ==
586                  PH_FRINFC_MIFARESTD_FLAG1) {
587           status = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)
588                         ? phFriNfc_MifStd_H_RdBeforeWr(NdefMap)
589                         : phFriNfc_MifStd_H_WrABlock(NdefMap));
590         } else {
591           status = phFriNfc_MifStd_H_AuthSector(NdefMap);
592         }
593       }
594     }
595   }
596 
597   return status;
598 }
599 
600 /******************************************************************************
601  * Function         phFriNfc_MifareStdMap_Process
602  *
603  * Description      This function is a Completion Routine, Processing function,
604  *                  needed to avoid long blocking.
605  *                  This function as a Completion Routine in order to be able
606  *                  to notify the component that an I/O has finished and data
607  *                  are ready to be processed.
608 
609  * Returns          void
610  *
611  ******************************************************************************/
phFriNfc_MifareStdMap_Process(void * Context,NFCSTATUS Status)612 void phFriNfc_MifareStdMap_Process(void* Context, NFCSTATUS Status) {
613   phFriNfc_NdefMap_t* NdefMap;
614   uint8_t NDEFFlag = 0, CRFlag = 0, Temp16Bytes = 0, i = 0;
615 
616   NdefMap = (phFriNfc_NdefMap_t*)Context;
617 
618   if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER)) {
619     switch (NdefMap->State) {
620       case PH_FRINFC_NDEFMAP_STATE_CHK_NDEF_COMP:
621         Status = phFriNfc_MifStd_H_ProChkNdef(NdefMap);
622         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
623                                ? PH_FRINFC_MIFARESTD_FLAG1
624                                : PH_FRINFC_MIFARESTD_FLAG0);
625         break;
626 
627       case PH_FRINFC_NDEFMAP_STATE_READ:
628         /* Receive Length for read shall always be equal to 16 */
629         if ((*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) &&
630             (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize)) {
631           Temp16Bytes = PH_FRINFC_MIFARESTD_VAL0;
632           NDEFFlag = (uint8_t)PH_FRINFC_MIFARESTD_FLAG1;
633           if (NdefMap->TLVStruct.BytesRemainLinTLV != 0) {
634             NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
635             CRFlag = PH_FRINFC_MIFARESTD_FLAG0;
636             /* To read the remaining length (L) in TLV */
637             Status =
638                 phFriNfc_MifStd_H_RemainTLV(NdefMap, &NDEFFlag, &Temp16Bytes);
639             CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
640                                    ? PH_FRINFC_MIFARESTD_FLAG1
641                                    : PH_FRINFC_MIFARESTD_FLAG0);
642           }
643 
644           /* check the NDEFFlag is set. if this is not set, then
645               in the above RemainTLV function all the 16 bytes has been
646               read */
647         } else {
648           Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
649                               NFCSTATUS_INVALID_RECEIVE_LENGTH);
650           CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
651         }
652         break;
653 
654       case PH_FRINFC_NDEFMAP_STATE_WRITE:
655         Status = phFriNfc_MifStd_H_ProWrABlock(NdefMap);
656         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
657                                ? PH_FRINFC_MIFARESTD_FLAG1
658                                : PH_FRINFC_MIFARESTD_FLAG0);
659 
660         /* Call Completion Routine if CR Flag is Set to 1 */
661         if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) {
662           *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
663         }
664         break;
665 
666       case PH_FRINFC_NDEFMAP_STATE_AUTH:
667         NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0;
668         Status = phFriNfc_MifStd_H_ProAuth(NdefMap);
669         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
670                                ? PH_FRINFC_MIFARESTD_FLAG1
671                                : PH_FRINFC_MIFARESTD_FLAG0);
672         break;
673 
674       case PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT:
675         Status = phFriNfc_MifStd_H_ProAcsBits(NdefMap);
676         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
677                                ? PH_FRINFC_MIFARESTD_FLAG1
678                                : PH_FRINFC_MIFARESTD_FLAG0);
679         break;
680 
681       case PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN:
682         if (NdefMap->StdMifareContainer.RdAfterWrFlag ==
683             PH_FRINFC_MIFARESTD_FLAG1) {
684           Status = phFriNfc_MifStd_H_CallWrNdefLen(NdefMap);
685           CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
686                                  ? PH_FRINFC_MIFARESTD_FLAG1
687                                  : PH_FRINFC_MIFARESTD_FLAG0);
688         } else {
689           /* Check this */
690           if (NdefMap->StdMifareContainer.TempBlockNo ==
691               NdefMap->StdMifareContainer.currentBlock) {
692             memcpy(NdefMap->StdMifareContainer.internalBuf,
693                    NdefMap->StdMifareContainer.Buffer,
694                    NdefMap->StdMifareContainer.internalLength);
695           }
696           *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
697           NdefMap->StdMifareContainer.currentBlock =
698               NdefMap->StdMifareContainer.TempBlockNo;
699           NdefMap->CardState = (uint8_t)(
700               (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED)
701                   ? PH_NDEFMAP_CARD_STATE_READ_WRITE
702                   : NdefMap->CardState);
703           CRFlag = (uint8_t)PH_FRINFC_MIFARESTD_FLAG1;
704         }
705         break;
706 
707       case PH_FRINFC_NDEFMAP_STATE_RD_TO_WR_NDEF_LEN:
708         CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
709         Status =
710             PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST);
711         if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
712           /* Size of NdefMap->SendRecvBuf is set by phLibNfc_Gen_NdefMapReset to
713            * PH_LIBNFC_GEN_MAX_BUFFER */
714           /* We don't have to check memory here */
715           for (i = PH_FRINFC_MIFARESTD_BYTES_READ; i > 0; i--) {
716             NdefMap->SendRecvBuf[i] = NdefMap->SendRecvBuf[i - 1];
717           }
718           NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
719               NdefMap->StdMifareContainer.currentBlock;
720           Status = phFriNfc_MifStd_H_WriteNdefLen(NdefMap);
721           CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
722                                  ? PH_FRINFC_MIFARESTD_FLAG1
723                                  : PH_FRINFC_MIFARESTD_FLAG0);
724         }
725         break;
726 
727       case PH_FRINFC_NDEFMAP_STATE_GET_ACT_CARDSIZE:
728         NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1;
729         if (NdefMap->TLVStruct.NoLbytesinTLV > PH_FRINFC_MIFARESTD_VAL0) {
730           NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
731           Status = phFriNfc_MifStd_H_ChkRemainTLVs(NdefMap, &CRFlag, &NDEFFlag);
732           NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0;
733         }
734         if ((NDEFFlag == PH_FRINFC_MIFARESTD_FLAG1) &&
735             (CRFlag != PH_FRINFC_MIFARESTD_FLAG1)) {
736           Status = phFriNfc_MifStd_H_ChkTLVs(NdefMap, &CRFlag);
737         }
738         if (((NdefMap->StdMifareContainer.ReadNdefFlag ==
739               PH_FRINFC_MIFARESTD_FLAG1) ||
740              (NdefMap->StdMifareContainer.WrNdefFlag ==
741               PH_FRINFC_MIFARESTD_FLAG1)) &&
742             (Status != NFCSTATUS_PENDING)) {
743           NdefMap->StdMifareContainer.NFCforumSectFlag =
744               PH_FRINFC_MIFARESTD_FLAG1;
745           CRFlag = PH_FRINFC_MIFARESTD_FLAG0;
746           /* if the card state has changed to initialised and
747            read ndef is called then error is returned */
748           if (((NdefMap->StdMifareContainer.WrNdefFlag ==
749                 PH_FRINFC_MIFARESTD_FLAG1) &&
750                (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) ||
751               ((NdefMap->StdMifareContainer.ReadNdefFlag ==
752                 PH_FRINFC_MIFARESTD_FLAG1) &&
753                (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED))) {
754             Status =
755                 PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
756           }
757           if (NdefMap->StdMifareContainer.AuthDone ==
758               PH_FRINFC_MIFARESTD_FLAG0) {
759             Status = phFriNfc_MifStd_H_AuthSector(NdefMap);
760           } else {
761             Status = ((NdefMap->StdMifareContainer.ReadNdefFlag ==
762                        PH_FRINFC_MIFARESTD_FLAG1)
763                           ? phFriNfc_MifStd_H_RdTLV(NdefMap)
764                           : phFriNfc_MifStd_H_RdBeforeWr(NdefMap));
765           }
766           NdefMap->StdMifareContainer.ReadNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
767           NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
768         }
769 
770         if (NdefMap->StdMifareContainer.ChkNdefFlag ==
771             PH_FRINFC_MIFARESTD_FLAG1) {
772           CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
773                                  ? PH_FRINFC_MIFARESTD_FLAG1
774                                  : PH_FRINFC_MIFARESTD_FLAG0);
775         }
776         break;
777 
778       case PH_FRINFC_NDEFMAP_STATE_RD_BEF_WR:
779         /* Read flag says that already part of TLV has been written */
780         Status = phFriNfc_MifStd_H_ProBytesToWr(NdefMap);
781         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
782                                ? PH_FRINFC_MIFARESTD_FLAG1
783                                : PH_FRINFC_MIFARESTD_FLAG0);
784         break;
785 
786       case PH_FRINFC_NDEFMAP_STATE_WR_TLV:
787         Status = phFriNfc_MifStd_H_ProWrTLV(NdefMap);
788         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
789                                ? PH_FRINFC_MIFARESTD_FLAG1
790                                : PH_FRINFC_MIFARESTD_FLAG0);
791         break;
792 
793       case PH_FRINFC_NDEFMAP_STATE_RD_TLV:
794         Status = phFriNfc_MifStd_H_ProRdTLV(NdefMap);
795         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
796                                ? PH_FRINFC_MIFARESTD_FLAG1
797                                : PH_FRINFC_MIFARESTD_FLAG0);
798         break;
799 
800       case PH_FRINFC_NDEFMAP_STATE_TERM_TLV:
801         phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap);
802         NdefMap->StdMifareContainer.currentBlock =
803             NdefMap->TLVStruct.NdefTLVBlock;
804         Status = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap);
805         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
806                                ? PH_FRINFC_MIFARESTD_FLAG1
807                                : PH_FRINFC_MIFARESTD_FLAG0);
808         break;
809 
810       case PH_FRINFC_NDEFMAP_STATE_DISCONNECT:
811         NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG0;
812 
813         Status = phFriNfc_MifStd_H_CallConnect(NdefMap);
814         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
815                                ? PH_FRINFC_MIFARESTD_FLAG1
816                                : PH_FRINFC_MIFARESTD_FLAG0);
817         break;
818 
819       case PH_FRINFC_NDEFMAP_STATE_CONNECT:
820         if (NdefMap->StdMifareContainer.FirstReadFlag ==
821             PH_FRINFC_MIFARESTD_FLAG1) {
822           NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0;
823           Status = phFriNfc_MifStd_H_AuthSector(NdefMap);
824         } else if ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD ||
825                     NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD ||
826                     NdefMap->CardType ==
827                         PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) &&
828                    (NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
829                     NdefMap->StdMifareContainer.SectorTrailerBlockNo ==
830                         NdefMap->StdMifareContainer.currentBlock)) {
831           NdefMap->StdMifareContainer.ReadOnlySectorIndex =
832               PH_FRINFC_MIFARESTD_FLAG0;
833           NdefMap->StdMifareContainer.SectorTrailerBlockNo =
834               PH_FRINFC_MIFARESTD_FLAG0;
835           NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_FLAG0;
836           Status = NFCSTATUS_FAILED;
837         } else {
838           Status =
839               ((((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
840                  (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE)) ||
841                 (NdefMap->StdMifareContainer.WrLength >
842                  PH_FRINFC_MIFARESTD_VAL0))
843                    ? phFriNfc_MifStd_H_ProStatNotValid(NdefMap, Status)
844                    : phFriNfc_MifStd_H_AuthSector(NdefMap));
845         }
846         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
847                                ? PH_FRINFC_MIFARESTD_FLAG1
848                                : PH_FRINFC_MIFARESTD_FLAG0);
849         break;
850 
851       case PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT:
852         Status = phFriNfc_MifStd_H_ProSectorTrailorAcsBits(NdefMap);
853         CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
854                                ? PH_FRINFC_MIFARESTD_FLAG1
855                                : PH_FRINFC_MIFARESTD_FLAG0);
856         if ((CRFlag == PH_FRINFC_MIFARESTD_FLAG1) &&
857             (NdefMap->StdMifareContainer.WriteAcsBitFlag ==
858              PH_FRINFC_MIFARESTD_FLAG0)) {
859           Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
860                               NFCSTATUS_INVALID_DEVICE_REQUEST);
861         }
862         break;
863 
864       case PH_FRINFC_NDEFMAP_STATE_WRITE_SEC:
865         /* Set flag for writing of Acs bit */
866         NdefMap->StdMifareContainer.WriteAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG1;
867 
868         /* The first NDEF sector is already made read only,
869            set card state to read only and proceed*/
870         if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY) {
871           Status = phFriNfc_MapTool_SetCardState(
872               NdefMap, NdefMap->TLVStruct.BytesRemainLinTLV);
873           if (Status != NFCSTATUS_SUCCESS) {
874             CRFlag = (uint8_t)PH_FRINFC_MIFARESTD_FLAG1;
875           }
876         }
877 
878         if (CRFlag != PH_FRINFC_MIFARESTD_FLAG1) {
879           Status = phFriNfc_MifStd_H_ProWrSectorTrailor(NdefMap);
880           CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)
881                                  ? PH_FRINFC_MIFARESTD_FLAG1
882                                  : PH_FRINFC_MIFARESTD_FLAG0);
883         }
884         break;
885 
886       default:
887         Status =
888             PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST);
889         CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
890         break;
891     }
892   } else if (NdefMap->State == PH_FRINFC_NDEFMAP_STATE_AUTH) {
893     NdefMap->StdMifareContainer.PollFlag = PH_FRINFC_MIFARESTD_FLAG1;
894     if (NdefMap->StdMifareContainer.FirstWriteFlag ==
895         PH_FRINFC_MIFARESTD_FLAG1) {
896       NdefMap->StdMifareContainer.FirstWriteFlag = PH_FRINFC_MIFARESTD_FLAG0;
897       NdefMap->StdMifareContainer.WrLength =
898           ((NdefMap->StdMifareContainer.NFCforumSectFlag ==
899             PH_FRINFC_MIFARESTD_FLAG0)
900                ? PH_FRINFC_MIFARESTD_VAL1
901                : NdefMap->StdMifareContainer.WrLength);
902     }
903     if (NdefMap->StdMifareContainer.WrLength == PH_FRINFC_MIFARESTD_VAL0) {
904       Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
905                           NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
906       CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
907     } else {
908       /* Authentication has failed */
909       CRFlag = PH_FRINFC_MIFARESTD_FLAG1; /* Call Completion Routine */
910       Status = NFCSTATUS_FAILED;          /* Update Status Flag */
911     }
912   } else {
913     Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST);
914     CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
915   }
916   /* Call Completion Routine if CR Flag is Set to 1 */
917   if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) {
918     phFriNfc_MifStd_H_Complete(NdefMap, Status);
919   }
920 
921   return;
922 }
923 
924 /******************************************************************************
925  * Function         phFriNfc_MifStd_H_RdABlock
926  *
927  * Description      This function is a Helper function for Mifare Std. It Reads
928  *                  a block from the card.
929  *
930  * Returns          This function return NFCSTATUS_PENDING in case of success
931  *                  In case of failure returns other failure value.
932  *
933  ******************************************************************************/
phFriNfc_MifStd_H_RdABlock(phFriNfc_NdefMap_t * NdefMap)934 static NFCSTATUS phFriNfc_MifStd_H_RdABlock(phFriNfc_NdefMap_t* NdefMap) {
935   NFCSTATUS status = NFCSTATUS_PENDING;
936 
937   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_READ;
938   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
939   NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
940   NdefMap->MapCompletionInfo.Context = NdefMap;
941 
942   if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) {
943     if (NdefMap->StdMifareContainer.internalLength > PH_FRINFC_MIFARESTD_VAL0) {
944       status = phFriNfc_MifStd_H_ChkIntLen(NdefMap);
945     } /* internal Length Check */
946     else {
947       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
948           NdefMap->StdMifareContainer.currentBlock;
949       NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ;
950       *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
951 
952       NdefMap->Cmd.MfCmd = phHal_eMifareRead;
953 
954       /* Call the Overlapped HAL Transceive function */
955       status = phFriNfc_ExtnsTransceive(
956           NdefMap->pTransceiveInfo, NdefMap->Cmd, NdefMap->SendRecvBuf,
957           NdefMap->SendLength, NdefMap->SendRecvLength);
958     }
959   } else {
960     /* Check for the Card Size */
961     if ((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
962            NdefMap->StdMifareContainer.NdefBlocks) *
963           PH_FRINFC_MIFARESTD_BYTES_READ) == 0) ||
964         (NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex)) {
965       NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
966           (uint8_t)((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
967                        NdefMap->StdMifareContainer.NdefBlocks) *
968                       PH_FRINFC_MIFARESTD_BYTES_READ) == 0)
969                         ? PH_FRINFC_MIFARESTD_FLAG1
970                         : PH_FRINFC_MIFARESTD_FLAG0);
971       *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
972       status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
973     } else {
974       /* Error: The control should not ideally come here. Return Error. */
975       status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED);
976     }
977   }
978 
979   return status;
980 }
981 
982 /******************************************************************************
983  * Function         phFriNfc_MifStd_H_WrABlock
984  *
985  * Description      This function writes into a block of the card.
986  *
987  * Returns          This function return NFCSTATUS_PENDING in case of success
988  *                  In case of failure returns other failure value.
989  *
990  ******************************************************************************/
phFriNfc_MifStd_H_WrABlock(phFriNfc_NdefMap_t * NdefMap)991 static NFCSTATUS phFriNfc_MifStd_H_WrABlock(phFriNfc_NdefMap_t* NdefMap) {
992   NFCSTATUS status = NFCSTATUS_PENDING;
993 
994   uint16_t RemainingBytes = 0, BytesRemained = 0, index = 0;
995   uint8_t Temp16Bytes = 0;
996 
997   NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
998   NdefMap->MapCompletionInfo.Context = NdefMap;
999   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
1000 
1001   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WRITE;
1002 
1003   /* User Buffer Check */
1004   if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) {
1005     RemainingBytes =
1006         (((uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <
1007           NdefMap->StdMifareContainer.remainingSize)
1008              ? (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)
1009              : NdefMap->StdMifareContainer.remainingSize);
1010 
1011     NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock;
1012     Temp16Bytes += PH_FRINFC_MIFARESTD_INC_1;
1013 
1014     /* Check for internal bytes */
1015     if (NdefMap->StdMifareContainer.internalLength > 0) {
1016       /* copy the bytes previously written in the internal Buffer */
1017       memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]),
1018              NdefMap->StdMifareContainer.internalBuf,
1019              NdefMap->StdMifareContainer.internalLength);
1020 
1021       Temp16Bytes += (uint8_t)(NdefMap->StdMifareContainer.internalLength);
1022       if (RemainingBytes >= (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)) {
1023         /* Copy the Remaining bytes from the user buffer to make the send
1024             data and length = 16 */
1025         memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]), NdefMap->ApduBuffer,
1026                (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes));
1027 
1028         NdefMap->NumOfBytesWritten =
1029             (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes);
1030         Temp16Bytes += (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes);
1031         *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1);
1032       } else {
1033         memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]), NdefMap->ApduBuffer,
1034                RemainingBytes);
1035 
1036         NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG1;
1037         NdefMap->NumOfBytesWritten = RemainingBytes;
1038         Temp16Bytes += (uint8_t)(RemainingBytes);
1039         *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1);
1040 
1041         BytesRemained = (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes);
1042         /* Pad empty bytes with Zeroes to complete 16 bytes*/
1043         for (index = 0; index < BytesRemained; index++) {
1044           NdefMap->SendRecvBuf[(Temp16Bytes + index)] =
1045               (uint8_t)((index == PH_FRINFC_MIFARESTD_VAL0)
1046                             ? PH_FRINFC_MIFARESTD_TERMTLV_T
1047                             : PH_FRINFC_MIFARESTD_NULLTLV_T);
1048           NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1;
1049         }
1050         Temp16Bytes += (uint8_t)(BytesRemained);
1051       }
1052     } else {
1053       if (RemainingBytes >= (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes)) {
1054         /* Bytes left to write < 16, copy remaining bytes */
1055         memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]),
1056                &(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
1057                (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes));
1058 
1059         NdefMap->NumOfBytesWritten =
1060             (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes);
1061         Temp16Bytes += (MIFARE_MAX_SEND_BUF_TO_WRITE - Temp16Bytes);
1062         *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1);
1063       } else {
1064         /* Bytes left to write < 16, copy remaining bytes */
1065         memcpy(&(NdefMap->SendRecvBuf[Temp16Bytes]),
1066                &(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), RemainingBytes);
1067 
1068         NdefMap->StdMifareContainer.RemainingBufFlag =
1069             PH_FRINFC_MIFARESTD_FLAG1;
1070         NdefMap->NumOfBytesWritten = RemainingBytes;
1071         Temp16Bytes += (uint8_t)(RemainingBytes);
1072         *NdefMap->DataCount = (Temp16Bytes - PH_FRINFC_MIFARESTD_VAL1);
1073 
1074         /* Pad empty bytes with Zeroes to complete 16 bytes */
1075         for (index = Temp16Bytes; index < MIFARE_MAX_SEND_BUF_TO_WRITE;
1076              index++) {
1077           NdefMap->SendRecvBuf[index] =
1078               (uint8_t)((index == Temp16Bytes) ? PH_FRINFC_MIFARESTD_TERMTLV_T
1079                                                : PH_FRINFC_MIFARESTD_NULLTLV_T);
1080 
1081           NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1;
1082         }
1083       }
1084     }
1085     /* Buffer to store 16 bytes which is writing to the present block */
1086     memcpy(NdefMap->StdMifareContainer.Buffer,
1087            &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_INC_1]),
1088            PH_FRINFC_MIFARESTD_BLOCK_BYTES);
1089 
1090     /* Write from here */
1091     NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE;
1092     NdefMap->Cmd.MfCmd = phHal_eMifareWrite16;
1093     *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1094     /* Call the Overlapped HAL Transceive function */
1095     status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
1096                                       NdefMap->SendRecvBuf, NdefMap->SendLength,
1097                                       NdefMap->SendRecvLength);
1098   } else /* Check User Buffer */
1099   {
1100     if (NdefMap->StdMifareContainer.NdefBlocks >
1101         NdefMap->StdMifareContainer.NoOfNdefCompBlocks) {
1102       NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
1103           PH_FRINFC_MIFARESTD_FLAG1;
1104       status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
1105     } else if (NdefMap->ApduBuffIndex == (uint16_t)NdefMap->ApduBufferSize) {
1106       status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
1107     } else {
1108       /* Error: The control should not ideally come here. Return Error. */
1109       status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED);
1110     }
1111   }
1112 
1113   return status;
1114 }
1115 
1116 /******************************************************************************
1117  * Function         phFriNfc_MifStd_H_AuthSector
1118  *
1119  * Description      This function authenticates one sector at a time.
1120  *
1121  * Returns          This function return NFCSTATUS_PENDING in case of success
1122  *                  In case of failure returns other failure value.
1123  *
1124  ******************************************************************************/
phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t * NdefMap)1125 static NFCSTATUS phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t* NdefMap) {
1126   NFCSTATUS status = NFCSTATUS_PENDING;
1127 
1128   NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
1129   NdefMap->MapCompletionInfo.Context = NdefMap;
1130 
1131   *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1132   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_AUTH;
1133 
1134   /* Authenticate */
1135   NdefMap->Cmd.MfCmd = phHal_eMifareAuthentA;
1136 
1137   NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
1138       ((NdefMap->TLVStruct.NdefTLVAuthFlag == PH_FRINFC_MIFARESTD_FLAG1)
1139            ? NdefMap->TLVStruct.NdefTLVBlock
1140            : NdefMap->StdMifareContainer.currentBlock);
1141 
1142   /* if MAD blocks then authentication key is
1143       0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 else
1144       0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 */
1145   if (((NdefMap->StdMifareContainer.currentBlock !=
1146         PH_FRINFC_MIFARESTD_MAD_BLK0) &&
1147        (NdefMap->StdMifareContainer.currentBlock !=
1148         PH_FRINFC_MIFARESTD_MAD_BLK1) &&
1149        (NdefMap->StdMifareContainer.currentBlock !=
1150         PH_FRINFC_MIFARESTD_MAD_BLK2) &&
1151        (NdefMap->StdMifareContainer.currentBlock !=
1152         PH_FRINFC_MIFARESTD_MAD_BLK64) &&
1153        (NdefMap->StdMifareContainer.currentBlock !=
1154         PH_FRINFC_MIFARESTD_MAD_BLK65) &&
1155        (NdefMap->StdMifareContainer.currentBlock !=
1156         PH_FRINFC_MIFARESTD_MAD_BLK66)) ||
1157       (NdefMap->TLVStruct.NdefTLVAuthFlag ==
1158        (uint8_t)PH_FRINFC_MIFARESTD_FLAG1)) {
1159     NdefMap->SendRecvBuf[1] =
1160         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
1161     NdefMap->SendRecvBuf[2] =
1162         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
1163     NdefMap->SendRecvBuf[3] =
1164         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
1165     NdefMap->SendRecvBuf[4] =
1166         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
1167     NdefMap->SendRecvBuf[5] =
1168         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
1169     NdefMap->SendRecvBuf[6] =
1170         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
1171   } else {
1172     NdefMap->SendRecvBuf[1] =
1173         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT1; /* 0xA0 */
1174     NdefMap->SendRecvBuf[2] =
1175         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT2; /* 0xA1 */
1176     NdefMap->SendRecvBuf[3] =
1177         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT3; /* 0xA2 */
1178     NdefMap->SendRecvBuf[4] =
1179         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT4; /* 0xA3 */
1180     NdefMap->SendRecvBuf[5] =
1181         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5; /* 0xA4 */
1182     NdefMap->SendRecvBuf[6] =
1183         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6; /* 0xA5 */
1184   }
1185 
1186   if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD ||
1187       NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD ||
1188       NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) {
1189     if (NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
1190         NdefMap->StdMifareContainer.SectorTrailerBlockNo ==
1191             NdefMap->StdMifareContainer.currentBlock) {
1192       memcpy(&NdefMap->SendRecvBuf[1],
1193              &NdefMap->StdMifareContainer.UserScrtKeyB[0],
1194              PH_FRINFC_MIFARESTD_KEY_LEN);
1195 
1196       /* Authenticate with KeyB */
1197       NdefMap->Cmd.MfCmd = phHal_eMifareAuthentB;
1198     }
1199   }
1200 
1201   NdefMap->SendLength = MIFARE_AUTHENTICATE_CMD_LENGTH;
1202   *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1203   /* Call the Overlapped HAL Transceive function */
1204   status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
1205                                     NdefMap->SendRecvBuf, NdefMap->SendLength,
1206                                     NdefMap->SendRecvLength);
1207 
1208   return status;
1209 }
1210 
1211 /******************************************************************************
1212  * Function         phFriNfc_MifStd_H_Complete
1213  *
1214  * Description      It is used to call the Completion Routine
1215  *
1216  * Returns          void
1217  *
1218  ******************************************************************************/
phFriNfc_MifStd_H_Complete(phFriNfc_NdefMap_t * NdefMap,NFCSTATUS Result)1219 static void phFriNfc_MifStd_H_Complete(phFriNfc_NdefMap_t* NdefMap,
1220                                        NFCSTATUS Result) {
1221   /* set the state back to the Reset_Init state */
1222   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
1223 
1224   /* set the completion routine */
1225   NdefMap->CompletionRoutine[NdefMap->StdMifareContainer.CRIndex]
1226       .CompletionRoutine(NdefMap->CompletionRoutine->Context, Result);
1227 
1228   return;
1229 }
1230 
1231 /******************************************************************************
1232  * Function         phFriNfc_MifStd4k_H_CheckNdef
1233  *
1234  * Description      This function is used for Mifare 4k Check Ndef to
1235  *                  get the next AID blocks.
1236  *
1237  * Returns          This function return NFCSTATUS_SUCCESS in case of success
1238  *                  In case of failure returns other failure value.
1239  *
1240  ******************************************************************************/
phFriNfc_MifStd4k_H_CheckNdef(phFriNfc_NdefMap_t * NdefMap)1241 static NFCSTATUS phFriNfc_MifStd4k_H_CheckNdef(phFriNfc_NdefMap_t* NdefMap) {
1242   NFCSTATUS Result = NFCSTATUS_SUCCESS;
1243 
1244   /* Get the AID Block */
1245   if (NdefMap->StdMifareContainer.currentBlock ==
1246       PH_FRINFC_MIFARESTD_MAD_BLK2) {
1247     NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK64;
1248     NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
1249   } else if (NdefMap->StdMifareContainer.currentBlock ==
1250              PH_FRINFC_MIFARESTD_MAD_BLK64) {
1251     NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK65;
1252   } else {
1253     NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_MAD_BLK66;
1254   }
1255 
1256   Result = phFriNfc_MifareStdMap_ChkNdef(NdefMap);
1257 
1258   return Result;
1259 }
1260 
1261 /******************************************************************************
1262  * Function         phFriNfc_MifStd_H_fillAIDarray
1263  *
1264  * Description      This function storew the AIDs for check ndef.
1265  *
1266  * Returns          void
1267  *
1268  ******************************************************************************/
phFriNfc_MifStd_H_fillAIDarray(phFriNfc_NdefMap_t * NdefMap)1269 static void phFriNfc_MifStd_H_fillAIDarray(phFriNfc_NdefMap_t* NdefMap) {
1270   uint8_t byteindex = 0;
1271 
1272   if ((NdefMap->StdMifareContainer.currentBlock ==
1273        PH_FRINFC_MIFARESTD_MAD_BLK1) ||
1274       (NdefMap->StdMifareContainer.currentBlock ==
1275        PH_FRINFC_MIFARESTD_MAD_BLK64)) {
1276     /* The First Two Bytes in Receive Buffer
1277         are CRC bytes so it is not copied
1278         instead, 0 is copied in AID[0] & AID[1] */
1279     NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.SectorIndex] =
1280         PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
1281     NdefMap->StdMifareContainer.SectorIndex++;
1282     byteindex = 2;
1283   }
1284 
1285   while (byteindex < PH_FRINFC_MIFARESTD_BYTES_READ) {
1286     if ((NdefMap->SendRecvBuf[byteindex] ==
1287          PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL2) &&
1288         (NdefMap->SendRecvBuf[(byteindex + 1)] ==
1289          PH_FRINFC_NDEFMAP_MIFARESTD_NDEF_COMPVAL1)) {
1290       /* This flag is set when a NFC forum sector is found in a
1291           MAD block for the first time */
1292       NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG1;
1293       NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.SectorIndex] =
1294           PH_FRINFC_MIFARESTD_NDEF_COMP;
1295       NdefMap->StdMifareContainer.SectorIndex++;
1296     } else {
1297       NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.SectorIndex] =
1298           PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
1299       NdefMap->StdMifareContainer.SectorIndex++;
1300       /* AID complete flag is set when a non NFC forum sector is found in a
1301          MAD block after the NFC forum sector. After setting this, all other
1302          values are ignored and are NOT NDEF compliant */
1303       NdefMap->StdMifareContainer.aidCompleteFlag =
1304           ((NdefMap->StdMifareContainer.NFCforumSectFlag ==
1305             PH_FRINFC_MIFARESTD_FLAG1)
1306                ? PH_FRINFC_MIFARESTD_FLAG1
1307                : PH_FRINFC_MIFARESTD_FLAG0);
1308 
1309       NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0;
1310       if (NdefMap->StdMifareContainer.aidCompleteFlag ==
1311           PH_FRINFC_MIFARESTD_FLAG1) {
1312         break;
1313       }
1314     }
1315     byteindex += 2;
1316   }
1317 
1318   /* If "aidCompleteFlag" is set then the remaining sectors are made NOT
1319      NDEF compliant */
1320   if ((NdefMap->StdMifareContainer.aidCompleteFlag ==
1321        PH_FRINFC_MIFARESTD_FLAG1) &&
1322       (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) {
1323     /* for Mifare 1k there are 16 sectors, till this number all sectors
1324        are made NOT NDEF compliant */
1325     for (byteindex = NdefMap->StdMifareContainer.SectorIndex;
1326          byteindex < PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR; byteindex++) {
1327       NdefMap->StdMifareContainer.aid[byteindex] =
1328           PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
1329     }
1330   } else if ((NdefMap->StdMifareContainer.aidCompleteFlag ==
1331               PH_FRINFC_MIFARESTD_FLAG1) &&
1332              (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) {
1333     /* for Mifare 2k there are 32 sectors, till this number all sectors
1334        are made NOT NDEF compliant */
1335     for (byteindex = NdefMap->StdMifareContainer.SectorIndex;
1336          byteindex < PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR; byteindex++) {
1337       NdefMap->StdMifareContainer.aid[byteindex] =
1338           PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
1339     }
1340   } else {
1341     /* for Mifare 4k there are 40 sectors, till this number all sectors
1342        are made NOT NDEF compliant */
1343     if ((NdefMap->StdMifareContainer.aidCompleteFlag ==
1344          PH_FRINFC_MIFARESTD_FLAG1) &&
1345         (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)) {
1346       for (byteindex = NdefMap->StdMifareContainer.SectorIndex;
1347            byteindex < PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR; byteindex++) {
1348         NdefMap->StdMifareContainer.aid[byteindex] =
1349             PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
1350       }
1351     }
1352   }
1353 
1354   return;
1355 }
1356 
1357 /******************************************************************************
1358  * Function         phFriNfc_MifStd_H_BlkChk
1359  *
1360  * Description      This function is to check the Ndef compliance of the
1361  *                  current block, if the block is not Ndef Compliant,
1362  *                  increment the block till the next Ndef compliant block
1363  *                  using the Get Sector Helper function
1364  *
1365  * Returns          This function return NFCSTATUS_SUCCESS in case of success
1366  *                  In case of failure returns other failure value.
1367  *
1368  ******************************************************************************/
phFriNfc_MifStd_H_BlkChk(phFriNfc_NdefMap_t * NdefMap)1369 static NFCSTATUS phFriNfc_MifStd_H_BlkChk(phFriNfc_NdefMap_t* NdefMap) {
1370   NFCSTATUS Result = NFCSTATUS_SUCCESS;
1371   uint8_t SectorID = 0, callbreak = 0;
1372 
1373   for (;;) {
1374     /* Get a Sector ID for the Current Block */
1375     SectorID =
1376         phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock);
1377     /* Check the card Type 1k or 4k */
1378     /* enter if Mifare 1k card. For Mifare 4k go to else */
1379     if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) {
1380       /* if Sector Id > 15 No Sectors to write */
1381       if (SectorID > 15) {
1382         /*Error: No Ndef Compliant Sectors present */
1383         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
1384         callbreak = 1;
1385       } else {
1386         phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak);
1387       }
1388     } /* End of if */ /* End of Mifare 1k check */
1389     else if (NdefMap->CardType ==
1390              PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) /* Mifare 2k check starts
1391                                                       here */
1392     {
1393       /* Sector > 39 no ndef compliant sectors found*/
1394       if (SectorID > PH_FRINFC_MIFARESTD_SECTOR_NO31) {
1395         /*Error: No Ndef Compliant Sectors present */
1396         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
1397         callbreak = 1;
1398       } else if (NdefMap->StdMifareContainer.currentBlock ==
1399                  PH_FRINFC_MIFARESTD_MAD_BLK64) {
1400         NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4;
1401       } else if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) /* sector < 32
1402                                                                 contains 4
1403                                                                 blocks in each
1404                                                                 sector */
1405       {
1406         /* If the block checked is 63, the 3 blocks after this
1407             are AID(MAD) blocks so its need to be skipped */
1408         if (NdefMap->StdMifareContainer.currentBlock ==
1409             PH_FRINFC_MIFARESTD_MAD_BLK63) {
1410           NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4;
1411         } else {
1412           phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak);
1413         }
1414       }
1415     } /* End of if*/ /* End of Mifare 2k check*/
1416     else             /* Mifare 4k check starts here */
1417     {
1418       /* Sector > 39 no ndef compliant sectors found*/
1419       if (SectorID > PH_FRINFC_MIFARESTD_SECTOR_NO39) {
1420         /*Error: No Ndef Compliant Sectors present */
1421         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
1422         callbreak = 1;
1423       } else if (NdefMap->StdMifareContainer.currentBlock ==
1424                  PH_FRINFC_MIFARESTD_MAD_BLK64) {
1425         NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4;
1426       } else if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) /* sector < 32
1427                                                                 contains 4
1428                                                                 blocks in each
1429                                                                 sector */
1430       {
1431         /* If the block checked is 63, the 3 blocks after this
1432            are AID(MAD) blocks so its need to be skipped */
1433         if (NdefMap->StdMifareContainer.currentBlock ==
1434             PH_FRINFC_MIFARESTD_MAD_BLK63) {
1435           NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4;
1436         } else {
1437           phFriNfc_MifStd1k_H_BlkChk(NdefMap, SectorID, &callbreak);
1438         }
1439       } else {
1440         /* every last block of a sector needs to be skipped */
1441         if (((NdefMap->StdMifareContainer.currentBlock + 1) %
1442              PH_FRINFC_MIFARESTD_BLOCK_BYTES) == 0) {
1443           NdefMap->StdMifareContainer.currentBlock++;
1444         } else {
1445           if (NdefMap->StdMifareContainer.aid[SectorID] ==
1446               PH_FRINFC_MIFARESTD_NDEF_COMP) {
1447             /* Check whether the block is first block of a (next)new sector and
1448                 also check if it is first block then internal length is zero
1449                 or not. Because once Authentication is done for the sector again
1450                 we should not authenticate it again */
1451             /* In this case 32 sectors contains 4 blocks and next remaining 8
1452                sectors contains 16 blocks that is why (32 * 4) + (sectorID - 32)
1453                *16*/
1454             if ((NdefMap->StdMifareContainer.currentBlock ==
1455                  ((PH_FRINFC_MIFARESTD_SECTOR_NO32 * PH_FRINFC_MIFARESTD_BLK4) +
1456                   ((SectorID - PH_FRINFC_MIFARESTD_SECTOR_NO32) *
1457                    PH_FRINFC_MIFARESTD_BLOCK_BYTES))) &&
1458                 (NdefMap->StdMifareContainer.internalLength == 0)) {
1459               NdefMap->StdMifareContainer.AuthDone = 0;
1460             }
1461             callbreak = 1;
1462           } else {
1463             NdefMap->StdMifareContainer.currentBlock += 16;
1464           }
1465         }
1466       }
1467     }
1468     if (callbreak == 1) {
1469       break;
1470     }
1471   }
1472 
1473   return Result;
1474 }
1475 
1476 /******************************************************************************
1477  * Function         phFriNfc_MifStd_H_GetSect
1478  *
1479  * Description      This function  to get the Sector from the current block
1480  *
1481  * Returns          uint8_t SectorID
1482  *
1483  ******************************************************************************/
phFriNfc_MifStd_H_GetSect(uint8_t BlockNumber)1484 static uint8_t phFriNfc_MifStd_H_GetSect(uint8_t BlockNumber) {
1485   uint8_t SectorID = 0;
1486 
1487   if (BlockNumber >= PH_FRINFC_MIFARESTD4K_BLK128) {
1488     SectorID = (uint8_t)(PH_FRINFC_MIFARESTD_SECTOR_NO32 +
1489                          ((BlockNumber - PH_FRINFC_MIFARESTD4K_BLK128) /
1490                           PH_FRINFC_MIFARESTD_BLOCK_BYTES));
1491   } else {
1492     SectorID = (BlockNumber / PH_FRINFC_MIFARESTD_BLK4);
1493   }
1494 
1495   return SectorID;
1496 }
1497 
1498 /******************************************************************************
1499  * Function         phFriNfc_MifStd_H_RdAcsBit
1500  *
1501  * Description      It read the access bits of each sector.
1502  *                  NCI messages.
1503  *
1504  * Returns          This function return NFCSTATUS_SUCCESS in case of success
1505  *                  In case of failure returns other failure value.
1506  *
1507  ******************************************************************************/
phFriNfc_MifStd_H_RdAcsBit(phFriNfc_NdefMap_t * NdefMap)1508 static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit(phFriNfc_NdefMap_t* NdefMap) {
1509   NFCSTATUS Result = NFCSTATUS_SUCCESS;
1510 
1511   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT;
1512 
1513   if (NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
1514       NdefMap->StdMifareContainer.currentBlock ==
1515           NdefMap->StdMifareContainer.SectorTrailerBlockNo) {
1516     NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT;
1517   }
1518 
1519   if (NdefMap->StdMifareContainer.ReadAcsBitFlag == PH_FRINFC_MIFARESTD_FLAG1) {
1520     /* Get the sector trailer */
1521     ((NdefMap->StdMifareContainer.currentBlock > 127)
1522          ? phFriNfc_MifStd_H_Get4kStTrail(NdefMap)
1523          : phFriNfc_MifStd_H_Get1kStTrail(NdefMap));
1524   } else {
1525     /* Give the current block to read */
1526     NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
1527         NdefMap->StdMifareContainer.currentBlock;
1528   }
1529 
1530   Result = phFriNfc_MifStd_H_Rd16Bytes(
1531       NdefMap, NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0]);
1532 
1533   return Result;
1534 }
1535 
1536 /******************************************************************************
1537  * Function         phFriNfc_MifStd_H_ChkAcsBit
1538  *
1539  * Description      This function check the access bits of each sector.
1540  *
1541  * Returns          This function return NFCSTATUS_SUCCESS in case of success
1542  *                  In case of failure returns other failure value.
1543  *
1544  ******************************************************************************/
phFriNfc_MifStd_H_ChkAcsBit(phFriNfc_NdefMap_t * NdefMap)1545 static NFCSTATUS phFriNfc_MifStd_H_ChkAcsBit(phFriNfc_NdefMap_t* NdefMap) {
1546   NFCSTATUS Result = NFCSTATUS_SUCCESS;
1547 
1548   /* Blocks from 0 to 3 and from 64 to 67(MAD blocks) */
1549   if ((NdefMap->StdMifareContainer.currentBlock ==
1550        PH_FRINFC_MIFARESTD_MAD_BLK0) ||
1551       (NdefMap->StdMifareContainer.currentBlock ==
1552        PH_FRINFC_MIFARESTD_MAD_BLK1) ||
1553       (NdefMap->StdMifareContainer.currentBlock ==
1554        PH_FRINFC_MIFARESTD_MAD_BLK2) ||
1555       (NdefMap->StdMifareContainer.currentBlock ==
1556        PH_FRINFC_MIFARESTD_MAD_BLK3) ||
1557       (NdefMap->StdMifareContainer.currentBlock ==
1558        PH_FRINFC_MIFARESTD_MAD_BLK64) ||
1559       (NdefMap->StdMifareContainer.currentBlock ==
1560        PH_FRINFC_MIFARESTD_MAD_BLK65) ||
1561       (NdefMap->StdMifareContainer.currentBlock ==
1562        PH_FRINFC_MIFARESTD_MAD_BLK66)) {
1563 /* Access bits check removed for the MAD blocks */
1564 #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD
1565 
1566     if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL6] &
1567           PH_FRINFC_MIFARESTD_MASK_FF) ==
1568          PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE6) &&
1569         ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL7] &
1570           PH_FRINFC_MIFARESTD_MASK_FF) ==
1571          PH_FRINFC_MIFARESTD_MADSECT_ACS_BYTE7) &&
1572         ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL8] &
1573           PH_FRINFC_MIFARESTD_MASK_FF) == PH_FRINFC_MIFARESTD_ACS_BYTE8)) {
1574       NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0;
1575       NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG1;
1576     } else {
1577       NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0;
1578       NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG0;
1579     }
1580 
1581 #else /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */
1582 
1583     NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
1584 
1585 #endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */
1586   } else {
1587     /* Check for Access bytes 6, 7 and 8 value =
1588         0x7F, 0x07, 0x88 NFC forum sectors*/
1589     if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL6] &
1590           PH_FRINFC_MIFARESTD_MASK_FF) ==
1591          PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE6) &&
1592         ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL7] &
1593           PH_FRINFC_MIFARESTD_MASK_FF) ==
1594          PH_FRINFC_MIFARESTD_NFCSECT_ACS_BYTE7) &&
1595         ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL8] &
1596           PH_FRINFC_MIFARESTD_MASK_FF) == PH_FRINFC_MIFARESTD_ACS_BYTE8)) {
1597       NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG1;
1598       NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG1;
1599     } else if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL6] &
1600                  PH_FRINFC_MIFARESTD_MASK_FF) ==
1601                 PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6) &&
1602                ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL7] &
1603                  PH_FRINFC_MIFARESTD_MASK_FF) ==
1604                 PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7) &&
1605                ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL8] &
1606                  PH_FRINFC_MIFARESTD_MASK_FF) ==
1607                 PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8)) {
1608       /* Read Only state */
1609       /* Check for Access bytes 6, 7 and 8 value =
1610           0x55, 0xAD, 0x2A NFC forum Sectors */
1611       NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0;
1612       NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG1;
1613     } else {
1614       NdefMap->StdMifareContainer.WriteFlag = PH_FRINFC_MIFARESTD_FLAG0;
1615       NdefMap->StdMifareContainer.ReadFlag = PH_FRINFC_MIFARESTD_FLAG0;
1616     }
1617 
1618 #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD
1619 /* Do nothing */
1620 #else  /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */
1621     Result = phFriNfc_MifStd_H_GPBChk(NdefMap);
1622 #endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */
1623   }
1624 
1625 #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD
1626   Result = phFriNfc_MifStd_H_GPBChk(NdefMap);
1627 #endif /* #ifdef ENABLE_ACS_BIT_CHK_FOR_MAD */
1628 
1629   return Result;
1630 }
1631 
1632 /******************************************************************************
1633  * Function         phFriNfc_MifStd_H_ChkRdWr
1634  *
1635  * Description      This function is for read access bits, depending
1636  *                  on the read/write/check ndef function called.
1637  *
1638  * Returns          This function return NFCSTATUS_SUCCESS in case of success
1639  *                  In case of failure returns other failure value.
1640  *
1641  ******************************************************************************/
phFriNfc_MifStd_H_ChkRdWr(phFriNfc_NdefMap_t * NdefMap)1642 static NFCSTATUS phFriNfc_MifStd_H_ChkRdWr(phFriNfc_NdefMap_t* NdefMap) {
1643   NFCSTATUS Result = NFCSTATUS_SUCCESS;
1644 
1645   switch (NdefMap->PrevOperation) {
1646     case PH_FRINFC_NDEFMAP_CHECK_OPE:
1647       if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) {
1648         /* No permission to read */
1649         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED);
1650       } else if ((NdefMap->StdMifareContainer.currentBlock > 3) &&
1651                  (NdefMap->StdMifareContainer.ChkNdefCompleteFlag ==
1652                   PH_FRINFC_MIFARESTD_FLAG1) &&
1653                  (NdefMap->StdMifareContainer.currentBlock !=
1654                   PH_FRINFC_MIFARESTD_MAD_BLK65) &&
1655                  (NdefMap->StdMifareContainer.currentBlock !=
1656                   PH_FRINFC_MIFARESTD_MAD_BLK66)) {
1657         Result = ((NdefMap->StdMifareContainer.ReadAcsBitFlag ==
1658                    PH_FRINFC_MIFARESTD_FLAG0)
1659                       ? phFriNfc_MifStd_H_RdAcsBit(NdefMap)
1660                       : phFriNfc_MifStd_H_AuthSector(NdefMap));
1661       } else {
1662         Result = phFriNfc_MifareStdMap_ChkNdef(NdefMap);
1663       }
1664       break;
1665 
1666     case PH_FRINFC_NDEFMAP_READ_OPE:
1667       if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) {
1668         /* No permission to Read */
1669         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED);
1670       } else if (NdefMap->StdMifareContainer.ReadNdefFlag ==
1671                  PH_FRINFC_MIFARESTD_FLAG1) {
1672         Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap);
1673       } else {
1674         Result = phFriNfc_MifStd_H_RdABlock(NdefMap);
1675       }
1676       break;
1677 
1678     case PH_FRINFC_NDEFMAP_WRITE_OPE:
1679       if ((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) ||
1680           (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)) {
1681         /* No permission to Read */
1682         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_WRITE_FAILED);
1683       } else if (NdefMap->StdMifareContainer.WrNdefFlag ==
1684                  PH_FRINFC_MIFARESTD_FLAG1) {
1685         Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap);
1686       } else if (NdefMap->StdMifareContainer.RdBeforeWrFlag ==
1687                  PH_FRINFC_MIFARESTD_FLAG1) {
1688         /*NdefMap->StdMifareContainer.ReadFlag =
1689                         PH_FRINFC_MIFARESTD_FLAG0;*/
1690         Result = phFriNfc_MifStd_H_RdBeforeWr(NdefMap);
1691       } else if (NdefMap->StdMifareContainer.RdAfterWrFlag ==
1692                  PH_FRINFC_MIFARESTD_FLAG1) {
1693         Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap);
1694       } else {
1695         Result = (((NdefMap->TLVStruct.NdefTLVBlock ==
1696                     NdefMap->StdMifareContainer.currentBlock) &&
1697                    (NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN))
1698                       ? phFriNfc_MifStd_H_RdBeforeWr(NdefMap)
1699                       : phFriNfc_MifStd_H_WrABlock(NdefMap));
1700       }
1701       break;
1702 
1703     case PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE:
1704       Result =
1705           ((NdefMap->StdMifareContainer.ReadFlag == PH_FRINFC_MIFARESTD_FLAG0)
1706                ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED))
1707                : phFriNfc_MifStd_H_GetActCardLen(NdefMap));
1708       break;
1709 
1710     default:
1711       /* Operation is not correct */
1712       Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
1713 
1714       break;
1715   }
1716 
1717   return Result;
1718 }
1719 
1720 /******************************************************************************
1721  * Function         phFriNfc_MifStd_H_ChkNdefCmpltSects
1722  *
1723  * Description      This function is used to check ndef to check the
1724  *                  ndef compliant sectors.
1725  *
1726  * Returns          void
1727  *
1728  ******************************************************************************/
phFriNfc_MifStd_H_ChkNdefCmpltSects(phFriNfc_NdefMap_t * NdefMap)1729 static void phFriNfc_MifStd_H_ChkNdefCmpltSects(phFriNfc_NdefMap_t* NdefMap) {
1730   uint8_t index = 0;
1731   uint8_t index_max_4k_2k = 0;
1732   if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) {
1733     index_max_4k_2k = PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR;
1734   } else {
1735     index_max_4k_2k = PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR;
1736   }
1737 
1738   if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD ||
1739       NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD) {
1740     for (index = PH_FRINFC_MIFARESTD_SECTOR_NO1; index < index_max_4k_2k;
1741          index++) /*Block 0 is MAD block, so it should start with 1*/
1742     {
1743       /* For Mifare 4k, Block 0 to 31 contains 4 blocks */
1744       /* sector 0 and 15 are aid blocks */
1745       if (index != PH_FRINFC_MIFARESTD_SECTOR_NO16) {
1746         if (((index < 32) && (index != PH_FRINFC_MIFARESTD_SECTOR_NO0)) &&
1747             (NdefMap->StdMifareContainer.aid[index] ==
1748              PH_FRINFC_MIFARESTD_NON_NDEF_COMP)) {
1749           /* Only 3 blocks can be read/written till sector 31 */
1750           NdefMap->StdMifareContainer.NoOfNdefCompBlocks -=
1751               PH_FRINFC_MIFARESTD_MAD_BLK3;
1752 
1753         } else {
1754           /* For Mifare 4k, Block 32 to 39 contains 16 blocks */
1755           if (NdefMap->StdMifareContainer.aid[index] ==
1756               PH_FRINFC_MIFARESTD_NON_NDEF_COMP) {
1757             /* Only 15 blocks can be read/written from sector 31 */
1758             NdefMap->StdMifareContainer.NoOfNdefCompBlocks -=
1759                 PH_FRINFC_MIFARESTD_BLK15;
1760           }
1761         }
1762       }
1763     } /* For index > 40 */
1764   } else {
1765     for (index = PH_FRINFC_MIFARESTD_SECTOR_NO1;
1766          index < PH_FRINFC_MIFARESTD_SECTOR_NO16; index++) {
1767       if (NdefMap->StdMifareContainer.aid[index] ==
1768           PH_FRINFC_MIFARESTD_NON_NDEF_COMP) {
1769         /*  Only three blocks can be read/written in
1770             a sector. So if a sector is non-ndef
1771             compliant, decrement 3 */
1772         NdefMap->StdMifareContainer.NoOfNdefCompBlocks -=
1773             PH_FRINFC_MIFARESTD_MAD_BLK3;
1774       }
1775     }
1776   }
1777 
1778   return;
1779 }
1780 
1781 /******************************************************************************
1782  * Function         phFriNfc_MifStd_H_RemainTLV
1783  *
1784  * Description      This function is used for read ndef to process the
1785  *                  remaining bytes of length (L) in the TLV.
1786  *
1787  * Returns          This function return NFCSTATUS_PENDING in case of success
1788  *                  In case of failure returns other failure value.
1789  *
1790  ******************************************************************************/
phFriNfc_MifStd_H_RemainTLV(phFriNfc_NdefMap_t * NdefMap,uint8_t * Flag,uint8_t * Temp16Bytes)1791 static NFCSTATUS phFriNfc_MifStd_H_RemainTLV(phFriNfc_NdefMap_t* NdefMap,
1792                                              uint8_t* Flag,
1793                                              uint8_t* Temp16Bytes) {
1794   NFCSTATUS Result = NFCSTATUS_SUCCESS;
1795   uint8_t CRFlag = 0;
1796   uint16_t RemainingBytes = 0;
1797 
1798   RemainingBytes = ((uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
1799 
1800   if (NdefMap->StdMifareContainer.remainingSize < RemainingBytes) {
1801     /* If the user Buffer is greater than the Card Size
1802        set LastBlockFlag = 1. This Flag is used to read bytes
1803        till the end of the card only */
1804     RemainingBytes = NdefMap->StdMifareContainer.remainingSize;
1805   }
1806 
1807   /* Remaining Bytes of length (L) in TLV <=  16 */
1808   if ((NdefMap->TLVStruct.BytesRemainLinTLV <=
1809        (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) &&
1810       (RemainingBytes <= NdefMap->TLVStruct.BytesRemainLinTLV)) {
1811     /* Copy data to user buffer */
1812     memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
1813            &(NdefMap->SendRecvBuf[(*Temp16Bytes)]), RemainingBytes);
1814 
1815     NdefMap->ApduBuffIndex += RemainingBytes;
1816     NdefMap->StdMifareContainer.remainingSize -= RemainingBytes;
1817 
1818     /* copy the bytes to internal buffer, that are read,
1819        but not used for the user buffer */
1820     if (RemainingBytes != NdefMap->TLVStruct.BytesRemainLinTLV) {
1821       memcpy(
1822           NdefMap->StdMifareContainer.internalBuf,
1823           &(NdefMap->SendRecvBuf[((*Temp16Bytes) + RemainingBytes)]),
1824           ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes));
1825 
1826       /* internal buffer length */
1827       NdefMap->StdMifareContainer.internalLength =
1828           ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes);
1829     }
1830     *Temp16Bytes += ((uint8_t)RemainingBytes);
1831     /* Remaining Bytes of length value in TLV */
1832     NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes;
1833 
1834     if (NdefMap->StdMifareContainer.internalLength ==
1835         PH_FRINFC_MIFARESTD_VAL0) {
1836       NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)(
1837           ((NdefMap->StdMifareContainer.remainingSize ==
1838             PH_FRINFC_MIFARESTD_VAL0) ||
1839            (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))
1840               ? PH_FRINFC_MIFARESTD_FLAG1
1841               : PH_FRINFC_MIFARESTD_FLAG0);
1842 
1843       /* internal length bytes completed */
1844       NdefMap->StdMifareContainer.currentBlock++;
1845       NdefMap->StdMifareContainer.NdefBlocks++;
1846     }
1847 
1848     if (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0) {
1849       /* Remaining Bytes of length (L) in TLV is Zero means that the next
1850          coming bytes are containing type (T), length (L) in TLV */
1851       NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1;
1852       NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
1853       NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
1854     }
1855     /* call completion routine */
1856     CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
1857     *Flag = PH_FRINFC_MIFARESTD_FLAG0;
1858   } else if ((NdefMap->TLVStruct.BytesRemainLinTLV <=
1859               (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) &&
1860              (RemainingBytes > NdefMap->TLVStruct.BytesRemainLinTLV)) {
1861     /* Copy data to user buffer */
1862     memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
1863            &(NdefMap->SendRecvBuf[(*Temp16Bytes)]),
1864            NdefMap->TLVStruct.BytesRemainLinTLV);
1865 
1866     NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV;
1867     NdefMap->StdMifareContainer.remainingSize -=
1868         NdefMap->TLVStruct.BytesRemainLinTLV;
1869     NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1;
1870     *Temp16Bytes += ((uint8_t)NdefMap->TLVStruct.BytesRemainLinTLV);
1871     NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0;
1872 
1873     *Flag = PH_FRINFC_MIFARESTD_FLAG1;
1874 
1875     NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
1876     NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
1877     /* 16 bytes completed */
1878     if (NdefMap->TLVStruct.BytesRemainLinTLV ==
1879         PH_FRINFC_MIFARESTD_BYTES_READ) {
1880       *Flag = PH_FRINFC_MIFARESTD_FLAG0;
1881       NdefMap->TLVStruct.BytesRemainLinTLV =
1882           PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0;
1883       NdefMap->StdMifareContainer.currentBlock++;
1884       NdefMap->StdMifareContainer.NdefBlocks++;
1885       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
1886       if (Result == NFCSTATUS_SUCCESS) {
1887         if (NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1) {
1888           Result = phFriNfc_MifStd_H_RdABlock(NdefMap);
1889         } else {
1890           Result = phFriNfc_MifStd_H_AuthSector(NdefMap);
1891         }
1892       }
1893     } else {
1894       NdefMap->TLVStruct.BytesRemainLinTLV =
1895           PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0;
1896       /* The read operation has finished. so, completion routine
1897          can be called. set the Completion routine(CR) flag */
1898       CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
1899     }
1900   } else if ((NdefMap->TLVStruct.BytesRemainLinTLV >
1901               (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) &&
1902              (RemainingBytes <=
1903               (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)))) {
1904     /* Copy data to user buffer */
1905     memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
1906            &(NdefMap->SendRecvBuf[(*Temp16Bytes)]), RemainingBytes);
1907     NdefMap->ApduBuffIndex += RemainingBytes;
1908     NdefMap->StdMifareContainer.remainingSize -= RemainingBytes;
1909 
1910     /* Remaining Bytes of length (L) in TLV */
1911     NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes;
1912     /* copy the bytes to internal buffer, that are read,
1913                     but not used for the user buffer */
1914     memcpy(
1915         NdefMap->StdMifareContainer.internalBuf,
1916         &(NdefMap->SendRecvBuf[(RemainingBytes + (*Temp16Bytes))]),
1917         ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes));
1918 
1919     /* internal buffer length */
1920     NdefMap->StdMifareContainer.internalLength =
1921         ((PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)) - RemainingBytes);
1922 
1923     if (RemainingBytes == (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) {
1924       NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)(
1925           ((NdefMap->StdMifareContainer.remainingSize ==
1926             PH_FRINFC_MIFARESTD_VAL0) ||
1927            (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))
1928               ? PH_FRINFC_MIFARESTD_FLAG1
1929               : PH_FRINFC_MIFARESTD_FLAG0);
1930 
1931       /* internal length bytes completed */
1932       NdefMap->StdMifareContainer.currentBlock++;
1933       NdefMap->StdMifareContainer.NdefBlocks++;
1934     }
1935     *Temp16Bytes += ((uint8_t)RemainingBytes);
1936     NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
1937     CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
1938     *Flag = PH_FRINFC_MIFARESTD_FLAG0;
1939   } else {
1940     if ((NdefMap->TLVStruct.BytesRemainLinTLV >
1941          (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes))) &&
1942         (RemainingBytes > (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)))) {
1943       *Flag = PH_FRINFC_MIFARESTD_FLAG0;
1944       /* Copy data to user buffer */
1945       memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
1946              &(NdefMap->SendRecvBuf[(*Temp16Bytes)]),
1947              (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes)));
1948       NdefMap->ApduBuffIndex +=
1949           (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes));
1950       NdefMap->StdMifareContainer.remainingSize -=
1951           (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes));
1952       NdefMap->TLVStruct.BytesRemainLinTLV -=
1953           (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes));
1954       *Temp16Bytes += (PH_FRINFC_MIFARESTD_BYTES_READ - (*Temp16Bytes));
1955       if (NdefMap->TLVStruct.BytesRemainLinTLV !=
1956           PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0) {
1957         NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
1958       }
1959       /* 16 bytes completed */
1960       NdefMap->StdMifareContainer.currentBlock++;
1961       NdefMap->StdMifareContainer.NdefBlocks++;
1962       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
1963       if (Result == NFCSTATUS_SUCCESS) {
1964         Result =
1965             ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1)
1966                  ? phFriNfc_MifStd_H_RdABlock(NdefMap)
1967                  : phFriNfc_MifStd_H_AuthSector(NdefMap));
1968       }
1969     }
1970   }
1971 
1972   if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) {
1973     *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
1974     NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)(
1975         ((NdefMap->StdMifareContainer.remainingSize ==
1976           PH_FRINFC_MIFARESTD_VAL0) ||
1977          (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))
1978             ? PH_FRINFC_MIFARESTD_FLAG1
1979             : PH_FRINFC_MIFARESTD_FLAG0);
1980   }
1981 
1982   return Result;
1983 }
1984 
1985 /******************************************************************************
1986  * Function         phFriNfc_MifStd_H_ChkIntLen
1987  *
1988  * Description      This function reads ndef to process the internal bytes.
1989  *
1990  * Returns          This function return NFCSTATUS_SUCCESS in case of success,
1991  *                  In case of failure returns other failure value.
1992  *
1993  ******************************************************************************/
phFriNfc_MifStd_H_ChkIntLen(phFriNfc_NdefMap_t * NdefMap)1994 static NFCSTATUS phFriNfc_MifStd_H_ChkIntLen(phFriNfc_NdefMap_t* NdefMap) {
1995   NFCSTATUS Result = NFCSTATUS_SUCCESS;
1996   uint8_t NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1;
1997   uint8_t TempintBytes = 0;
1998 
1999   if (NdefMap->TLVStruct.BytesRemainLinTLV != 0) {
2000     NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
2001     /* To read the remaining length (L) in TLV */
2002     Result =
2003         phFriNfc_MifStd_H_IntLenWioutNdef(NdefMap, &NDEFFlag, &TempintBytes);
2004   }
2005   NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
2006   /* check the NDEFFlag is set. if this is not set, then
2007      in the above RemainTLV function all the 16 bytes has been
2008      read */
2009 
2010   return Result;
2011 }
2012 
2013 /******************************************************************************
2014  * Function         phFriNfc_MifStd_H_IntLenWioutNdef
2015  *
2016  * Description      This function reads ndef to check the internal bytes
2017  *                  without ndef tlv flag.
2018  *
2019  * Returns          This function return NFCSTATUS_SUCCESS in case of success,
2020  *                  In case of failure returns other failure value.
2021  *
2022  ******************************************************************************/
phFriNfc_MifStd_H_IntLenWioutNdef(phFriNfc_NdefMap_t * NdefMap,uint8_t * Flag,uint8_t * TempintBytes)2023 static NFCSTATUS phFriNfc_MifStd_H_IntLenWioutNdef(phFriNfc_NdefMap_t* NdefMap,
2024                                                    uint8_t* Flag,
2025                                                    uint8_t* TempintBytes) {
2026   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2027   uint8_t CRFlag = 0;
2028   uint16_t RemainingBytes = 0;
2029 
2030   RemainingBytes = ((uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
2031 
2032   if (NdefMap->StdMifareContainer.remainingSize < RemainingBytes) {
2033     /* If the user Buffer is greater than the Card Size
2034        set LastBlockFlag = 1. This Flag is used to read bytes
2035        till the end of the card only */
2036     RemainingBytes = NdefMap->StdMifareContainer.remainingSize;
2037   }
2038 
2039   /* Remaining Bytes of length (L) in TLV <=  internal length */
2040   if ((NdefMap->TLVStruct.BytesRemainLinTLV <=
2041        NdefMap->StdMifareContainer.internalLength) &&
2042       (RemainingBytes <= NdefMap->TLVStruct.BytesRemainLinTLV)) {
2043     memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
2044            &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]),
2045            RemainingBytes);
2046     NdefMap->ApduBuffIndex += RemainingBytes;
2047     NdefMap->StdMifareContainer.remainingSize -= RemainingBytes;
2048     *TempintBytes += ((uint8_t)RemainingBytes);
2049 
2050     /* copy the bytes to internal buffer, that are read,
2051        but not used for the user buffer */
2052     memcpy(NdefMap->StdMifareContainer.internalBuf,
2053            &(NdefMap->StdMifareContainer.internalBuf[RemainingBytes]),
2054            (NdefMap->StdMifareContainer.internalLength - RemainingBytes));
2055 
2056     /* internal buffer length */
2057     NdefMap->StdMifareContainer.internalLength -= RemainingBytes;
2058 
2059     NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes;
2060     if (NdefMap->StdMifareContainer.internalLength ==
2061         PH_FRINFC_MIFARESTD_VAL0) {
2062       NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)(
2063           ((NdefMap->StdMifareContainer.remainingSize ==
2064             PH_FRINFC_MIFARESTD_VAL0) ||
2065            (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))
2066               ? PH_FRINFC_MIFARESTD_FLAG1
2067               : PH_FRINFC_MIFARESTD_FLAG0);
2068 
2069       /* internal length bytes completed */
2070       NdefMap->StdMifareContainer.currentBlock++;
2071       NdefMap->StdMifareContainer.NdefBlocks++;
2072     }
2073 
2074     /* Remaining Bytes of length value in TLV */
2075     if (NdefMap->TLVStruct.BytesRemainLinTLV == 0) {
2076       /* Remaining Bytes of length (L) in TLV is Zero means that the next
2077        coming bytes are containing type (T), length (L) in TLV */
2078       NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1;
2079       NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2080       NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2081     }
2082     /* call completion routine */
2083     CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2084     *Flag = PH_FRINFC_MIFARESTD_FLAG0;
2085   } else if ((NdefMap->TLVStruct.BytesRemainLinTLV <=
2086               NdefMap->StdMifareContainer.internalLength) &&
2087              (RemainingBytes > NdefMap->TLVStruct.BytesRemainLinTLV)) {
2088     memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
2089            &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]),
2090            NdefMap->TLVStruct.BytesRemainLinTLV);
2091 
2092     NdefMap->ApduBuffIndex += NdefMap->TLVStruct.BytesRemainLinTLV;
2093     NdefMap->StdMifareContainer.remainingSize -=
2094         NdefMap->TLVStruct.BytesRemainLinTLV;
2095     NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG1;
2096 
2097     *TempintBytes += ((uint8_t)NdefMap->TLVStruct.BytesRemainLinTLV);
2098     *Flag = PH_FRINFC_MIFARESTD_FLAG1;
2099 
2100     NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2101     NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2102 
2103     NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0;
2104     NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)(
2105         ((NdefMap->StdMifareContainer.remainingSize ==
2106           PH_FRINFC_MIFARESTD_VAL0) ||
2107          (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))
2108             ? PH_FRINFC_MIFARESTD_FLAG1
2109             : PH_FRINFC_MIFARESTD_FLAG0);
2110 
2111     if (PH_FRINFC_MIFARESTD_FLAG1 ==
2112         NdefMap->StdMifareContainer.ReadWriteCompleteFlag) {
2113       CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2114     }
2115 
2116     if (NdefMap->TLVStruct.BytesRemainLinTLV ==
2117         NdefMap->StdMifareContainer.internalLength) {
2118       /* Remaining Bytes in Length (L) field of TLV is 0 */
2119       NdefMap->TLVStruct.BytesRemainLinTLV =
2120           PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0;
2121       NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0;
2122       *Flag = PH_FRINFC_MIFARESTD_FLAG0;
2123       /* internal length bytes completed */
2124       NdefMap->StdMifareContainer.currentBlock++;
2125       NdefMap->StdMifareContainer.NdefBlocks++;
2126       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
2127       if (Result == NFCSTATUS_SUCCESS) {
2128         Result =
2129             ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1)
2130                  ? phFriNfc_MifStd_H_RdABlock(NdefMap)
2131                  : phFriNfc_MifStd_H_AuthSector(NdefMap));
2132       }
2133     } else {
2134       /* Remaining Bytes in Length (L) field of TLV is 0 */
2135       NdefMap->TLVStruct.BytesRemainLinTLV =
2136           PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0;
2137       *Flag = PH_FRINFC_MIFARESTD_FLAG1;
2138     }
2139   } else if ((NdefMap->TLVStruct.BytesRemainLinTLV >
2140               NdefMap->StdMifareContainer.internalLength) &&
2141              (RemainingBytes <= NdefMap->StdMifareContainer.internalLength)) {
2142     memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
2143            &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]),
2144            RemainingBytes);
2145 
2146     NdefMap->ApduBuffIndex += RemainingBytes;
2147     NdefMap->StdMifareContainer.remainingSize -= RemainingBytes;
2148     *TempintBytes += ((uint8_t)RemainingBytes);
2149     /* Remaining Bytes of length (L) in TLV */
2150     NdefMap->TLVStruct.BytesRemainLinTLV -= RemainingBytes;
2151 
2152     /* copy the bytes to internal buffer, that are read,
2153                     but not used for the user buffer */
2154     memcpy(NdefMap->StdMifareContainer.internalBuf,
2155            &(NdefMap->StdMifareContainer.internalBuf[RemainingBytes]),
2156            (NdefMap->StdMifareContainer.internalLength - RemainingBytes));
2157 
2158     /* internal buffer length */
2159     NdefMap->StdMifareContainer.internalLength -= RemainingBytes;
2160     if (NdefMap->StdMifareContainer.internalLength ==
2161         PH_FRINFC_MIFARESTD_VAL0) {
2162       NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)(
2163           ((NdefMap->StdMifareContainer.remainingSize ==
2164             PH_FRINFC_MIFARESTD_VAL0) ||
2165            (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))
2166               ? PH_FRINFC_MIFARESTD_FLAG1
2167               : PH_FRINFC_MIFARESTD_FLAG0);
2168 
2169       /* internal length bytes completed */
2170       NdefMap->StdMifareContainer.currentBlock++;
2171       NdefMap->StdMifareContainer.NdefBlocks++;
2172     }
2173 
2174     NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
2175     CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2176     *Flag = PH_FRINFC_MIFARESTD_FLAG0;
2177   } else {
2178     if ((NdefMap->TLVStruct.BytesRemainLinTLV >
2179          NdefMap->StdMifareContainer.internalLength) &&
2180         (RemainingBytes > NdefMap->StdMifareContainer.internalLength)) {
2181       memcpy(&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]),
2182              &(NdefMap->StdMifareContainer.internalBuf[(*TempintBytes)]),
2183              NdefMap->StdMifareContainer.internalLength);
2184       *Flag = PH_FRINFC_MIFARESTD_FLAG0;
2185       NdefMap->ApduBuffIndex += NdefMap->StdMifareContainer.internalLength;
2186       NdefMap->StdMifareContainer.remainingSize -=
2187           NdefMap->StdMifareContainer.internalLength;
2188       NdefMap->TLVStruct.BytesRemainLinTLV -=
2189           NdefMap->StdMifareContainer.internalLength;
2190 
2191       if (NdefMap->TLVStruct.BytesRemainLinTLV !=
2192           PH_FRINFC_MIFARESTD_NDEFTLV_LBYTES0) {
2193         NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
2194       }
2195 
2196       NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0;
2197       /* internal length bytes completed */
2198       NdefMap->StdMifareContainer.currentBlock++;
2199       NdefMap->StdMifareContainer.NdefBlocks++;
2200       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
2201       if (Result == NFCSTATUS_SUCCESS) {
2202         Result =
2203             ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1)
2204                  ? phFriNfc_MifStd_H_RdABlock(NdefMap)
2205                  : phFriNfc_MifStd_H_AuthSector(NdefMap));
2206       }
2207     }
2208   }
2209 
2210   if (CRFlag == PH_FRINFC_MIFARESTD_FLAG1) {
2211     NdefMap->StdMifareContainer.ReadWriteCompleteFlag = (uint8_t)(
2212         ((NdefMap->StdMifareContainer.remainingSize ==
2213           PH_FRINFC_MIFARESTD_VAL0) ||
2214          (NdefMap->TLVStruct.BytesRemainLinTLV == PH_FRINFC_MIFARESTD_VAL0))
2215             ? PH_FRINFC_MIFARESTD_FLAG1
2216             : PH_FRINFC_MIFARESTD_FLAG0);
2217     *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
2218   }
2219 
2220   return Result;
2221 }
2222 
2223 /******************************************************************************
2224  * Function         phFriNfc_MifStd_H_WriteNdefLen
2225  *
2226  * Description      This function is Helper function for write ndef
2227  *                  to write the Length TLV.
2228  *
2229  * Returns          This function return NFCSTATUS_PENDING in case of success
2230  *                  In case of failure returns other failure value.
2231  *
2232  ******************************************************************************/
phFriNfc_MifStd_H_WriteNdefLen(phFriNfc_NdefMap_t * NdefMap)2233 static NFCSTATUS phFriNfc_MifStd_H_WriteNdefLen(phFriNfc_NdefMap_t* NdefMap) {
2234   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2235   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN;
2236 
2237   /* If Current block = Ndef TLV block then the starting point
2238      is writing from type of TLV
2239      Else */
2240 
2241   if (NdefMap->StdMifareContainer.currentBlock ==
2242       NdefMap->TLVStruct.NdefTLVBlock) {
2243     if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) {
2244       phFriNfc_MifStd_H_fillTLV1(NdefMap);
2245     } else {
2246       phFriNfc_MifStd_H_fillTLV2(NdefMap);
2247     }
2248   } else {
2249     if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) {
2250       phFriNfc_MifStd_H_fillTLV1_1(NdefMap);
2251     } else {
2252       phFriNfc_MifStd_H_fillTLV2_1(NdefMap);
2253     }
2254   }
2255 
2256   memcpy(NdefMap->StdMifareContainer.Buffer,
2257          &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]),
2258          PH_FRINFC_MIFARESTD_BYTES_READ);
2259 
2260   /* Write from here */
2261   NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE;
2262 
2263   NdefMap->Cmd.MfCmd = phHal_eMifareWrite16;
2264 
2265   *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2266   /* Call the Overlapped HAL Transceive function */
2267   Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
2268                                     NdefMap->SendRecvBuf, NdefMap->SendLength,
2269                                     NdefMap->SendRecvLength);
2270 
2271   return Result;
2272 }
2273 
2274 /******************************************************************************
2275  * Function         phFriNfc_MifStd_H_RdWrReset
2276  *
2277  * Description      It resets ndef TLV values. This is used when the offset
2278  *                  is BEGIN.
2279  *
2280  * Returns          void
2281  *
2282  ******************************************************************************/
phFriNfc_MifStd_H_RdWrReset(phFriNfc_NdefMap_t * NdefMap)2283 static void phFriNfc_MifStd_H_RdWrReset(phFriNfc_NdefMap_t* NdefMap) {
2284   NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4;
2285   NdefMap->StdMifareContainer.NdefBlocks = PH_FRINFC_MIFARESTD_VAL1;
2286   NdefMap->TLVStruct.BytesRemainLinTLV = PH_FRINFC_MIFARESTD_VAL0;
2287   NdefMap->TLVStruct.LcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2288   NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2289   NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0;
2290   NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_MIFARESTD_MAD_BLK0;
2291   NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0;
2292   NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0;
2293   NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
2294   NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0;
2295   NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
2296   NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0;
2297   NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG1;
2298   NdefMap->StdMifareContainer.ReadWriteCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0;
2299   NdefMap->StdMifareContainer.remainingSize =
2300       (uint16_t)(NdefMap->StdMifareContainer.NoOfNdefCompBlocks *
2301                  PH_FRINFC_MIFARESTD_BLOCK_BYTES);
2302   NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL1;
2303 
2304   return;
2305 }
2306 
2307 /******************************************************************************
2308  * Function         phFriNfc_MifStd_H_RdtoWrNdefLen
2309  *
2310  * Description      This function is used to read the first ndef compliant
2311  *                  block to change the length.
2312  *
2313  * Returns          This function return NFCSTATUS_PENDING in case of success
2314  *                  In case of failure returns other failure value.
2315  *
2316  ******************************************************************************/
phFriNfc_MifStd_H_RdtoWrNdefLen(phFriNfc_NdefMap_t * NdefMap)2317 static NFCSTATUS phFriNfc_MifStd_H_RdtoWrNdefLen(phFriNfc_NdefMap_t* NdefMap) {
2318   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2319 
2320   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_TO_WR_NDEF_LEN;
2321 
2322   if (NdefMap->TLVStruct.NdefTLVAuthFlag == PH_FRINFC_MIFARESTD_FLAG1) {
2323     NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
2324     Result = phFriNfc_MifStd_H_AuthSector(NdefMap);
2325   } else {
2326     NdefMap->SendRecvBuf[0] = NdefMap->StdMifareContainer.currentBlock;
2327     NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ;
2328     *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2329 
2330     NdefMap->Cmd.MfCmd = phHal_eMifareRead;
2331 
2332     /* Call the Overlapped HAL Transceive function */
2333     Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
2334                                       NdefMap->SendRecvBuf, NdefMap->SendLength,
2335                                       NdefMap->SendRecvLength);
2336   }
2337 
2338   return Result;
2339 }
2340 
2341 /******************************************************************************
2342  * Function         phFriNfc_MifStd_H_SetNdefBlkAuth
2343  *
2344  * Description      This function is used to set the authentication flag
2345  *                  for the ndef TLV block.
2346  *
2347  * Returns          void
2348  *
2349  ******************************************************************************/
phFriNfc_MifStd_H_SetNdefBlkAuth(phFriNfc_NdefMap_t * NdefMap)2350 static void phFriNfc_MifStd_H_SetNdefBlkAuth(phFriNfc_NdefMap_t* NdefMap) {
2351   NdefMap->TLVStruct.NdefTLVAuthFlag =
2352       ((phFriNfc_MifStd_H_GetSect(NdefMap->TLVStruct.NdefTLVBlock) ==
2353         phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock))
2354            ? PH_FRINFC_MIFARESTD_FLAG0
2355            : PH_FRINFC_MIFARESTD_FLAG1);
2356 
2357   return;
2358 }
2359 
2360 /******************************************************************************
2361  * Function         phFriNfc_MifStd_H_GetActCardLen
2362  *
2363  * Description      Helper function to get the actual length of card.
2364  *
2365  * Returns          This function return NFCSTATUS_SUCCESS in case of success
2366  *                  In case of failure returns other failure value.
2367  *
2368  ******************************************************************************/
phFriNfc_MifStd_H_GetActCardLen(phFriNfc_NdefMap_t * NdefMap)2369 static NFCSTATUS phFriNfc_MifStd_H_GetActCardLen(phFriNfc_NdefMap_t* NdefMap) {
2370   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2371 
2372   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_GET_ACT_CARDSIZE;
2373   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE;
2374 
2375   Result = ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG0)
2376                 ? phFriNfc_MifStd_H_AuthSector(NdefMap)
2377                 : phFriNfc_MifStd_H_Rd16Bytes(
2378                       NdefMap, NdefMap->StdMifareContainer.currentBlock));
2379 
2380   return Result;
2381 }
2382 
2383 /******************************************************************************
2384  * Function         phFriNfc_MifStd_H_ChkTLVs
2385  *
2386  * Description      Helper function to check all the TLVs.
2387  *
2388  * Returns          This function return NFCSTATUS_SUCCESS in case of success
2389  *                  In case of failure returns other failure value.
2390  *
2391  ******************************************************************************/
phFriNfc_MifStd_H_ChkTLVs(phFriNfc_NdefMap_t * NdefMap,uint8_t * CRFlag)2392 static NFCSTATUS phFriNfc_MifStd_H_ChkTLVs(phFriNfc_NdefMap_t* NdefMap,
2393                                            uint8_t* CRFlag) {
2394   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2395   uint16_t TempLength = PH_FRINFC_MIFARESTD_VAL0,
2396            ShiftLength = PH_FRINFC_MIFARESTD_VAL0;
2397   uint8_t TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0;
2398 
2399   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE;
2400   TempLength = NdefMap->TLVStruct.NdefTLVByte;
2401 
2402   for (;;) {
2403     if ((NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_TERMTLV_T) &&
2404         (NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_NULLTLV_T) &&
2405         (NdefMap->SendRecvBuf[TempLength] != PH_FRINFC_MIFARESTD_NDEFTLV_T) &&
2406         (false == NdefMap->TLVStruct.NdefTLVFoundFlag)) {
2407       Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
2408       NdefMap->TLVStruct.BytesRemainLinTLV = 0;
2409       NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2410       *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2411       break;
2412 
2413     } else if ((NdefMap->SendRecvBuf[TempLength] !=
2414                 PH_FRINFC_MIFARESTD_TERMTLV_T) &&
2415                (NdefMap->SendRecvBuf[TempLength] !=
2416                 PH_FRINFC_MIFARESTD_NULLTLV_T)) {
2417       if (NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_NDEFTLV_T) {
2418         NdefMap->TLVStruct.NdefTLVBlock =
2419             NdefMap->StdMifareContainer.currentBlock;
2420         NdefMap->TLVStruct.NdefTLVByte = (uint8_t)TempLength;
2421         NdefMap->TLVStruct.NdefTLVFoundFlag =
2422             ((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_NDEFTLV_T)
2423                  ? PH_FRINFC_MIFARESTD_FLAG1
2424                  : PH_FRINFC_MIFARESTD_FLAG0);
2425 
2426         NdefMap->TLVStruct.NULLTLVCount =
2427             ((NdefMap->TLVStruct.NULLTLVCount == PH_FRINFC_MIFARESTD_VAL1)
2428                  ? PH_FRINFC_MIFARESTD_VAL0
2429                  : NdefMap->TLVStruct.NULLTLVCount);
2430       } else {
2431         NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
2432       }
2433 
2434       TempLength++;
2435       if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
2436         NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1;
2437         NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL3;
2438       }
2439       Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength);
2440       if (Result != NFCSTATUS_SUCCESS) {
2441         *CRFlag = (uint8_t)((Result == NFCSTATUS_PENDING)
2442                                 ? PH_FRINFC_MIFARESTD_FLAG0
2443                                 : PH_FRINFC_MIFARESTD_FLAG1);
2444         break;
2445       }
2446 
2447       if (((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
2448               NdefMap->StdMifareContainer.NdefBlocks) *
2449              PH_FRINFC_MIFARESTD_BLOCK_BYTES) +
2450             (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) <
2451            NdefMap->SendRecvBuf[TempLength]) &&
2452           ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L) &&
2453            (NdefMap->TLVStruct.NdefTLVFoundFlag != PH_FRINFC_MIFARESTD_VAL1))) {
2454         /* Result = Error */
2455         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
2456         *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2457         break;
2458       }
2459 
2460       if (((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
2461               NdefMap->StdMifareContainer.NdefBlocks) *
2462              PH_FRINFC_MIFARESTD_BLOCK_BYTES) +
2463             (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) <
2464            NdefMap->SendRecvBuf[TempLength]) &&
2465           ((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_VAL0) &&
2466            (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_VAL1))) {
2467         /* Result = Error */
2468         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
2469         *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2470         break;
2471       }
2472 
2473       if ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1) &&
2474           (NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L)) {
2475         Result = phFriNfc_MapTool_SetCardState(
2476             NdefMap, NdefMap->SendRecvBuf[TempLength]);
2477         NdefMap->TLVStruct.BytesRemainLinTLV = NdefMap->SendRecvBuf[TempLength];
2478         NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL2;
2479         /* This flag is set */
2480         NdefMap->StdMifareContainer.remSizeUpdFlag = (uint8_t)(
2481             (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2)
2482                 ? PH_FRINFC_MIFARESTD_FLAG0
2483                 : PH_FRINFC_MIFARESTD_FLAG1);
2484 
2485         *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2486         break;
2487       }
2488 
2489       NdefMap->StdMifareContainer.remainingSize -=
2490           ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L)
2491                ? (NdefMap->SendRecvBuf[TempLength] + PH_FRINFC_MIFARESTD_VAL2)
2492                : PH_FRINFC_MIFARESTD_VAL0);
2493 
2494       if (NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_VAL0) {
2495         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
2496         *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2497         break;
2498       }
2499 
2500       TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0;
2501       /* get the next TLV after the proprietary TLV */
2502       Result =
2503           ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L)
2504                ? phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength,
2505                                              &TL4bytesFlag)
2506                : NFCSTATUS_PENDING);
2507 
2508       if ((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) &&
2509           (Result == NFCSTATUS_SUCCESS)) {
2510         NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2511         NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0;
2512 
2513         Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap);
2514         *CRFlag = (uint8_t)((Result != NFCSTATUS_PENDING)
2515                                 ? PH_FRINFC_MIFARESTD_FLAG1
2516                                 : PH_FRINFC_MIFARESTD_FLAG0);
2517         break;
2518       } else {
2519         if (Result == NFCSTATUS_PENDING) {
2520           TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG1;
2521           Result = ((NdefMap->SendRecvBuf[TempLength] ==
2522                      PH_FRINFC_MIFARESTD_NDEFTLV_L)
2523                         ? NFCSTATUS_SUCCESS
2524                         : (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2525                                       NFCSTATUS_INVALID_PARAMETER)));
2526 
2527           if (Result != NFCSTATUS_SUCCESS) {
2528             *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2529             break;
2530           }
2531           NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
2532           TempLength++;
2533           /* Check 0xFF */
2534           if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
2535             NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1;
2536             NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL2;
2537           }
2538           Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength);
2539           if (Result != NFCSTATUS_SUCCESS) {
2540             break;
2541           }
2542 
2543           ShiftLength = NdefMap->SendRecvBuf[TempLength];
2544           TempLength++;
2545           if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
2546             NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG1;
2547             NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL1;
2548             NdefMap->TLVStruct.prevLenByteValue =
2549                 NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)];
2550           }
2551           Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength);
2552           if (Result != NFCSTATUS_SUCCESS) {
2553             break;
2554           }
2555 
2556           if ((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
2557                  NdefMap->StdMifareContainer.NdefBlocks) *
2558                 PH_FRINFC_MIFARESTD_BLOCK_BYTES) +
2559                (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) <
2560               ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLength])) {
2561             Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2562                                 NFCSTATUS_INVALID_REMOTE_DEVICE);
2563 
2564             break;
2565           }
2566 
2567           if (NdefMap->TLVStruct.NdefTLVFoundFlag ==
2568               PH_FRINFC_MIFARESTD_FLAG1) {
2569             ShiftLength =
2570                 ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLength]);
2571             NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength;
2572             Result = phFriNfc_MapTool_SetCardState(NdefMap, ShiftLength);
2573             NdefMap->StdMifareContainer.remainingSize -=
2574                 PH_FRINFC_MIFARESTD_VAL4;
2575             *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2576             break;
2577           }
2578 
2579           NdefMap->StdMifareContainer.remainingSize -=
2580               ((ShiftLength << 8) +
2581                NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]);
2582           TempLength++;
2583 
2584           /* get the next TLV after the proprietary TLV */
2585           Result =
2586               phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag);
2587 
2588           if ((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) &&
2589               (Result == NFCSTATUS_SUCCESS)) {
2590             NdefMap->TLVStruct.TcheckedinTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
2591             NdefMap->TLVStruct.NoLbytesinTLV = PH_FRINFC_MIFARESTD_VAL0;
2592             Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap);
2593 
2594             break;
2595           }
2596           break;
2597         }
2598       }
2599     } else if ((NdefMap->SendRecvBuf[TempLength] ==
2600                 PH_FRINFC_MIFARESTD_TERMTLV_T) &&
2601                (NdefMap->TLVStruct.NdefTLVFoundFlag ==
2602                 PH_FRINFC_MIFARESTD_FLAG0)) {
2603       Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
2604       NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
2605           PH_FRINFC_MIFARESTD_FLAG1;
2606       break;
2607 
2608     } else if (NdefMap->SendRecvBuf[TempLength] ==
2609                PH_FRINFC_MIFARESTD_NULLTLV_T) {
2610       TempLength++;
2611       NdefMap->TLVStruct.NULLTLVCount += PH_FRINFC_MIFARESTD_VAL1;
2612       ShiftLength =
2613           NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)];
2614       NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL1;
2615       if (NdefMap->StdMifareContainer.remainingSize <
2616           ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLength])) {
2617         Result =
2618             PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE);
2619         break;
2620       }
2621       Result = phFriNfc_MifStd_H_Chk16Bytes(NdefMap, TempLength);
2622       if (Result != NFCSTATUS_SUCCESS) {
2623         NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL0;
2624         break;
2625       }
2626     } else {
2627       if ((NdefMap->SendRecvBuf[TempLength] == PH_FRINFC_MIFARESTD_TERMTLV_T) &&
2628           (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1)) {
2629         TempLength++;
2630         Result = NFCSTATUS_SUCCESS;
2631         NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL1;
2632       }
2633     }
2634   }
2635 
2636   if (NdefMap->TLVStruct.BytesRemainLinTLV >
2637       NdefMap->StdMifareContainer.remainingSize) {
2638     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT);
2639   } else {
2640     if (NdefMap->StdMifareContainer.remainingSize == PH_FRINFC_MIFARESTD_VAL0) {
2641       Result =
2642           ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1)
2643                ? NFCSTATUS_SUCCESS
2644                : (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2645                              NFCSTATUS_INVALID_PARAMETER)));
2646     }
2647   }
2648 
2649   return Result;
2650 }
2651 
2652 /******************************************************************************
2653  * Function         phFriNfc_MifStd_H_GetNxtTLV
2654  *
2655  * Description      This is a Helper function to get the next TLV.
2656  *
2657  * Returns          This function return NFCSTATUS_SUCCESS in case of success
2658  *                  In case of failure returns other failure value.
2659  *
2660  ******************************************************************************/
phFriNfc_MifStd_H_GetNxtTLV(phFriNfc_NdefMap_t * NdefMap,uint16_t * TempLength,uint8_t * TL4bytesFlag)2661 static NFCSTATUS phFriNfc_MifStd_H_GetNxtTLV(phFriNfc_NdefMap_t* NdefMap,
2662                                              uint16_t* TempLength,
2663                                              uint8_t* TL4bytesFlag) {
2664   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2665   uint16_t LengthRemaining = PH_FRINFC_MIFARESTD_VAL0,
2666            TempLen = PH_FRINFC_MIFARESTD_VAL0,
2667            ShiftLength = PH_FRINFC_MIFARESTD_VAL0;
2668 
2669   TempLen = (*TempLength);
2670   LengthRemaining =
2671       (PH_FRINFC_MIFARESTD_BYTES_READ - (TempLen + PH_FRINFC_MIFARESTD_VAL1));
2672 
2673   if (*TL4bytesFlag == PH_FRINFC_MIFARESTD_FLAG0) {
2674     (*TempLength) += (NdefMap->SendRecvBuf[TempLen] + PH_FRINFC_MIFARESTD_VAL1);
2675     LengthRemaining = (((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)
2676                            ? PH_FRINFC_MIFARESTD_VAL0
2677                            : (NdefMap->SendRecvBuf[TempLen] - LengthRemaining));
2678   } else {
2679     *TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0;
2680     if (NdefMap->TLVStruct.NoLbytesinTLV == PH_FRINFC_MIFARESTD_VAL1) {
2681       ShiftLength = NdefMap->TLVStruct.prevLenByteValue;
2682       (*TempLength) += ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen] +
2683                         PH_FRINFC_MIFARESTD_VAL1);
2684 
2685       LengthRemaining = (((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen]) -
2686                          LengthRemaining);
2687     } else {
2688       ShiftLength = NdefMap->SendRecvBuf[(TempLen - PH_FRINFC_MIFARESTD_VAL1)];
2689       (*TempLength) += ((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen] +
2690                         PH_FRINFC_MIFARESTD_VAL1);
2691 
2692       LengthRemaining = (((ShiftLength << 8) + NdefMap->SendRecvBuf[TempLen]) -
2693                          LengthRemaining);
2694     }
2695   }
2696 
2697   NdefMap->TLVStruct.NdefTLVByte =
2698       (uint8_t)(((*TempLength) < PH_FRINFC_MIFARESTD_BYTES_READ)
2699                     ? (*TempLength)
2700                     : (LengthRemaining % PH_FRINFC_MIFARESTD_BYTES_READ));
2701 
2702   while (LengthRemaining != PH_FRINFC_MIFARESTD_VAL0) {
2703     NdefMap->StdMifareContainer.currentBlock++;
2704     NdefMap->StdMifareContainer.NdefBlocks++;
2705     Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
2706     LengthRemaining -= ((LengthRemaining <= PH_FRINFC_MIFARESTD_BYTES_READ)
2707                             ? LengthRemaining
2708                             : PH_FRINFC_MIFARESTD_BYTES_READ);
2709   }
2710 
2711   if (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL0) {
2712     NdefMap->StdMifareContainer.currentBlock++;
2713     NdefMap->StdMifareContainer.NdefBlocks++;
2714     Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
2715   }
2716 
2717   return Result;
2718 }
2719 
2720 /******************************************************************************
2721  * Function         phFriNfc_MifStd_H_Chk16Bytes
2722  *
2723  * Description      This Helper function is used to know whether the read
2724  *                  16 bytes are parsed completely.
2725  *
2726  * Returns          This function return NFCSTATUS_SUCCESS in case of success
2727  *                  In case of failure returns other failure value.
2728  *
2729  ******************************************************************************/
phFriNfc_MifStd_H_Chk16Bytes(phFriNfc_NdefMap_t * NdefMap,uint16_t TempLength)2730 static NFCSTATUS phFriNfc_MifStd_H_Chk16Bytes(phFriNfc_NdefMap_t* NdefMap,
2731                                               uint16_t TempLength) {
2732   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2733 
2734   if (TempLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
2735     NdefMap->StdMifareContainer.currentBlock++;
2736     NdefMap->StdMifareContainer.NdefBlocks++;
2737     Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
2738 
2739     Result =
2740         ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG1)
2741              ? phFriNfc_MifStd_H_GetActCardLen(NdefMap)
2742              : phFriNfc_MifStd_H_AuthSector(NdefMap));
2743   }
2744 
2745   return Result;
2746 }
2747 
2748 /******************************************************************************
2749  * Function         phFriNfc_MifStd_H_ChkRemainTLVs
2750  *
2751  * Description      This function is used to know whether the read
2752  *                  16 bytes are parsed completely.
2753  *
2754  * Returns          This function return NFCSTATUS_SUCCESS in case of success
2755  *                  In case of failure returns other failure value.
2756  *
2757  ******************************************************************************/
phFriNfc_MifStd_H_ChkRemainTLVs(phFriNfc_NdefMap_t * NdefMap,uint8_t * CRFlag,uint8_t * NDEFFlag)2758 static NFCSTATUS phFriNfc_MifStd_H_ChkRemainTLVs(phFriNfc_NdefMap_t* NdefMap,
2759                                                  uint8_t* CRFlag,
2760                                                  uint8_t* NDEFFlag) {
2761   NFCSTATUS Result = NFCSTATUS_SUCCESS;
2762   uint16_t TempLength = PH_FRINFC_MIFARESTD_VAL0,
2763            ShiftLength = PH_FRINFC_MIFARESTD_VAL0;
2764   uint8_t TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0;
2765 
2766   switch (NdefMap->TLVStruct.NoLbytesinTLV) {
2767     case PH_FRINFC_MIFARESTD_VAL3:
2768       /* if TLV is found then set card state */
2769       Result =
2770           ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1)
2771                ? phFriNfc_MapTool_SetCardState(NdefMap,
2772                                                NdefMap->SendRecvBuf[TempLength])
2773                : Result);
2774 
2775       Result =
2776           ((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1)
2777                ? 1
2778                : Result);
2779 
2780       /* Check the length field is less than or
2781          equal to 0xFF if yes enter below statement
2782          else enter else if*/
2783       if ((NdefMap->SendRecvBuf[TempLength] < PH_FRINFC_MIFARESTD_NDEFTLV_L) &&
2784           (Result == NFCSTATUS_SUCCESS)) {
2785         NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL2;
2786 
2787         Result =
2788             ((NdefMap->SendRecvBuf[TempLength] >
2789               NdefMap->StdMifareContainer.remainingSize)
2790                  ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT))
2791                  : Result);
2792         TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0;
2793         if ((NdefMap->TLVStruct.NdefTLVFoundFlag ==
2794              PH_FRINFC_MIFARESTD_FLAG1) &&
2795             (Result == NFCSTATUS_SUCCESS)) {
2796           NdefMap->TLVStruct.BytesRemainLinTLV =
2797               NdefMap->SendRecvBuf[TempLength];
2798           *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2799 
2800         } else if (Result == NFCSTATUS_SUCCESS) {
2801           TempLength++;
2802           Result =
2803               phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag);
2804 
2805           NdefMap->StdMifareContainer.remainingSize -=
2806               NdefMap->SendRecvBuf[TempLength];
2807           if ((TempLength >= PH_FRINFC_MIFARESTD_BYTES_READ) &&
2808               (*CRFlag == PH_FRINFC_MIFARESTD_FLAG0)) {
2809             *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
2810             Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap);
2811           }
2812         }
2813 
2814         else {
2815           /* do nothing */
2816         }
2817       } else if ((NdefMap->SendRecvBuf[TempLength] ==
2818                   PH_FRINFC_MIFARESTD_NDEFTLV_L) &&
2819                  (Result == NFCSTATUS_SUCCESS)) {
2820         TempLength++;
2821         NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL4;
2822         TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG0;
2823         Result =
2824             (((((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) +
2825                NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]) >
2826               NdefMap->StdMifareContainer.remainingSize)
2827                  ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT))
2828                  : Result);
2829         if ((NdefMap->TLVStruct.NdefTLVFoundFlag ==
2830              PH_FRINFC_MIFARESTD_FLAG1) &&
2831             (Result == NFCSTATUS_SUCCESS)) {
2832           NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
2833           NdefMap->TLVStruct.BytesRemainLinTLV =
2834               (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) +
2835                NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]);
2836           *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2837         } else if (Result == NFCSTATUS_SUCCESS) {
2838           TempLength++;
2839 
2840           Result =
2841               phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength, &TL4bytesFlag);
2842           NdefMap->StdMifareContainer.remainingSize -=
2843               (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) +
2844                NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]);
2845 
2846           *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
2847           Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap);
2848         } else {
2849           /* do nothing */
2850           *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2851         }
2852       } else {
2853         /* Result = Error */
2854         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT);
2855         *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2856       }
2857       break;
2858 
2859     case PH_FRINFC_MIFARESTD_VAL2:
2860     case PH_FRINFC_MIFARESTD_VAL1:
2861       ShiftLength =
2862           ((NdefMap->TLVStruct.NoLbytesinTLV == PH_FRINFC_MIFARESTD_VAL1)
2863                ? ((NdefMap->TLVStruct.prevLenByteValue << 8) +
2864                   NdefMap->SendRecvBuf[TempLength])
2865                : (((uint16_t)NdefMap->SendRecvBuf[TempLength] << 8) +
2866                   NdefMap
2867                       ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]));
2868       if ((((NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
2869              NdefMap->StdMifareContainer.NdefBlocks) *
2870             PH_FRINFC_MIFARESTD_BLOCK_BYTES) +
2871            (PH_FRINFC_MIFARESTD_BLOCK_BYTES - TempLength)) < ShiftLength) {
2872         /* Result = Error */
2873         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
2874         *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2875       } else {
2876         NdefMap->StdMifareContainer.remainingSize -= PH_FRINFC_MIFARESTD_VAL2;
2877         if (NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_MIFARESTD_FLAG1) {
2878           NdefMap->TLVStruct.BytesRemainLinTLV = ShiftLength;
2879           if (NdefMap->TLVStruct.BytesRemainLinTLV >
2880               NdefMap->StdMifareContainer.remainingSize) {
2881             Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT);
2882           }
2883           *CRFlag = PH_FRINFC_MIFARESTD_FLAG1;
2884           *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
2885         } else {
2886           NdefMap->StdMifareContainer.remainingSize -= ShiftLength;
2887           *CRFlag = PH_FRINFC_MIFARESTD_FLAG0;
2888           TempLength += PH_FRINFC_MIFARESTD_VAL2;
2889           TL4bytesFlag = PH_FRINFC_MIFARESTD_FLAG1;
2890           Result = ((NdefMap->TLVStruct.NdefTLVFoundFlag ==
2891                      PH_FRINFC_MIFARESTD_FLAG1)
2892                         ? NFCSTATUS_SUCCESS
2893                         : phFriNfc_MifStd_H_GetNxtTLV(NdefMap, &TempLength,
2894                                                       &TL4bytesFlag));
2895 
2896           *NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
2897           Result = phFriNfc_MifStd_H_GetActCardLen(NdefMap);
2898         }
2899       }
2900       break;
2901 
2902     default:
2903       break;
2904   }
2905 
2906   return Result;
2907 }
2908 
2909 /******************************************************************************
2910  * Function         phFriNfc_MifStd_H_Get1kStTrail
2911  *
2912  * Description      This function is used to get the Mifare 1k Sector Trailer.
2913  *
2914  * Returns          void
2915  *
2916  ******************************************************************************/
phFriNfc_MifStd_H_Get1kStTrail(phFriNfc_NdefMap_t * NdefMap)2917 static void phFriNfc_MifStd_H_Get1kStTrail(phFriNfc_NdefMap_t* NdefMap) {
2918   switch ((NdefMap->StdMifareContainer.currentBlock % 4)) {
2919     case PH_FRINFC_MIFARESTD_VAL0:
2920       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2921           (NdefMap->StdMifareContainer.currentBlock +
2922            PH_FRINFC_MIFARESTD_MAD_BLK3);
2923       break;
2924 
2925     case PH_FRINFC_MIFARESTD_VAL1:
2926       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2927           (NdefMap->StdMifareContainer.currentBlock +
2928            PH_FRINFC_MIFARESTD_MAD_BLK2);
2929       break;
2930 
2931     case PH_FRINFC_MIFARESTD_VAL2:
2932       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2933           (NdefMap->StdMifareContainer.currentBlock +
2934            PH_FRINFC_MIFARESTD_MAD_BLK1);
2935       break;
2936 
2937     default:
2938       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2939           NdefMap->StdMifareContainer.currentBlock;
2940       break;
2941   }
2942 
2943   return;
2944 }
2945 
2946 /******************************************************************************
2947  * Function         phFriNfc_MifStd_H_Get4kStTrail
2948  *
2949  * Description      This function gets the Mifare 4k Sector Trailer.
2950  *
2951  * Returns          void
2952  *
2953  ******************************************************************************/
phFriNfc_MifStd_H_Get4kStTrail(phFriNfc_NdefMap_t * NdefMap)2954 static void phFriNfc_MifStd_H_Get4kStTrail(phFriNfc_NdefMap_t* NdefMap) {
2955   switch ((NdefMap->StdMifareContainer.currentBlock % 16)) {
2956     case PH_FRINFC_MIFARESTD_MAD_BLK0:
2957       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2958           (NdefMap->StdMifareContainer.currentBlock +
2959            PH_FRINFC_MIFARESTD_BLK15);
2960       break;
2961 
2962     case PH_FRINFC_MIFARESTD_MAD_BLK1:
2963       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2964           (NdefMap->StdMifareContainer.currentBlock +
2965            PH_FRINFC_MIFARESTD_BLK14);
2966       break;
2967 
2968     case PH_FRINFC_MIFARESTD_MAD_BLK2:
2969       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2970           (NdefMap->StdMifareContainer.currentBlock +
2971            PH_FRINFC_MIFARESTD_BLK13);
2972       break;
2973 
2974     case PH_FRINFC_MIFARESTD_MAD_BLK3:
2975       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2976           (NdefMap->StdMifareContainer.currentBlock +
2977            PH_FRINFC_MIFARESTD_BLK12);
2978       break;
2979 
2980     case PH_FRINFC_MIFARESTD_BLK4:
2981       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2982           (NdefMap->StdMifareContainer.currentBlock +
2983            PH_FRINFC_MIFARESTD_BLK11);
2984       break;
2985 
2986     case PH_FRINFC_MIFARESTD_BLK5:
2987       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2988           (NdefMap->StdMifareContainer.currentBlock +
2989            PH_FRINFC_MIFARESTD_BLK10);
2990       break;
2991 
2992     case PH_FRINFC_MIFARESTD_BLK6:
2993       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2994           (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK9);
2995       break;
2996 
2997     case PH_FRINFC_MIFARESTD_BLK7:
2998       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
2999           (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK8);
3000       break;
3001 
3002     case PH_FRINFC_MIFARESTD_BLK8:
3003       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3004           (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK7);
3005       break;
3006 
3007     case PH_FRINFC_MIFARESTD_BLK9:
3008       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3009           (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK6);
3010       break;
3011 
3012     case PH_FRINFC_MIFARESTD_BLK10:
3013       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3014           (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK5);
3015       break;
3016 
3017     case PH_FRINFC_MIFARESTD_BLK11:
3018       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3019           (NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_BLK4);
3020       break;
3021 
3022     case PH_FRINFC_MIFARESTD_BLK12:
3023       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3024           (NdefMap->StdMifareContainer.currentBlock +
3025            PH_FRINFC_MIFARESTD_MAD_BLK3);
3026       break;
3027 
3028     case PH_FRINFC_MIFARESTD_BLK13:
3029       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3030           (NdefMap->StdMifareContainer.currentBlock +
3031            PH_FRINFC_MIFARESTD_MAD_BLK2);
3032       break;
3033 
3034     case PH_FRINFC_MIFARESTD_BLK14:
3035       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3036           (NdefMap->StdMifareContainer.currentBlock +
3037            PH_FRINFC_MIFARESTD_MAD_BLK1);
3038       break;
3039 
3040     default:
3041       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3042           NdefMap->StdMifareContainer.currentBlock;
3043       break;
3044   }
3045 
3046   return;
3047 }
3048 
3049 /******************************************************************************
3050  * Function         phFriNfc_MifStd_H_ProChkNdef
3051  *
3052  * Description      This function processes the check ndef call.
3053  *
3054  * Returns          This function return NFCSTATUS_PENDING in case of success
3055  *                  In case of failure returns other failure value.
3056  *
3057  ******************************************************************************/
phFriNfc_MifStd_H_ProChkNdef(phFriNfc_NdefMap_t * NdefMap)3058 static NFCSTATUS phFriNfc_MifStd_H_ProChkNdef(phFriNfc_NdefMap_t* NdefMap) {
3059   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3060 
3061   /* Copy remaining bytes into the AID array
3062      from Receive Buffer till array number 7 in aid */
3063   if (NdefMap->StdMifareContainer.currentBlock == PH_FRINFC_MIFARESTD_VAL1) {
3064     /* Helper Function to Store AID Information */
3065     phFriNfc_MifStd_H_fillAIDarray(NdefMap);
3066 
3067     NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_VAL2;
3068     /* read remaining AIDs from block number 2 */
3069     Result = ((NdefMap->StdMifareContainer.aidCompleteFlag ==
3070                PH_FRINFC_MIFARESTD_FLAG1)
3071                   ? Result
3072                   : phFriNfc_MifareStdMap_ChkNdef(NdefMap));
3073   } else if (((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD) &&
3074               (NdefMap->StdMifareContainer.currentBlock ==
3075                PH_FRINFC_MIFARESTD_MAD_BLK2)) ||
3076              ((NdefMap->StdMifareContainer.currentBlock ==
3077                PH_FRINFC_MIFARESTD_MAD_BLK66) &&
3078               (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD ||
3079                NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))) {
3080     /* Helper Function to Store AID Information */
3081     phFriNfc_MifStd_H_fillAIDarray(NdefMap);
3082 
3083     NdefMap->StdMifareContainer.aidCompleteFlag = PH_FRINFC_MIFARESTD_FLAG1;
3084   } /* Mifare 1k and Mifare 4k end Check */
3085   else if ((NdefMap->StdMifareContainer.currentBlock >
3086             PH_FRINFC_MIFARESTD_VAL1) &&
3087            (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD ||
3088             NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) {
3089     phFriNfc_MifStd_H_fillAIDarray(NdefMap);
3090     /* read remaining AIDs from block number 2 */
3091     /* Mifare 4k Helper Function */
3092     Result = ((NdefMap->StdMifareContainer.aidCompleteFlag ==
3093                PH_FRINFC_MIFARESTD_FLAG1)
3094                   ? Result
3095                   : phFriNfc_MifStd4k_H_CheckNdef(NdefMap));
3096   } /* Card Type 4k Check */
3097   else {
3098     /* Since we have decided temporarily not to go
3099        for any new error codes we are using
3100        NFCSTATUS_INVALID_PARAMETER even though it is not
3101        the relevant error code here TBD */
3102     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
3103   }
3104 
3105   if (NdefMap->StdMifareContainer.aidCompleteFlag ==
3106       PH_FRINFC_MIFARESTD_FLAG1) {
3107     NdefMap->StdMifareContainer.ChkNdefCompleteFlag = PH_FRINFC_MIFARESTD_FLAG1;
3108     /*  The check for NDEF compliant information is now over for
3109         the Mifare 1K card.
3110         Update(decrement) the NoOfNdefCompBlocks as much required,
3111         depending on the NDEF compliant information found */
3112     /* Check the Sectors are Ndef Compliant */
3113     phFriNfc_MifStd_H_ChkNdefCmpltSects(NdefMap);
3114     if ((NdefMap->StdMifareContainer.NoOfNdefCompBlocks == 0) ||
3115         (NdefMap->StdMifareContainer.NoOfNdefCompBlocks > 255)) {
3116       Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
3117     } else {
3118       NdefMap->StdMifareContainer.aidCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0;
3119       NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0;
3120       NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_BLK4;
3121       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
3122       Result = ((Result != NFCSTATUS_SUCCESS)
3123                     ? Result
3124                     : phFriNfc_MifStd_H_AuthSector(NdefMap));
3125     }
3126   }
3127 
3128   return Result;
3129 }
3130 
3131 /******************************************************************************
3132  * Function         phFriNfc_MifStd_H_ProAuth
3133  *
3134  * Description      This function process the authentication of a sector.
3135  *
3136  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3137  *                  In case of failure returns other failure value.
3138  *
3139  ******************************************************************************/
phFriNfc_MifStd_H_ProAuth(phFriNfc_NdefMap_t * NdefMap)3140 static NFCSTATUS phFriNfc_MifStd_H_ProAuth(phFriNfc_NdefMap_t* NdefMap) {
3141   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3142 
3143   if (NdefMap->TLVStruct.NdefTLVAuthFlag == PH_FRINFC_MIFARESTD_FLAG1) {
3144     NdefMap->TLVStruct.NdefTLVAuthFlag = PH_FRINFC_MIFARESTD_FLAG0;
3145     NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG1;
3146     Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap);
3147   } else {
3148     NdefMap->StdMifareContainer.AuthDone = 1;
3149     NdefMap->StdMifareContainer.ReadAcsBitFlag = 1;
3150     Result = phFriNfc_MifStd_H_RdAcsBit(NdefMap);
3151   }
3152 
3153   return Result;
3154 }
3155 
3156 /******************************************************************************
3157  * Function         phFriNfc_MifStd_H_Rd16Bytes
3158  *
3159  * Description      This function reads 16 bytes from a specifed block no.
3160  *
3161  * Returns          This function return NFCSTATUS_PENDING in case of success
3162  *                  In case of failure returns other failure value.
3163  *
3164  ******************************************************************************/
phFriNfc_MifStd_H_Rd16Bytes(phFriNfc_NdefMap_t * NdefMap,uint8_t BlockNo)3165 static NFCSTATUS phFriNfc_MifStd_H_Rd16Bytes(phFriNfc_NdefMap_t* NdefMap,
3166                                              uint8_t BlockNo) {
3167   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3168 
3169   NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = BlockNo;
3170   NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_READ;
3171   *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
3172   NdefMap->Cmd.MfCmd = phHal_eMifareRead;
3173   NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
3174   NdefMap->MapCompletionInfo.Context = NdefMap;
3175 
3176   /* Call the Overlapped HAL Transceive function */
3177   Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
3178                                     NdefMap->SendRecvBuf, NdefMap->SendLength,
3179                                     NdefMap->SendRecvLength);
3180 
3181   return Result;
3182 }
3183 
3184 /******************************************************************************
3185  * Function         phFriNfc_MifStd_H_ProAcsBits
3186  *
3187  * Description      It processes access bits of the sector trailer.
3188  *
3189  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3190  *                  In case of failure returns other failure value.
3191  *
3192  ******************************************************************************/
phFriNfc_MifStd_H_ProAcsBits(phFriNfc_NdefMap_t * NdefMap)3193 static NFCSTATUS phFriNfc_MifStd_H_ProAcsBits(phFriNfc_NdefMap_t* NdefMap) {
3194   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3195   uint8_t CRFlag = PH_FRINFC_MIFARESTD_FLAG0;
3196 
3197   if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
3198     if (NdefMap->StdMifareContainer.ReadAcsBitFlag ==
3199         PH_FRINFC_MIFARESTD_FLAG1) {
3200       /* check for the correct access bits */
3201       Result = phFriNfc_MifStd_H_ChkAcsBit(NdefMap);
3202 
3203       if ((NdefMap->StdMifareContainer.ChkNdefFlag ==
3204            PH_FRINFC_MIFARESTD_FLAG1) &&
3205           (Result == NFCSTATUS_SUCCESS)) {
3206         if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID) {
3207           NdefMap->StdMifareContainer.NoOfNdefCompBlocks =
3208               ((NdefMap->StdMifareContainer.currentBlock >=
3209                 PH_FRINFC_MIFARESTD4K_BLK128)
3210                    ? (NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
3211                       PH_FRINFC_MIFARESTD_BLK15)
3212                    : (NdefMap->StdMifareContainer.NoOfNdefCompBlocks -
3213                       PH_FRINFC_MIFARESTD_MAD_BLK3));
3214 
3215           NdefMap->StdMifareContainer.ProprforumSectFlag =
3216               ((NdefMap->StdMifareContainer.NFCforumSectFlag ==
3217                 PH_FRINFC_MIFARESTD_FLAG1)
3218                    ? PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG
3219                    : PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG);
3220 
3221           Result = phFriNfc_MifStd_H_ProStatNotValid(NdefMap, Result);
3222         } else {
3223           NdefMap->StdMifareContainer.NFCforumSectFlag =
3224               (((NdefMap->StdMifareContainer.currentBlock == 64) &&
3225                 ((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) ||
3226                  (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)))
3227                    ? NdefMap->StdMifareContainer.NFCforumSectFlag
3228                    : PH_FRINFC_MIFARESTD_FLAG1);
3229         }
3230 
3231         if (NdefMap->StdMifareContainer.ProprforumSectFlag !=
3232             PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG) {
3233           NdefMap->StdMifareContainer.ReadAcsBitFlag =
3234               PH_FRINFC_MIFARESTD_FLAG0;
3235           /* ((NdefMap->StdMifareContainer.ReadCompleteFlag ==
3236                   PH_FRINFC_MIFARESTD_FLAG1)?
3237                   PH_FRINFC_MIFARESTD_FLAG0:
3238                   PH_FRINFC_MIFARESTD_FLAG1);*/
3239 
3240           NdefMap->StdMifareContainer.ReadCompleteFlag = (uint8_t)(
3241               (((((NdefMap->StdMifareContainer.currentBlock +
3242                    PH_FRINFC_MIFARESTD_VAL4) >=
3243                   PH_FRINFC_MIFARESTD1K_MAX_BLK) &&
3244                  (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) &&
3245                 (NdefMap->StdMifareContainer.ReadCompleteFlag ==
3246                  PH_FRINFC_MIFARESTD_FLAG0)) ||
3247                (NdefMap->StdMifareContainer.ReadCompleteFlag ==
3248                 PH_FRINFC_MIFARESTD_FLAG1))
3249                   ? PH_FRINFC_MIFARESTD_FLAG1
3250                   : PH_FRINFC_MIFARESTD_FLAG0);
3251 
3252           NdefMap->StdMifareContainer.ReadCompleteFlag = (uint8_t)(
3253               (((((uint16_t)(NdefMap->StdMifareContainer.currentBlock +
3254                              PH_FRINFC_MIFARESTD_VAL4) >=
3255                   PH_FRINFC_MIFARESTD4K_MAX_BLK) &&
3256                  (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) &&
3257                 (NdefMap->StdMifareContainer.ReadCompleteFlag ==
3258                  PH_FRINFC_MIFARESTD_FLAG0)) ||
3259                (NdefMap->StdMifareContainer.ReadCompleteFlag ==
3260                 PH_FRINFC_MIFARESTD_FLAG1))
3261                   ? PH_FRINFC_MIFARESTD_FLAG1
3262                   : PH_FRINFC_MIFARESTD_FLAG0);
3263 
3264           NdefMap->StdMifareContainer.ReadCompleteFlag = (uint8_t)(
3265               (((((uint16_t)(NdefMap->StdMifareContainer.currentBlock +
3266                              PH_FRINFC_MIFARESTD_VAL4) >=
3267                   PH_FRINFC_MIFARESTD4K_MAX_BLK) &&
3268                  (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)) &&
3269                 (NdefMap->StdMifareContainer.ReadCompleteFlag ==
3270                  PH_FRINFC_MIFARESTD_FLAG0)) ||
3271                (NdefMap->StdMifareContainer.ReadCompleteFlag ==
3272                 PH_FRINFC_MIFARESTD_FLAG1))
3273                   ? PH_FRINFC_MIFARESTD_FLAG1
3274                   : PH_FRINFC_MIFARESTD_FLAG0);
3275 
3276           NdefMap->StdMifareContainer.currentBlock =
3277               ((NdefMap->StdMifareContainer.ReadCompleteFlag ==
3278                 PH_FRINFC_MIFARESTD_FLAG1)
3279                    ? PH_FRINFC_MIFARESTD_BLK4
3280                    : NdefMap->StdMifareContainer.currentBlock);
3281 
3282           Result = ((NdefMap->StdMifareContainer.ReadCompleteFlag ==
3283                      PH_FRINFC_MIFARESTD_FLAG1)
3284                         ? phFriNfc_MifStd_H_BlkChk(NdefMap)
3285                         : Result);
3286         }
3287       }
3288 
3289       Result =
3290           ((Result != NFCSTATUS_SUCCESS) ? Result
3291                                          : phFriNfc_MifStd_H_ChkRdWr(NdefMap));
3292     } else {
3293       NdefMap->StdMifareContainer.ChkNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
3294       /* Here its required to read the entire card to know the */
3295       /* Get exact ndef size of the card */
3296       Result = phFriNfc_MifStd_H_ChkTLVs(NdefMap, &CRFlag);
3297     }
3298   } else {
3299     /* Since we have decided temporarily not to go
3300        for any new error codes we are using
3301        NFCSTATUS_INVALID_PARAMETER even though it is not
3302        the relevant error code here TBD */
3303     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
3304   }
3305 
3306   return Result;
3307 }
3308 
3309 /******************************************************************************
3310  * Function         phFriNfc_MifStd_H_GPBChk
3311  *
3312  * Description      This function is checks the GPB bytes.
3313  *
3314  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3315  *                  In case of failure returns other failure value.
3316  *
3317  ******************************************************************************/
phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t * NdefMap)3318 static NFCSTATUS phFriNfc_MifStd_H_GPBChk(phFriNfc_NdefMap_t* NdefMap) {
3319   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3320 
3321   /* Spec version needs to be checked every time (Version check is not enabled)
3322    */
3323   /* Result = phFriNfc_MapTool_ChkSpcVer(NdefMap, PH_FRINFC_MIFARESTD_VAL9); */
3324 
3325   /* Check rhe read and write access field
3326       in GPB is 00b
3327       bit 0 and 1 for write access check
3328       bit 2 and 3 for read access check */
3329   if (Result == NFCSTATUS_SUCCESS) {
3330     if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] &
3331           PH_FRINFC_MIFARESTD_MASK_GPB_WR) ==
3332          PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL) &&
3333         ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] &
3334           PH_FRINFC_MIFARESTD_MASK_GPB_RD) ==
3335          PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL)) {
3336       NdefMap->CardState = (((NdefMap->StdMifareContainer.ChkNdefFlag ==
3337                               PH_FRINFC_MIFARESTD_FLAG1) ||
3338                              (NdefMap->StdMifareContainer.ReadNdefFlag ==
3339                               PH_FRINFC_MIFARESTD_FLAG1) ||
3340                              (NdefMap->StdMifareContainer.WrNdefFlag ==
3341                               PH_FRINFC_MIFARESTD_FLAG1))
3342                                 ? PH_NDEFMAP_CARD_STATE_INITIALIZED
3343                                 : PH_NDEFMAP_CARD_STATE_READ_WRITE);
3344     } else if (((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] &
3345                  PH_FRINFC_MIFARESTD_MASK_GPB_WR) !=
3346                 PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL) &&
3347                ((NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL9] &
3348                  PH_FRINFC_MIFARESTD_MASK_GPB_RD) ==
3349                 PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL)) {
3350       /* write access not given
3351       only read access check */
3352       NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
3353     } else {
3354       NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
3355     }
3356   }
3357 
3358   return Result;
3359 }
3360 
3361 /******************************************************************************
3362  * Function         phFriNfc_MifStd_H_ProStatNotValid
3363  *
3364  * Description      This function checks for the different status value in the
3365  *                  process because of proprietary forum sector.
3366  *
3367  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3368  *                  In case of failure returns other failure value.
3369  *
3370  ******************************************************************************/
phFriNfc_MifStd_H_ProStatNotValid(phFriNfc_NdefMap_t * NdefMap,NFCSTATUS status)3371 static NFCSTATUS phFriNfc_MifStd_H_ProStatNotValid(phFriNfc_NdefMap_t* NdefMap,
3372                                                    NFCSTATUS status) {
3373   NFCSTATUS Result = status;
3374 
3375   /* if NFC forum sector is not found before the proprietary one then
3376      authenticate the next sector
3377      Else it is a error*/
3378   if (NdefMap->StdMifareContainer.NFCforumSectFlag ==
3379       PH_FRINFC_MIFARESTD_FLAG0) {
3380     NdefMap->StdMifareContainer.ProprforumSectFlag =
3381         PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG;
3382     if (NdefMap->StdMifareContainer.currentBlock <
3383         PH_FRINFC_MIFARESTD4K_BLK128) {
3384       /* Fix for the disovery problem,
3385          if 1st sector is invalid then ignore the remaining sectors and
3386          send an error if the card is mifare 1k,
3387          if the card is mifare 4k, then update the block number to 67 and
3388          continue.
3389          Even if the authentication of that block fails then send error */
3390       if (((NdefMap->StdMifareContainer.currentBlock <
3391             PH_FRINFC_MIFARESTD_BLK4) &&
3392            (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) ||
3393           ((NdefMap->StdMifareContainer.currentBlock <=
3394             PH_FRINFC_MIFARESTD_MAD_BLK67) &&
3395            (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD ||
3396             NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD))) {
3397         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
3398       } else if ((NdefMap->StdMifareContainer.currentBlock <
3399                   PH_FRINFC_MIFARESTD_BLK4) &&
3400                  (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD ||
3401                   NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) {
3402         Result = NFCSTATUS_SUCCESS;
3403         NdefMap->StdMifareContainer.currentBlock =
3404             PH_FRINFC_MIFARESTD_MAD_BLK67;
3405       } else if (((NdefMap->StdMifareContainer.currentBlock +
3406                    PH_FRINFC_MIFARESTD_BLK4) > PH_FRINFC_MIFARESTD1K_MAX_BLK) &&
3407                  (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) {
3408         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
3409       } else {
3410         NdefMap->StdMifareContainer.remainingSize -=
3411             (PH_FRINFC_MIFARESTD_MAD_BLK3 * PH_FRINFC_MIFARESTD_BLOCK_BYTES);
3412         NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4;
3413         Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
3414       }
3415     } else if ((NdefMap->StdMifareContainer.currentBlock +
3416                 PH_FRINFC_MIFARESTD_BLK15) > PH_FRINFC_MIFARESTD4K_MAX_BLK) {
3417       Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
3418     } else {
3419       NdefMap->StdMifareContainer.remainingSize -=
3420           (PH_FRINFC_MIFARESTD_BLK15 * PH_FRINFC_MIFARESTD_BLOCK_BYTES);
3421       NdefMap->StdMifareContainer.currentBlock +=
3422           PH_FRINFC_MIFARESTD_BLOCK_BYTES;
3423       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
3424     }
3425     Result =
3426         ((Result != NFCSTATUS_SUCCESS)
3427              ? (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT))
3428              : phFriNfc_MifStd_H_AuthSector(NdefMap));
3429   } else if ((NdefMap->StdMifareContainer.ProprforumSectFlag ==
3430               PH_FRINFC_MIFARESTD_PROP_3RD_CONFIG) &&
3431              (NdefMap->StdMifareContainer.NFCforumSectFlag ==
3432               PH_FRINFC_MIFARESTD_FLAG1)) {
3433     /*  if the proprietary forum sector are found before
3434         NFC forum sector then again a proprietary
3435         forum sector are found after the NFC forum
3436         sector */
3437     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
3438   } else {
3439     NdefMap->StdMifareContainer.ProprforumSectFlag =
3440         PH_FRINFC_MIFARESTD_PROP_2ND_CONFIG;
3441     switch (NdefMap->PrevOperation) {
3442       case PH_FRINFC_NDEFMAP_CHECK_OPE:
3443       case PH_FRINFC_NDEFMAP_GET_ACTSIZE_OPE:
3444         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
3445         break;
3446 
3447       case PH_FRINFC_NDEFMAP_READ_OPE:
3448         if ((NdefMap->TLVStruct.NdefTLVFoundFlag ==
3449              PH_FRINFC_MIFARESTD_FLAG1) &&
3450             (NdefMap->TLVStruct.NoLbytesinTLV == PH_FRINFC_MIFARESTD_VAL0)) {
3451           *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
3452           Result = NFCSTATUS_SUCCESS;
3453         } else {
3454           Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
3455         }
3456         break;
3457 
3458       case PH_FRINFC_NDEFMAP_WRITE_OPE:
3459       default:
3460         /* This means the further write is not possible,
3461            EOF_NDEF_CONTAINER_REACHED */
3462         NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
3463             PH_FRINFC_MIFARESTD_FLAG1;
3464         /* Write the length to the L field in the TLV */
3465         NdefMap->StdMifareContainer.TempBlockNo =
3466             NdefMap->StdMifareContainer.currentBlock;
3467         phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap);
3468         NdefMap->StdMifareContainer.currentBlock =
3469             NdefMap->TLVStruct.NdefTLVBlock;
3470         Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap);
3471         break;
3472     }
3473   }
3474 
3475   return Result;
3476 }
3477 
3478 /******************************************************************************
3479  * Function         phFriNfc_MifStd_H_RdBeforeWr
3480  *
3481  * Description      This function is used to read the NDEF TLV block.
3482  *
3483  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3484  *                  In case of failure returns other failure value.
3485  *
3486  ******************************************************************************/
phFriNfc_MifStd_H_RdBeforeWr(phFriNfc_NdefMap_t * NdefMap)3487 static NFCSTATUS phFriNfc_MifStd_H_RdBeforeWr(phFriNfc_NdefMap_t* NdefMap) {
3488   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3489 
3490   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_BEF_WR;
3491   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
3492 
3493   Result = phFriNfc_MifStd_H_Rd16Bytes(
3494       NdefMap, NdefMap->StdMifareContainer.currentBlock);
3495 
3496   return Result;
3497 }
3498 
3499 /******************************************************************************
3500  * Function         phFriNfc_MifStd_H_ProBytesToWr
3501  *
3502  * Description      This function processes the NDEF TLV block read bytes to
3503  *                  start write from the NDEF TLV.
3504  *
3505  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3506  *                  In case of failure returns other failure value.
3507  *
3508  ******************************************************************************/
phFriNfc_MifStd_H_ProBytesToWr(phFriNfc_NdefMap_t * NdefMap)3509 static NFCSTATUS phFriNfc_MifStd_H_ProBytesToWr(phFriNfc_NdefMap_t* NdefMap) {
3510   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3511   uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0;
3512 
3513   if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
3514     memmove(&NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1],
3515             NdefMap->SendRecvBuf, PH_FRINFC_MIFARESTD_BLOCK_BYTES);
3516 
3517     /* Write to Ndef TLV Block */
3518     NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3519         NdefMap->StdMifareContainer.currentBlock;
3520 
3521     TempLength = ((NdefMap->StdMifareContainer.currentBlock ==
3522                    NdefMap->TLVStruct.NdefTLVBlock)
3523                       ? phFriNfc_MifStd_H_UpdateTLV(NdefMap)
3524                       : phFriNfc_MifStd_H_UpdRemTLV(NdefMap));
3525 
3526     NdefMap->StdMifareContainer.remainingSize -=
3527         ((NdefMap->StdMifareContainer.remSizeUpdFlag ==
3528           PH_FRINFC_MIFARESTD_FLAG1)
3529              ? PH_FRINFC_MIFARESTD_VAL2
3530              : PH_FRINFC_MIFARESTD_VAL0);
3531 
3532     NdefMap->StdMifareContainer.remSizeUpdFlag = PH_FRINFC_MIFARESTD_FLAG0;
3533     NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_TLV;
3534     Result = ((TempLength == PH_FRINFC_MIFARESTD_BLOCK_BYTES)
3535                   ? phFriNfc_MifStd_H_WrTLV(NdefMap)
3536                   : phFriNfc_MifStd_H_fillSendBuf(NdefMap, TempLength));
3537   } else {
3538     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_READ_FAILED);
3539   }
3540 
3541   return Result;
3542 }
3543 
3544 /******************************************************************************
3545  * Function         phFriNfc_MifStd_H_UpdateTLV
3546  *
3547  * Description      This function writes ndef to add the TLV structure.
3548  *
3549  * Returns          uint8_t     TempLength
3550  *
3551  ******************************************************************************/
phFriNfc_MifStd_H_UpdateTLV(phFriNfc_NdefMap_t * NdefMap)3552 static uint8_t phFriNfc_MifStd_H_UpdateTLV(phFriNfc_NdefMap_t* NdefMap) {
3553   uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0;
3554 
3555   TempLength =
3556       (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL1);
3557   /* Creating TLV */
3558   if (NdefMap->TLVStruct.NULLTLVCount >= 2) {
3559     if ((PH_FRINFC_MIFARESTD_BYTES_READ - TempLength) ==
3560         PH_FRINFC_MIFARESTD_VAL0) {
3561       NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3562     } else {
3563       NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3564       TempLength++;
3565       NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0;
3566     }
3567   } else {
3568     switch ((PH_FRINFC_MIFARESTD_BYTES_READ - TempLength)) {
3569       case PH_FRINFC_MIFARESTD_VAL0:
3570         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3571         break;
3572 
3573       case PH_FRINFC_MIFARESTD_VAL1:
3574         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3575         TempLength++;
3576         NdefMap->TLVStruct.prevLenByteValue = (uint16_t)(
3577             (NdefMap->SendRecvBuf[TempLength] >= PH_FRINFC_MIFARESTD_NDEFTLV_L)
3578                 ? PH_FRINFC_MIFARESTD_VAL0
3579                 : NdefMap->SendRecvBuf[TempLength]);
3580         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3581         break;
3582 
3583       case PH_FRINFC_MIFARESTD_VAL2:
3584         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3585         TempLength++;
3586         NdefMap->TLVStruct.prevLenByteValue = (uint16_t)(
3587             (NdefMap->SendRecvBuf[TempLength] >= PH_FRINFC_MIFARESTD_NDEFTLV_L)
3588                 ? NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]
3589                 : NdefMap->SendRecvBuf[TempLength]);
3590         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3591         TempLength++;
3592         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3593         break;
3594 
3595       default:
3596         NdefMap->TLVStruct.prevLenByteValue = NdefMap->SendRecvBuf[TempLength];
3597         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3598         TempLength++;
3599         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3600         TempLength++;
3601         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3602         TempLength++;
3603         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0;
3604         break;
3605     }
3606   }
3607 
3608   return TempLength;
3609 }
3610 
3611 /******************************************************************************
3612  * Function         phFriNfc_MifStd_H_fillSendBuf
3613  *
3614  * Description      It fill the send buffer to write.
3615  *
3616  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3617  *                  In case of failure returns other failure value.
3618  *
3619  ******************************************************************************/
phFriNfc_MifStd_H_fillSendBuf(phFriNfc_NdefMap_t * NdefMap,uint8_t Length)3620 static NFCSTATUS phFriNfc_MifStd_H_fillSendBuf(phFriNfc_NdefMap_t* NdefMap,
3621                                                uint8_t Length) {
3622   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3623   uint16_t RemainingBytes = PH_FRINFC_MIFARESTD_VAL0,
3624            BytesToWrite = PH_FRINFC_MIFARESTD_VAL0;
3625   uint8_t index = PH_FRINFC_MIFARESTD_VAL0;
3626 
3627   Length = (Length + PH_FRINFC_MIFARESTD_VAL1);
3628 
3629   RemainingBytes =
3630       (uint16_t)((NdefMap->StdMifareContainer.remainingSize <
3631                   (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))
3632                      ? NdefMap->StdMifareContainer.remainingSize
3633                      : (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
3634 
3635   NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
3636       NdefMap->StdMifareContainer.currentBlock;
3637   /* Get the number of bytes that can be written after copying
3638      the internal buffer */
3639   BytesToWrite =
3640       ((RemainingBytes < ((PH_FRINFC_MIFARESTD_WR_A_BLK - Length) -
3641                           NdefMap->StdMifareContainer.internalLength))
3642            ? RemainingBytes
3643            : ((PH_FRINFC_MIFARESTD_WR_A_BLK - Length) -
3644               NdefMap->StdMifareContainer.internalLength));
3645 
3646   if (NdefMap->StdMifareContainer.internalLength > PH_FRINFC_MIFARESTD_VAL0) {
3647     /* copy the internal buffer to the send buffer */
3648     memcpy(&(NdefMap->SendRecvBuf[Length]),
3649            NdefMap->StdMifareContainer.internalBuf,
3650            NdefMap->StdMifareContainer.internalLength);
3651   }
3652 
3653   /* Copy Bytes to write in the send buffer */
3654   memcpy(&(NdefMap->SendRecvBuf[(Length +
3655                                  NdefMap->StdMifareContainer.internalLength)]),
3656          &(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]), BytesToWrite);
3657 
3658   /* update number of bytes written from the user buffer */
3659   NdefMap->NumOfBytesWritten = BytesToWrite;
3660 
3661   /* check the exact number of bytes written to a block including the
3662       internal length */
3663   *NdefMap->DataCount =
3664       ((BytesToWrite + NdefMap->StdMifareContainer.internalLength + Length) -
3665        PH_FRINFC_MIFARESTD_VAL1);
3666 
3667   /* if total bytes to write in the card is less than 4 bytes then
3668   pad zeroes till 4 bytes */
3669   if ((BytesToWrite + NdefMap->StdMifareContainer.internalLength + Length) <
3670       PH_FRINFC_MIFARESTD_WR_A_BLK) {
3671     for (index = (uint8_t)(BytesToWrite +
3672                            NdefMap->StdMifareContainer.internalLength + Length);
3673          index < PH_FRINFC_MIFARESTD_WR_A_BLK; index++) {
3674       NdefMap->SendRecvBuf[index] =
3675           (uint8_t)((index == (BytesToWrite + Length +
3676                                NdefMap->StdMifareContainer.internalLength))
3677                         ? PH_FRINFC_MIFARESTD_TERMTLV_T
3678                         : PH_FRINFC_MIFARESTD_NULLTLV_T);
3679 
3680       NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1;
3681     }
3682   }
3683 
3684   NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG1;
3685 
3686   /* A temporary buffer to hold four bytes of data that is
3687      written to the card */
3688   memcpy(NdefMap->StdMifareContainer.Buffer,
3689          &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]),
3690          PH_FRINFC_MIFARESTD_BLOCK_BYTES);
3691 
3692   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WR_TLV;
3693   Result = phFriNfc_MifStd_H_WrTLV(NdefMap);
3694 
3695   return Result;
3696 }
3697 
3698 /******************************************************************************
3699  * Function         phFriNfc_MifStd_H_WrTLV
3700  *
3701  * Description      This function writes 16 bytes in a block.
3702  *
3703  * Returns          This function return NFCSTATUS_SUCCESS in case of success
3704  *                  In case of failure returns other failure value.
3705  *
3706  ******************************************************************************/
phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t * NdefMap)3707 static NFCSTATUS phFriNfc_MifStd_H_WrTLV(phFriNfc_NdefMap_t* NdefMap) {
3708   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3709 
3710   NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
3711   NdefMap->MapCompletionInfo.Context = NdefMap;
3712   /* Write from here */
3713   NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE;
3714 
3715   NdefMap->Cmd.MfCmd = phHal_eMifareWrite16;
3716 
3717   *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
3718 
3719   /* Call the Overlapped HAL Transceive function */
3720   Result = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
3721                                     NdefMap->SendRecvBuf, NdefMap->SendLength,
3722                                     NdefMap->SendRecvLength);
3723 
3724   return Result;
3725 }
3726 
3727 /******************************************************************************
3728  * Function         phFriNfc_MifStd_H_ProWrTLV
3729  *
3730  * Description      This function processes the write TLV bytes in a block.
3731  *
3732  * Returns          This function return NFCSTATUS_SUCESS in case of success
3733  *                  In case of failure returns other failure value.
3734  *
3735  ******************************************************************************/
phFriNfc_MifStd_H_ProWrTLV(phFriNfc_NdefMap_t * NdefMap)3736 static NFCSTATUS phFriNfc_MifStd_H_ProWrTLV(phFriNfc_NdefMap_t* NdefMap) {
3737   NFCSTATUS Result = NFCSTATUS_SUCCESS;
3738 
3739   /* Check that if complete TLV has been written in the
3740      card if yes enter the below check or go to else*/
3741   if (((((PH_FRINFC_MIFARESTD_BLOCK_BYTES - NdefMap->TLVStruct.NdefTLVByte) ==
3742          PH_FRINFC_MIFARESTD_VAL1) &&
3743         (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2)) ||
3744        (((PH_FRINFC_MIFARESTD_BLOCK_BYTES - NdefMap->TLVStruct.NdefTLVByte) <=
3745          PH_FRINFC_MIFARESTD_VAL3) &&
3746         (NdefMap->TLVStruct.NULLTLVCount == PH_FRINFC_MIFARESTD_VAL0))) &&
3747       (NdefMap->StdMifareContainer.currentBlock ==
3748        NdefMap->TLVStruct.NdefTLVBlock)) {
3749     /* increment the block and chekc the block is in the same sector
3750        using the block check function */
3751     NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG1;
3752     NdefMap->StdMifareContainer.currentBlock++;
3753     NdefMap->StdMifareContainer.NdefBlocks++;
3754     Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
3755     if (Result == NFCSTATUS_SUCCESS) {
3756       Result =
3757           ((NdefMap->StdMifareContainer.AuthDone == PH_FRINFC_MIFARESTD_FLAG0)
3758                ? phFriNfc_MifStd_H_AuthSector(NdefMap)
3759                : phFriNfc_MifStd_H_RdBeforeWr(NdefMap));
3760     }
3761   } else {
3762     NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
3763     if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) {
3764       if (*NdefMap->DataCount < PH_FRINFC_MIFARESTD_BLOCK_BYTES) {
3765         /* Write complete, so next byte shall be */
3766         NdefMap->StdMifareContainer.internalLength = *NdefMap->DataCount;
3767 
3768         /* Copy bytes less than 16 to internal buffer
3769            for the next write this can be used */
3770         memcpy(NdefMap->StdMifareContainer.internalBuf,
3771                NdefMap->StdMifareContainer.Buffer,
3772                NdefMap->StdMifareContainer.internalLength);
3773       }
3774 
3775       /* Increment the Send Buffer index */
3776       NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten;
3777 
3778       NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten;
3779 
3780       /* Check for the End of Card */
3781       if ((NdefMap->StdMifareContainer.remainingSize ==
3782            PH_FRINFC_MIFARESTD_VAL0) ||
3783           (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize)) {
3784         NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
3785             (uint8_t)((NdefMap->StdMifareContainer.remainingSize == 0)
3786                           ? PH_FRINFC_MIFARESTD_FLAG1
3787                           : PH_FRINFC_MIFARESTD_FLAG0);
3788 
3789         if (NdefMap->StdMifareContainer.internalLength ==
3790             PH_FRINFC_MIFARESTD_VAL0) {
3791           NdefMap->StdMifareContainer.currentBlock++;
3792           /* Mifare 4k Card, After 128th Block
3793           each sector = 16 blocks in Mifare 4k */
3794           Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
3795           NdefMap->StdMifareContainer.NdefBlocks++;
3796         }
3797 
3798         NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)(
3799             ((NdefMap->StdMifareContainer.remainingSize ==
3800               PH_FRINFC_MIFARESTD_VAL0) ||
3801              (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1))
3802                 ? PH_FRINFC_MIFARESTD_FLAG1
3803                 : PH_FRINFC_MIFARESTD_FLAG0);
3804 
3805       } else {
3806         NdefMap->StdMifareContainer.currentBlock++;
3807         /* Mifare 4k Card, After 128th Block
3808         each sector = 16 blocks in Mifare 4k */
3809         Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
3810         if (Result == NFCSTATUS_SUCCESS) {
3811           NdefMap->StdMifareContainer.NdefBlocks++;
3812           Result = ((NdefMap->StdMifareContainer.AuthDone ==
3813                      PH_FRINFC_MIFARESTD_FLAG1)
3814                         ? phFriNfc_MifStd_H_WrABlock(NdefMap)
3815                         : phFriNfc_MifStd_H_AuthSector(NdefMap));
3816         }
3817       }
3818     }
3819   }
3820 
3821   if ((Result == NFCSTATUS_SUCCESS) &&
3822       (NdefMap->TLVStruct.SetTermTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) &&
3823       (NdefMap->StdMifareContainer.remainingSize > PH_FRINFC_MIFARESTD_VAL0)) {
3824     Result = phFriNfc_MifStd_H_WrTermTLV(NdefMap);
3825   } else {
3826     if ((Result == NFCSTATUS_SUCCESS) &&
3827         (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) {
3828       /* Write the length to the L field in the TLV */
3829       NdefMap->StdMifareContainer.TempBlockNo =
3830           NdefMap->StdMifareContainer.currentBlock;
3831       phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap);
3832       NdefMap->StdMifareContainer.currentBlock =
3833           NdefMap->TLVStruct.NdefTLVBlock;
3834       Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap);
3835     }
3836   }
3837 
3838   return Result;
3839 }
3840 
3841 /******************************************************************************
3842  * Function         phFriNfc_MifStd_H_UpdRemTLV
3843  *
3844  * Description      This function updates the remaining TLV.
3845  *
3846  * Returns          uint8_t     TempLength : length value
3847  *
3848  ******************************************************************************/
phFriNfc_MifStd_H_UpdRemTLV(phFriNfc_NdefMap_t * NdefMap)3849 static uint8_t phFriNfc_MifStd_H_UpdRemTLV(phFriNfc_NdefMap_t* NdefMap) {
3850   uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL1;
3851 
3852   if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) {
3853     NdefMap->TLVStruct.prevLenByteValue = NdefMap->SendRecvBuf[TempLength];
3854     NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0;
3855   } else {
3856     switch (
3857         (PH_FRINFC_MIFARESTD_BLOCK_BYTES - NdefMap->TLVStruct.NdefTLVByte)) {
3858       case PH_FRINFC_MIFARESTD_VAL1:
3859         NdefMap->TLVStruct.prevLenByteValue =
3860             (((NdefMap->SendRecvBuf[TempLength] ==
3861                PH_FRINFC_MIFARESTD_NDEFTLV_L))
3862                  ? (((uint16_t)NdefMap
3863                          ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)]
3864                      << PH_FRINFC_MIFARESTD_LEFTSHIFT8) +
3865                     NdefMap
3866                         ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL2)])
3867                  : NdefMap->SendRecvBuf[TempLength]);
3868         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
3869         TempLength++;
3870         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3871         TempLength++;
3872         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0;
3873         break;
3874 
3875       case PH_FRINFC_MIFARESTD_VAL2:
3876         NdefMap->TLVStruct.prevLenByteValue =
3877             (((NdefMap->SendRecvBuf[TempLength] ==
3878                PH_FRINFC_MIFARESTD_NDEFTLV_L))
3879                  ? (((uint16_t)NdefMap->SendRecvBuf[TempLength]
3880                      << PH_FRINFC_MIFARESTD_LEFTSHIFT8) +
3881                     NdefMap
3882                         ->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)])
3883                  : NdefMap->SendRecvBuf[TempLength]);
3884         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3885         TempLength++;
3886         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0;
3887         break;
3888 
3889       case PH_FRINFC_MIFARESTD_VAL3:
3890       default:
3891         NdefMap->TLVStruct.prevLenByteValue =
3892             ((NdefMap->TLVStruct.prevLenByteValue
3893               << PH_FRINFC_MIFARESTD_LEFTSHIFT8) +
3894              NdefMap->SendRecvBuf[TempLength]);
3895         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L0;
3896         break;
3897     }
3898   }
3899 
3900   return TempLength;
3901 }
3902 
3903 /******************************************************************************
3904  * Function         phFriNfc_MifStd_H_fillTLV1
3905  *
3906  * Description      This function updates the length field if more than one
3907  *                  NULL TLVs exists before of the NDEF TLV.
3908  *
3909  * Returns          void
3910  *
3911  ******************************************************************************/
phFriNfc_MifStd_H_fillTLV1(phFriNfc_NdefMap_t * NdefMap)3912 static void phFriNfc_MifStd_H_fillTLV1(phFriNfc_NdefMap_t* NdefMap) {
3913   uint8_t TempLength =
3914       (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL1);
3915 
3916   NdefMap->TLVStruct.prevLenByteValue =
3917       ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR)
3918            ? (NdefMap->TLVStruct.prevLenByteValue + NdefMap->ApduBuffIndex)
3919            : NdefMap->ApduBuffIndex);
3920 
3921   NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG1;
3922   switch (NdefMap->TLVStruct.NdefTLVByte) {
3923     case PH_FRINFC_MIFARESTD_VAL0:
3924       if (NdefMap->TLVStruct.prevLenByteValue >=
3925           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
3926         NdefMap->SendRecvBuf[TempLength] =
3927             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
3928                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
3929         NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] =
3930             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
3931       } else {
3932         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3933         NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] =
3934             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
3935 
3936         NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
3937       }
3938       break;
3939 
3940     case PH_FRINFC_MIFARESTD_VAL1:
3941       if (NdefMap->TLVStruct.prevLenByteValue >=
3942           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
3943         NdefMap->SendRecvBuf[TempLength - PH_FRINFC_MIFARESTD_VAL1] =
3944             PH_FRINFC_MIFARESTD_NDEFTLV_L;
3945         NdefMap->SendRecvBuf[TempLength] =
3946             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
3947                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
3948         NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] =
3949             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
3950       } else {
3951         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3952         NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] =
3953             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
3954         NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
3955       }
3956       break;
3957 
3958     case PH_FRINFC_MIFARESTD_VAL15:
3959       /* if "Type" of TLV present at byte 15 */
3960       if (NdefMap->TLVStruct.prevLenByteValue >=
3961           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
3962         /* Update the null TLV, ndef TLV block and ndef TLV byte */
3963         NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
3964         NdefMap->TLVStruct.NdefTLVBlock =
3965             NdefMap->StdMifareContainer.currentBlock;
3966         NdefMap->TLVStruct.NdefTLVByte =
3967             (TempLength - PH_FRINFC_MIFARESTD_VAL3);
3968 
3969         NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL2)] =
3970             PH_FRINFC_MIFARESTD_NDEFTLV_T;
3971         NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)] =
3972             PH_FRINFC_MIFARESTD_NDEFTLV_L;
3973         NdefMap->SendRecvBuf[TempLength] =
3974             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
3975                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
3976       } else {
3977         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
3978       }
3979       break;
3980 
3981     default:
3982       /* Already the TLV is present so just append the length field */
3983       if (NdefMap->TLVStruct.prevLenByteValue >=
3984           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
3985         /* Update the null TLV, ndef TLV block and ndef TLV byte */
3986         NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
3987         NdefMap->TLVStruct.NdefTLVBlock =
3988             NdefMap->StdMifareContainer.currentBlock;
3989         NdefMap->TLVStruct.NdefTLVByte =
3990             (TempLength - PH_FRINFC_MIFARESTD_VAL3);
3991 
3992         NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL2)] =
3993             (uint8_t)PH_FRINFC_MIFARESTD_NDEFTLV_T;
3994         NdefMap->SendRecvBuf[(TempLength - PH_FRINFC_MIFARESTD_VAL1)] =
3995             (uint8_t)PH_FRINFC_MIFARESTD_NDEFTLV_L;
3996         NdefMap->SendRecvBuf[TempLength] =
3997             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
3998                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
3999         NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] =
4000             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4001       } else {
4002         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4003         NdefMap->SendRecvBuf[(TempLength + PH_FRINFC_MIFARESTD_VAL1)] =
4004             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4005       }
4006       NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
4007       break;
4008   }
4009 
4010   return;
4011 }
4012 
4013 /******************************************************************************
4014  * Function         phFriNfc_MifStd_H_fillTLV2
4015  *
4016  * Description      This function is updates the length field if more than one
4017  *                  NULL TLVs does not exists before the TLV.
4018  *
4019  * Returns          void
4020  *
4021  ******************************************************************************/
phFriNfc_MifStd_H_fillTLV2(phFriNfc_NdefMap_t * NdefMap)4022 static void phFriNfc_MifStd_H_fillTLV2(phFriNfc_NdefMap_t* NdefMap) {
4023   uint8_t TempLength =
4024       (uint8_t)(NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL1);
4025 
4026   NdefMap->TLVStruct.prevLenByteValue =
4027       ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR)
4028            ? (NdefMap->TLVStruct.prevLenByteValue + NdefMap->ApduBuffIndex)
4029            : NdefMap->ApduBuffIndex);
4030   NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG1;
4031   switch (NdefMap->TLVStruct.NdefTLVByte) {
4032     case PH_FRINFC_MIFARESTD_VAL13:
4033       if (NdefMap->TLVStruct.prevLenByteValue >=
4034           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
4035         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4036         TempLength++;
4037         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L;
4038         TempLength++;
4039         NdefMap->SendRecvBuf[TempLength] =
4040             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
4041                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
4042       } else {
4043         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4044         TempLength++;
4045         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4046         TempLength++;
4047 
4048         /* Update the null TLV, ndef TLV block and ndef TLV byte */
4049         NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2;
4050         NdefMap->TLVStruct.NdefTLVBlock =
4051             NdefMap->StdMifareContainer.currentBlock;
4052         NdefMap->TLVStruct.NdefTLVByte =
4053             (TempLength - PH_FRINFC_MIFARESTD_VAL1);
4054 
4055         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4056       }
4057       break;
4058 
4059     case PH_FRINFC_MIFARESTD_VAL14:
4060       if (NdefMap->TLVStruct.prevLenByteValue >=
4061           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
4062         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4063         TempLength++;
4064         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L;
4065       } else {
4066         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4067         TempLength++;
4068         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4069       }
4070       break;
4071 
4072     case PH_FRINFC_MIFARESTD_VAL15:
4073       if (NdefMap->TLVStruct.prevLenByteValue >=
4074           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
4075         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4076       } else {
4077         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4078       }
4079       break;
4080 
4081     default:
4082       if (NdefMap->TLVStruct.prevLenByteValue >=
4083           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
4084         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4085         TempLength++;
4086         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L;
4087         TempLength++;
4088         NdefMap->SendRecvBuf[TempLength] =
4089             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
4090                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
4091         TempLength++;
4092         NdefMap->SendRecvBuf[TempLength] =
4093             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4094       } else {
4095         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4096         TempLength++;
4097         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4098         TempLength++;
4099 
4100         /* Update the null TLV, ndef TLV block and ndef TLV byte */
4101         NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2;
4102         NdefMap->TLVStruct.NdefTLVBlock =
4103             NdefMap->StdMifareContainer.currentBlock;
4104         NdefMap->TLVStruct.NdefTLVByte =
4105             (TempLength - PH_FRINFC_MIFARESTD_VAL1);
4106 
4107         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4108         TempLength++;
4109         NdefMap->SendRecvBuf[TempLength] =
4110             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4111       }
4112       NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
4113       break;
4114   }
4115 
4116   return;
4117 }
4118 
4119 /******************************************************************************
4120  * Function         phFriNfc_MifStd_H_CallWrNdefLen
4121  *
4122  * Description      This function is used to increment/decrement the ndef tlv
4123  *block and read the block.
4124  *
4125  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4126  *                  In case of failure returns other failure value.
4127  *
4128  ******************************************************************************/
phFriNfc_MifStd_H_CallWrNdefLen(phFriNfc_NdefMap_t * NdefMap)4129 static NFCSTATUS phFriNfc_MifStd_H_CallWrNdefLen(phFriNfc_NdefMap_t* NdefMap) {
4130   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4131 
4132   if (NdefMap->TLVStruct.NULLTLVCount >= PH_FRINFC_MIFARESTD_VAL2) {
4133     if ((NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL0) ||
4134         (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL1)) {
4135       /* In this case, current block is decremented because the
4136          NULL TLVs are in the previous block */
4137       NdefMap->StdMifareContainer.currentBlock--;
4138       Result = phFriNfc_MifStd_H_BlkChk_1(NdefMap);
4139     } else {
4140       /* case NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL15:
4141          Current block is incremented to update the remaining TLV
4142          structure */
4143       NdefMap->StdMifareContainer.currentBlock++;
4144       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
4145     }
4146   } else {
4147     if ((NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL13) ||
4148         (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL14) ||
4149         (NdefMap->TLVStruct.NdefTLVByte == PH_FRINFC_MIFARESTD_VAL15)) {
4150       /* Current block is incremented to update the remaining TLV
4151           structure */
4152       NdefMap->StdMifareContainer.currentBlock++;
4153       Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
4154     }
4155   }
4156 
4157   Result =
4158       ((Result == NFCSTATUS_SUCCESS) ? phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap)
4159                                      : Result);
4160 
4161   return Result;
4162 }
4163 
4164 /******************************************************************************
4165  * Function         phFriNfc_MifStd_H_BlkChk_1
4166  *
4167  * Description      This function check the current block is valid or not
4168  *                  if not valid decrement the current block till the valid
4169  *block.
4170  *
4171  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4172  *                  In case of failure returns other failure value.
4173  *
4174  ******************************************************************************/
phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t * NdefMap)4175 static NFCSTATUS phFriNfc_MifStd_H_BlkChk_1(phFriNfc_NdefMap_t* NdefMap) {
4176   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4177   uint8_t SectorID = PH_FRINFC_MIFARESTD_VAL0;
4178 
4179   /* Get a Sector ID for the Current Block */
4180   SectorID =
4181       phFriNfc_MifStd_H_GetSect(NdefMap->StdMifareContainer.currentBlock);
4182 
4183   /* Check the sector id is valid or not and if valid then check the
4184       current block is greater than 128 */
4185   if ((NdefMap->StdMifareContainer.aid[SectorID] ==
4186        PH_FRINFC_MIFARESTD_NDEF_COMP) &&
4187       (((SectorID <= PH_FRINFC_MIFARESTD_VAL15) &&
4188         (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD)) ||
4189        ((SectorID <= PH_FRINFC_MIFARESTD_SECTOR_NO31) &&
4190         (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD)) ||
4191        ((SectorID <= PH_FRINFC_MIFARESTD_SECTOR_NO39) &&
4192         (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)))) {
4193     if (NdefMap->StdMifareContainer.currentBlock > 128) {
4194       NdefMap->TLVStruct.NdefTLVAuthFlag =
4195           ((((NdefMap->StdMifareContainer.currentBlock +
4196               PH_FRINFC_MIFARESTD_VAL1) %
4197              PH_FRINFC_MIFARESTD_MAD_BLK16) == PH_FRINFC_MIFARESTD_VAL0)
4198                ? PH_FRINFC_MIFARESTD_FLAG1
4199                : PH_FRINFC_MIFARESTD_FLAG0);
4200 
4201       NdefMap->StdMifareContainer.currentBlock -=
4202           ((((NdefMap->StdMifareContainer.currentBlock +
4203               PH_FRINFC_MIFARESTD_VAL1) %
4204              PH_FRINFC_MIFARESTD_MAD_BLK16) == PH_FRINFC_MIFARESTD_VAL0)
4205                ? PH_FRINFC_MIFARESTD_VAL1
4206                : PH_FRINFC_MIFARESTD_VAL0);
4207 
4208     } else {
4209       NdefMap->TLVStruct.NdefTLVAuthFlag =
4210           ((((NdefMap->StdMifareContainer.currentBlock +
4211               PH_FRINFC_MIFARESTD_VAL1) %
4212              PH_FRINFC_MIFARESTD_BLK4) == PH_FRINFC_MIFARESTD_VAL0)
4213                ? PH_FRINFC_MIFARESTD_FLAG1
4214                : PH_FRINFC_MIFARESTD_FLAG0);
4215 
4216       NdefMap->StdMifareContainer.currentBlock -=
4217           ((((NdefMap->StdMifareContainer.currentBlock +
4218               PH_FRINFC_MIFARESTD_VAL1) %
4219              PH_FRINFC_MIFARESTD_BLK4) == PH_FRINFC_MIFARESTD_VAL1)
4220                ? PH_FRINFC_MIFARESTD_VAL1
4221                : PH_FRINFC_MIFARESTD_VAL0);
4222     }
4223   } else {
4224     /*Error: No Ndef Compliant Sectors present.*/
4225     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
4226   }
4227 
4228   return Result;
4229 }
4230 
4231 /******************************************************************************
4232  * Function         phFriNfc_MifStd_H_fillTLV1_1
4233  *
4234  * Description      This function updates the length of the TLV if NULL TLVs
4235  *                  greater than or equal to 2.
4236  *
4237  * Returns          void
4238  *
4239  ******************************************************************************/
phFriNfc_MifStd_H_fillTLV1_1(phFriNfc_NdefMap_t * NdefMap)4240 static void phFriNfc_MifStd_H_fillTLV1_1(phFriNfc_NdefMap_t* NdefMap) {
4241   switch (NdefMap->TLVStruct.NdefTLVByte) {
4242     case PH_FRINFC_MIFARESTD_VAL0:
4243       /* In the first write ndef length procedure, the
4244          length is updated, in this case T and L = 0xFF of TLV are
4245          updated */
4246       NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
4247       NdefMap->TLVStruct.NdefTLVBlock =
4248           NdefMap->StdMifareContainer.currentBlock;
4249       NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL14;
4250 
4251       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL15] =
4252           PH_FRINFC_MIFARESTD_NDEFTLV_T;
4253       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL16] =
4254           PH_FRINFC_MIFARESTD_NDEFTLV_L;
4255       break;
4256 
4257     case PH_FRINFC_MIFARESTD_VAL1:
4258       /* In the first write ndef length procedure, the
4259          length is updated, in this case T of TLV is
4260          updated */
4261       NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL0;
4262       NdefMap->TLVStruct.NdefTLVBlock =
4263           NdefMap->StdMifareContainer.currentBlock;
4264       NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_MIFARESTD_VAL15;
4265       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL16] =
4266           PH_FRINFC_MIFARESTD_NDEFTLV_T;
4267       break;
4268 
4269     case PH_FRINFC_MIFARESTD_VAL15:
4270     default:
4271       /* In the first ndef write length, part of the L field or only T
4272          (if update length is less than 255) is updated */
4273       NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1] =
4274           (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4275       break;
4276   }
4277   NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
4278 
4279   return;
4280 }
4281 
4282 /******************************************************************************
4283  * Function         phFriNfc_MifStd_H_fillTLV2_1
4284  *
4285  * Description      This function updates the length of the TLV if NULL TLVs
4286  *                  less than 2.
4287  *
4288  * Returns          void
4289  *
4290  ******************************************************************************/
phFriNfc_MifStd_H_fillTLV2_1(phFriNfc_NdefMap_t * NdefMap)4291 static void phFriNfc_MifStd_H_fillTLV2_1(phFriNfc_NdefMap_t* NdefMap) {
4292   uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL1;
4293   switch (NdefMap->TLVStruct.NdefTLVByte) {
4294     case PH_FRINFC_MIFARESTD_VAL13:
4295       /* In last write ndef length, part of length (L) field of TLV
4296          is updated now */
4297       NdefMap->SendRecvBuf[TempLength] =
4298           (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4299       break;
4300 
4301     case PH_FRINFC_MIFARESTD_VAL14:
4302       /* In last write ndef length, part of length (L) field of TLV
4303          is updated now */
4304       if (NdefMap->TLVStruct.prevLenByteValue >=
4305           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
4306         NdefMap->SendRecvBuf[TempLength] =
4307             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
4308                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
4309         TempLength++;
4310         NdefMap->SendRecvBuf[TempLength] =
4311             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4312       } else {
4313         NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2;
4314         NdefMap->TLVStruct.NdefTLVBlock =
4315             NdefMap->StdMifareContainer.currentBlock;
4316         NdefMap->TLVStruct.NdefTLVByte =
4317             (TempLength - PH_FRINFC_MIFARESTD_VAL1);
4318         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4319         TempLength++;
4320         NdefMap->SendRecvBuf[TempLength] =
4321             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4322       }
4323       break;
4324 
4325     case PH_FRINFC_MIFARESTD_VAL15:
4326     default:
4327       if (NdefMap->TLVStruct.prevLenByteValue >=
4328           PH_FRINFC_MIFARESTD_NDEFTLV_L) {
4329         /* In last write ndef length, only T of TLV is updated and
4330            length (L) field of TLV is updated now */
4331         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_L;
4332         TempLength++;
4333         NdefMap->SendRecvBuf[TempLength] =
4334             (uint8_t)(NdefMap->TLVStruct.prevLenByteValue >>
4335                       PH_FRINFC_MIFARESTD_RIGHTSHIFT8);
4336         TempLength++;
4337         NdefMap->SendRecvBuf[TempLength] =
4338             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4339       } else {
4340         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4341         TempLength++;
4342         NdefMap->TLVStruct.NULLTLVCount = PH_FRINFC_MIFARESTD_VAL2;
4343         NdefMap->TLVStruct.NdefTLVBlock =
4344             NdefMap->StdMifareContainer.currentBlock;
4345         NdefMap->TLVStruct.NdefTLVByte =
4346             (TempLength - PH_FRINFC_MIFARESTD_VAL1);
4347         NdefMap->SendRecvBuf[TempLength] = PH_FRINFC_MIFARESTD_NDEFTLV_T;
4348         TempLength++;
4349         NdefMap->SendRecvBuf[TempLength] =
4350             (uint8_t)NdefMap->TLVStruct.prevLenByteValue;
4351       }
4352       break;
4353   }
4354   NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
4355 
4356   return;
4357 }
4358 
4359 /******************************************************************************
4360  * Function         phFriNfc_MifStd_H_RdTLV
4361  *
4362  * Description      This function reads the TLV block.
4363  *
4364  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4365  *                  In case of failure returns other failure value.
4366  *
4367  ******************************************************************************/
phFriNfc_MifStd_H_RdTLV(phFriNfc_NdefMap_t * NdefMap)4368 static NFCSTATUS phFriNfc_MifStd_H_RdTLV(phFriNfc_NdefMap_t* NdefMap) {
4369   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4370 
4371   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_TLV;
4372   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
4373 
4374   Result = phFriNfc_MifStd_H_Rd16Bytes(
4375       NdefMap, NdefMap->StdMifareContainer.currentBlock);
4376 
4377   return Result;
4378 }
4379 
4380 /******************************************************************************
4381  * Function         phFriNfc_MifStd_H_ProRdTLV
4382  *
4383  * Description      This function processes the read TLV block.
4384  *
4385  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4386  *                  In case of failure returns other failure value.
4387  *
4388  ******************************************************************************/
phFriNfc_MifStd_H_ProRdTLV(phFriNfc_NdefMap_t * NdefMap)4389 static NFCSTATUS phFriNfc_MifStd_H_ProRdTLV(phFriNfc_NdefMap_t* NdefMap) {
4390   NFCSTATUS Result =
4391       PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST);
4392   uint8_t TempLength = PH_FRINFC_MIFARESTD_VAL0,
4393           NDEFFlag = PH_FRINFC_MIFARESTD_FLAG1;
4394 
4395   /*TempLength = (uint8_t)(((NdefMap->TLVStruct.NULLTLVCount >=
4396               PH_FRINFC_MIFARESTD_VAL2) &&
4397               (NdefMap->TLVStruct.BytesRemainLinTLV > 0xFE))?
4398               ((NdefMap->TLVStruct.NdefTLVByte +
4399               PH_FRINFC_MIFARESTD_VAL2)%
4400               PH_FRINFC_MIFARESTD_VAL16):
4401               ((NdefMap->TLVStruct.NdefTLVByte +
4402               PH_FRINFC_MIFARESTD_VAL4)%
4403               PH_FRINFC_MIFARESTD_VAL16));*/
4404 
4405   TempLength = (uint8_t)(
4406       (NdefMap->TLVStruct.BytesRemainLinTLV <= 0xFE)
4407           ? ((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL2) %
4408              PH_FRINFC_MIFARESTD_VAL16)
4409           : ((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_MIFARESTD_VAL4) %
4410              PH_FRINFC_MIFARESTD_VAL16));
4411 
4412   if ((*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) &&
4413       (NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize)) {
4414     if (NdefMap->TLVStruct.BytesRemainLinTLV != 0) {
4415       NDEFFlag = PH_FRINFC_MIFARESTD_FLAG0;
4416       /* To read the remaining length (L) in TLV */
4417       Result = phFriNfc_MifStd_H_RemainTLV(NdefMap, &NDEFFlag, &TempLength);
4418     }
4419   }
4420 
4421   return Result;
4422 }
4423 
4424 /******************************************************************************
4425  * Function         phFriNfc_MifStd_H_WrTermTLV
4426  *
4427  * Description      This function is used to write the terminator TLV.
4428  *
4429  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4430  *                  In case of failure returns other failure value.
4431  *
4432  ******************************************************************************/
phFriNfc_MifStd_H_WrTermTLV(phFriNfc_NdefMap_t * NdefMap)4433 static NFCSTATUS phFriNfc_MifStd_H_WrTermTLV(phFriNfc_NdefMap_t* NdefMap) {
4434   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4435   uint8_t index = PH_FRINFC_MIFARESTD_VAL0;
4436 
4437   /* Change the state to check ndef compliancy */
4438   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_TERM_TLV;
4439 
4440   NdefMap->SendRecvBuf[index] = NdefMap->StdMifareContainer.currentBlock;
4441   index++;
4442   NdefMap->SendRecvBuf[index] = PH_FRINFC_MIFARESTD_TERMTLV_T;
4443   index++;
4444 
4445   while (index < PH_FRINFC_MIFARESTD_WR_A_BLK) {
4446     NdefMap->SendRecvBuf[index] = PH_FRINFC_MIFARESTD_NULLTLV_T;
4447     index++;
4448   }
4449 
4450   NdefMap->TLVStruct.SetTermTLVFlag = PH_FRINFC_MIFARESTD_FLAG0;
4451 
4452   Result = phFriNfc_MifStd_H_WrTLV(NdefMap);
4453 
4454   return Result;
4455 }
4456 
4457 /******************************************************************************
4458  * Function         phFriNfc_MifStd_H_ProWrABlock
4459  *
4460  * Description      This function processes the write a block.
4461  *
4462  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4463  *                  In case of failure returns other failure value.
4464  *
4465  ******************************************************************************/
phFriNfc_MifStd_H_ProWrABlock(phFriNfc_NdefMap_t * NdefMap)4466 static NFCSTATUS phFriNfc_MifStd_H_ProWrABlock(phFriNfc_NdefMap_t* NdefMap) {
4467   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4468 
4469   NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL0;
4470   if (NdefMap->ApduBuffIndex < (uint16_t)NdefMap->ApduBufferSize) {
4471     /* Remaining bytes to write < 16 */
4472     if (NdefMap->StdMifareContainer.RemainingBufFlag ==
4473         PH_FRINFC_MIFARESTD_FLAG1) {
4474       /* Write complete, so next byte shall be */
4475       NdefMap->StdMifareContainer.internalLength = *NdefMap->DataCount;
4476 
4477       /* Copy bytes less than 16 to internal buffer
4478          for the next write this can be used */
4479       memcpy(NdefMap->StdMifareContainer.internalBuf,
4480              NdefMap->StdMifareContainer.Buffer,
4481              NdefMap->StdMifareContainer.internalLength);
4482 
4483       /* Increment the Send Buffer index */
4484       NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten;
4485 
4486       NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten;
4487 
4488       NdefMap->StdMifareContainer.RemainingBufFlag = PH_FRINFC_MIFARESTD_VAL0;
4489       /* Check for the End of Card */
4490       NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
4491           (uint8_t)((NdefMap->StdMifareContainer.remainingSize ==
4492                      PH_FRINFC_MIFARESTD_VAL0)
4493                         ? PH_FRINFC_MIFARESTD_FLAG1
4494                         : PH_FRINFC_MIFARESTD_FLAG0);
4495 
4496       NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)(
4497           ((NdefMap->StdMifareContainer.remainingSize ==
4498             PH_FRINFC_MIFARESTD_VAL0) ||
4499            (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1))
4500               ? PH_FRINFC_MIFARESTD_FLAG1
4501               : PH_FRINFC_MIFARESTD_FLAG0);
4502 
4503     } /* internal Buffer > Send Buffer */
4504     else if (NdefMap->StdMifareContainer.internalBufFlag ==
4505              PH_FRINFC_MIFARESTD_FLAG1) {
4506       memcpy(NdefMap->StdMifareContainer.internalBuf,
4507              NdefMap->StdMifareContainer.Buffer, *NdefMap->DataCount);
4508 
4509       NdefMap->StdMifareContainer.internalLength = *NdefMap->DataCount;
4510 
4511       /* Increment the Send Buffer index */
4512       NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten;
4513 
4514       NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten;
4515 
4516       NdefMap->StdMifareContainer.internalBufFlag = PH_FRINFC_MIFARESTD_FLAG0;
4517       /* Check for the End of Card */
4518       NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
4519           (uint8_t)(((NdefMap->StdMifareContainer.remainingSize ==
4520                       PH_FRINFC_MIFARESTD_VAL0) &&
4521                      (NdefMap->StdMifareContainer.internalLength ==
4522                       PH_FRINFC_MIFARESTD_VAL0))
4523                         ? PH_FRINFC_MIFARESTD_FLAG1
4524                         : PH_FRINFC_MIFARESTD_FLAG0);
4525 
4526       NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)(
4527           ((NdefMap->StdMifareContainer.remainingSize ==
4528             PH_FRINFC_MIFARESTD_VAL0) ||
4529            (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1))
4530               ? PH_FRINFC_MIFARESTD_FLAG1
4531               : PH_FRINFC_MIFARESTD_FLAG0);
4532     } else {
4533       NdefMap->StdMifareContainer.internalLength = 0;
4534       /* Increment the Send Buffer index */
4535       NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten;
4536       NdefMap->StdMifareContainer.remainingSize -= NdefMap->NumOfBytesWritten;
4537 
4538       /* Check for the End of Card */
4539       if ((NdefMap->StdMifareContainer.remainingSize ==
4540            PH_FRINFC_MIFARESTD_VAL0) ||
4541           (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize)) {
4542         NdefMap->StdMifareContainer.ReadWriteCompleteFlag =
4543             (uint8_t)((NdefMap->StdMifareContainer.remainingSize == 0)
4544                           ? PH_FRINFC_MIFARESTD_FLAG1
4545                           : PH_FRINFC_MIFARESTD_FLAG0);
4546 
4547         if (NdefMap->StdMifareContainer.internalLength ==
4548             PH_FRINFC_MIFARESTD_VAL0) {
4549           NdefMap->StdMifareContainer.currentBlock++;
4550           /* Mifare 4k Card, After 128th Block
4551           each sector = 16 blocks in Mifare 4k */
4552           Result = ((NdefMap->StdMifareContainer.remainingSize == 0)
4553                         ? Result
4554                         : phFriNfc_MifStd_H_BlkChk(NdefMap));
4555           NdefMap->StdMifareContainer.NdefBlocks++;
4556         }
4557         NdefMap->TLVStruct.SetTermTLVFlag = (uint8_t)(
4558             ((NdefMap->StdMifareContainer.remainingSize ==
4559               PH_FRINFC_MIFARESTD_VAL0) ||
4560              (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1))
4561                 ? PH_FRINFC_MIFARESTD_FLAG1
4562                 : PH_FRINFC_MIFARESTD_FLAG0);
4563       } else {
4564         NdefMap->StdMifareContainer.currentBlock++;
4565         NdefMap->StdMifareContainer.WrLength =
4566             (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
4567         /* Mifare 4k Card, After 128th Block
4568         each sector = 16 blocks in Mifare 4k */
4569         Result = phFriNfc_MifStd_H_BlkChk(NdefMap);
4570         if (Result == NFCSTATUS_SUCCESS) {
4571           NdefMap->StdMifareContainer.NdefBlocks++;
4572           Result = ((NdefMap->StdMifareContainer.AuthDone ==
4573                      PH_FRINFC_MIFARESTD_FLAG1)
4574                         ? phFriNfc_MifStd_H_WrABlock(NdefMap)
4575                         : phFriNfc_MifStd_H_AuthSector(NdefMap));
4576         }
4577       }
4578     }
4579   } else {
4580     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST);
4581   }
4582 
4583   if ((Result == NFCSTATUS_SUCCESS) &&
4584       (NdefMap->TLVStruct.SetTermTLVFlag != PH_FRINFC_MIFARESTD_FLAG1) &&
4585       (NdefMap->StdMifareContainer.remainingSize > PH_FRINFC_MIFARESTD_VAL0)) {
4586     Result = phFriNfc_MifStd_H_WrTermTLV(NdefMap);
4587   } else {
4588     if ((Result == NFCSTATUS_SUCCESS) &&
4589         (NdefMap->TLVStruct.SetTermTLVFlag == PH_FRINFC_MIFARESTD_FLAG1)) {
4590       /* Write the length to the L field in the TLV */
4591       NdefMap->StdMifareContainer.TempBlockNo =
4592           NdefMap->StdMifareContainer.currentBlock;
4593       phFriNfc_MifStd_H_SetNdefBlkAuth(NdefMap);
4594       NdefMap->StdMifareContainer.currentBlock =
4595           NdefMap->TLVStruct.NdefTLVBlock;
4596       Result = phFriNfc_MifStd_H_RdtoWrNdefLen(NdefMap);
4597     }
4598   }
4599 
4600   return Result;
4601 }
4602 
4603 /******************************************************************************
4604  * Function         phFriNfc_MifStd_H_CallDisCon
4605  *
4606  * Description      This function trigger disconnect after the authentication
4607  *                  has failed.
4608  *
4609  * Returns          This function return NFCSTATUS_PENDING in case of success
4610  *                  In case of failure returns other failure value.
4611  *
4612  ******************************************************************************/
phFriNfc_MifStd_H_CallDisCon(phFriNfc_NdefMap_t * NdefMap)4613 static NFCSTATUS phFriNfc_MifStd_H_CallDisCon(phFriNfc_NdefMap_t* NdefMap) {
4614   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4615 
4616   /* Set Ndef State */
4617   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_DISCONNECT;
4618   NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
4619   NdefMap->MapCompletionInfo.Context = NdefMap;
4620 
4621   Result = phNxNciExtns_MifareStd_Reconnect();
4622 
4623   return Result;
4624 }
4625 
4626 /******************************************************************************
4627  * Function         phFriNfc_MifStd_H_CallConnect
4628  *
4629  * Description      This function sets card state to connect after the
4630  *                  authentication has failed.
4631  *
4632  * Returns          NFCSTATUS_SUCCESS
4633  *
4634  ******************************************************************************/
phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t * NdefMap)4635 static NFCSTATUS phFriNfc_MifStd_H_CallConnect(phFriNfc_NdefMap_t* NdefMap) {
4636   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4637 
4638   /* Set Ndef State */
4639   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_CONNECT;
4640 
4641   return Result;
4642 }
4643 
4644 /******************************************************************************
4645  * Function         phFriNfc_MifStd1k_H_BlkChk
4646  *
4647  * Description      This function used to update the current block.
4648  *
4649  * Returns          void
4650  *
4651  ******************************************************************************/
phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t * NdefMap,uint8_t SectorID,uint8_t * callbreak)4652 static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t* NdefMap,
4653                                        uint8_t SectorID, uint8_t* callbreak) {
4654   /* every last block of a sector needs to be skipped */
4655   if (((NdefMap->StdMifareContainer.currentBlock + PH_FRINFC_MIFARESTD_INC_1) %
4656        PH_FRINFC_MIFARESTD_BLK4) == 0) {
4657     NdefMap->StdMifareContainer.currentBlock++;
4658   } else {
4659     if (NdefMap->StdMifareContainer.aid[SectorID] ==
4660         PH_FRINFC_MIFARESTD_NDEF_COMP) {
4661       /* Check whether the block is first block of a (next)new sector and
4662       also check if it is first block then internal length is zero
4663       or not. Because once Authentication is done for the sector again
4664       we should not authenticate it again */
4665       if ((NdefMap->StdMifareContainer.currentBlock ==
4666            (SectorID * PH_FRINFC_MIFARESTD_BLK4)) &&
4667           (NdefMap->StdMifareContainer.internalLength == 0)) {
4668         NdefMap->StdMifareContainer.AuthDone = 0;
4669       }
4670       *callbreak = 1;
4671     } else {
4672       NdefMap->StdMifareContainer.currentBlock += PH_FRINFC_MIFARESTD_BLK4;
4673     }
4674   }
4675 
4676   return;
4677 }
4678 
4679 /******************************************************************************
4680  * Function         phFrinfc_MifareClassic_GetContainerSize
4681  *
4682  * Description      This function calculate the card size.
4683  *
4684  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4685  *                  In case of failure returns other failure value.
4686  *
4687  ******************************************************************************/
4688 NFCSTATUS
phFrinfc_MifareClassic_GetContainerSize(const phFriNfc_NdefMap_t * NdefMap,uint32_t * maxSize,uint32_t * actualSize)4689 phFrinfc_MifareClassic_GetContainerSize(const phFriNfc_NdefMap_t* NdefMap,
4690                                         uint32_t* maxSize,
4691                                         uint32_t* actualSize) {
4692   NFCSTATUS result = NFCSTATUS_SUCCESS;
4693   uint16_t valid_no_of_bytes = 0;
4694   uint8_t sect_aid_index = 0;
4695   /*  Mifare std card */
4696 
4697   /*  Max size is the number of NDEF compliant blocks in the card
4698       multiplied by 16 bytes */
4699 
4700   /* Skip all the non ndef sectors */
4701   while ((sect_aid_index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK) &&
4702          (PH_FRINFC_MIFARESTD_NON_NDEF_COMP ==
4703           NdefMap->StdMifareContainer.aid[sect_aid_index])) {
4704     sect_aid_index++;
4705   }
4706 
4707   /* Parse only the contiguous NDEF sectors for the max size calculation */
4708   while ((sect_aid_index < PH_FRINFC_NDEFMAP_MIFARESTD_TOTALNO_BLK) &&
4709          (PH_FRINFC_MIFARESTD_NDEF_COMP ==
4710           NdefMap->StdMifareContainer.aid[sect_aid_index])) {
4711     if (((PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD == NdefMap->CardType) ||
4712          (PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD == NdefMap->CardType)) &&
4713         (sect_aid_index >= 32)) {
4714       /* Mifare classic card of 4k size, sector >= 32 has
4715          16 blocks per sector and in that 15 blocks are valid data blocks
4716          16 is the block number in a sector
4717          15 is the number of valid data blocks in a sector
4718        */
4719       valid_no_of_bytes += (uint16_t)(16 * 15);
4720     } else {
4721       valid_no_of_bytes += (uint16_t)(16 * 3);
4722     }
4723 
4724     sect_aid_index++;
4725     if (16 == sect_aid_index) {
4726       /* Because sector index is 16, that is "MAD 2" block
4727          For calculating size MAD block shall be ignored
4728        */
4729       sect_aid_index++;
4730     }
4731   }
4732   /* The below check is for the 3 byte length format of the NDEF TLV
4733      If the length field > 255, Max size will less by 4
4734      else Max size will less by 2 (Type and Length of the NDEF TLV
4735      has to be skipped to provide the maximum size in the card */
4736   *maxSize = (valid_no_of_bytes > 0xFF) ? (valid_no_of_bytes - 4)
4737                                         : (valid_no_of_bytes - 2);
4738 
4739   *actualSize = NdefMap->TLVStruct.BytesRemainLinTLV;
4740 
4741   return result;
4742 }
4743 
4744 /******************************************************************************
4745  * Function         phFriNfc_MifareStdMap_ConvertToReadOnly
4746  *
4747  * Description      This function converts the Mifare card to read-only.
4748  *                  It check preconditions before converting to read only.
4749  *
4750  * Returns          This function return NFCSTATUS_PENDING in case of success
4751  *                  In case of failure returns other failure value.
4752  *
4753  ******************************************************************************/
4754 NFCSTATUS
phFriNfc_MifareStdMap_ConvertToReadOnly(phFriNfc_NdefMap_t * NdefMap,const uint8_t * ScrtKeyB)4755 phFriNfc_MifareStdMap_ConvertToReadOnly(phFriNfc_NdefMap_t* NdefMap,
4756                                         const uint8_t* ScrtKeyB) {
4757   NFCSTATUS result = NFCSTATUS_SUCCESS;
4758   uint8_t totalNoSectors = 0, sectorTrailerBlockNo = 0;
4759 
4760   if (NdefMap == NULL) {
4761     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
4762   } else if (PH_NDEFMAP_CARD_STATE_INVALID == NdefMap->CardState) {
4763     result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_STATE);
4764   } else {
4765     /* card state is PH_NDEFMAP_CARD_STATE_READ_WRITE now */
4766     /* get AID  array and parse */
4767     if (PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD == NdefMap->CardType) {
4768       totalNoSectors = PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR;
4769     } else if (PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD == NdefMap->CardType) {
4770       totalNoSectors = PH_FRINFC_MIFARESTD2K_TOTAL_SECTOR;
4771     } else if (PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD == NdefMap->CardType) {
4772       totalNoSectors = PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR;
4773     }
4774 
4775     /* Store Key B in the context */
4776     if (ScrtKeyB == NULL) {
4777       memset(NdefMap->StdMifareContainer.UserScrtKeyB,
4778              PH_FRINFC_MIFARESTD_DEFAULT_KEY, PH_FRINFC_MIFARESTD_KEY_LEN);
4779     } else {
4780       memcpy(NdefMap->StdMifareContainer.UserScrtKeyB, ScrtKeyB,
4781              PH_FRINFC_MIFARESTD_KEY_LEN);
4782     }
4783 
4784     NdefMap->StdMifareContainer.TotalNoSectors = totalNoSectors;
4785     if (totalNoSectors == 0) {
4786       result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
4787     } else {
4788       NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
4789       NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
4790       NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
4791       NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0;
4792       NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
4793       NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
4794       NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0;
4795       NdefMap->StdMifareContainer.WriteAcsBitFlag = PH_FRINFC_MIFARESTD_FLAG0;
4796 
4797       /* Sector 0 is MAD sector .Start from Sector 1 */
4798       for (NdefMap->StdMifareContainer.ReadOnlySectorIndex =
4799                PH_FRINFC_MIFARESTD_FLAG1;
4800            NdefMap->StdMifareContainer.ReadOnlySectorIndex < totalNoSectors;
4801            NdefMap->StdMifareContainer.ReadOnlySectorIndex++) {
4802         /* skip MAD sectors */
4803         if (PH_FRINFC_MIFARESTD_SECTOR_NO16 ==
4804             NdefMap->StdMifareContainer.ReadOnlySectorIndex) {
4805           continue;
4806         }
4807 
4808         /* if not NDEF compliant skip  */
4809         if (PH_FRINFC_MIFARESTD_NON_NDEF_COMP ==
4810             NdefMap->StdMifareContainer
4811                 .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) {
4812           continue;
4813         }
4814 
4815         if (PH_FRINFC_MIFARESTD_NDEF_COMP ==
4816             NdefMap->StdMifareContainer
4817                 .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) {
4818           /*get the sector trailer block number */
4819           sectorTrailerBlockNo = phFriNfc_MifStd_H_GetSectorTrailerBlkNo(
4820               NdefMap->StdMifareContainer.ReadOnlySectorIndex);
4821           NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo;
4822           NdefMap->StdMifareContainer.SectorTrailerBlockNo =
4823               sectorTrailerBlockNo;
4824 
4825           /* Proceed to authenticate the sector with Key B
4826              and  modify the sector trailor bits to make it read only*/
4827           result = phFriNfc_MifStd_H_AuthSector(NdefMap);
4828 
4829           if (result == NFCSTATUS_PENDING) {
4830             break;
4831           }
4832         }
4833       } /* end for */
4834 
4835       /* There are no NDEF sectors in this card , return */
4836       if (NdefMap->StdMifareContainer.ReadOnlySectorIndex == totalNoSectors &&
4837           NFCSTATUS_PENDING != result) {
4838         result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
4839       }
4840     } /* end else */
4841   }
4842 
4843   return result;
4844 }
4845 
4846 /******************************************************************************
4847  * Function         phFriNfc_MifStd_H_GetSectorTrailerBlkNo
4848  *
4849  * Description      This function returns the block number of the sector
4850  *                  trailor for the given sector trailer Id.
4851  *
4852  * Returns          uint8_t sectorTrailerblockNumber : sector trailor
4853  *
4854  ******************************************************************************/
phFriNfc_MifStd_H_GetSectorTrailerBlkNo(uint8_t SectorID)4855 static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo(uint8_t SectorID) {
4856   uint8_t sectorTrailerblockNumber = 0;
4857 
4858   /* every last block of a sector needs to be skipped */
4859   if (SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32) {
4860     sectorTrailerblockNumber = (SectorID * PH_FRINFC_MIFARESTD_BLK4) + 3;
4861   } else {
4862     sectorTrailerblockNumber =
4863         ((PH_FRINFC_MIFARESTD_SECTOR_NO32 * PH_FRINFC_MIFARESTD_BLK4) +
4864          ((SectorID - PH_FRINFC_MIFARESTD_SECTOR_NO32) *
4865           PH_FRINFC_MIFARESTD_SECTOR_BLOCKS)) +
4866         15;
4867   }
4868 
4869   return sectorTrailerblockNumber;
4870 }
4871 
4872 /******************************************************************************
4873  * Function         phFriNfc_MifStd_H_ProSectorTrailorAcsBits
4874  *
4875  * Description      This function is called during ConvertToReadonly process to
4876  *                  Authenticate NDEF compliant Sector.
4877  *
4878  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4879  *                  In case of failure returns other failure value.
4880  *
4881  ******************************************************************************/
phFriNfc_MifStd_H_ProSectorTrailorAcsBits(phFriNfc_NdefMap_t * NdefMap)4882 static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits(
4883     phFriNfc_NdefMap_t* NdefMap) {
4884   NFCSTATUS Result = NFCSTATUS_SUCCESS;
4885 
4886   if (*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ) {
4887     if (NdefMap->StdMifareContainer.ReadAcsBitFlag ==
4888         PH_FRINFC_MIFARESTD_FLAG1) {
4889       /* check for the correct access bits */
4890       Result = phFriNfc_MifStd_H_ChkAcsBit(NdefMap);
4891       if (Result == NFCSTATUS_SUCCESS) {
4892         if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY) {
4893           /* Go to next sector */
4894           Result = phFriNfc_MifStd_H_ProWrSectorTrailor(NdefMap);
4895         } else {
4896           /* tranceive to write the data into SendRecvBuff */
4897           Result = phFriNfc_MifStd_H_WrSectorTrailorBlock(NdefMap);
4898         }
4899       }
4900     }
4901   } else {
4902     Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
4903   }
4904 
4905   return Result;
4906 }
4907 
4908 /******************************************************************************
4909  * Function         phFriNfc_MifStd_H_WrSectorTrailorBlock
4910  *
4911  * Description      This function makes current NDEF compliant Sector ReadOnly
4912  *                  modify the sector trailor bits and write it to the card.
4913  *
4914  * Returns          This function return NFCSTATUS_PENDING in case of success
4915  *                  In case of failure returns other failure value.
4916  *
4917  ******************************************************************************/
phFriNfc_MifStd_H_WrSectorTrailorBlock(phFriNfc_NdefMap_t * NdefMap)4918 static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock(
4919     phFriNfc_NdefMap_t* NdefMap) {
4920   NFCSTATUS status = NFCSTATUS_PENDING;
4921 
4922   NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
4923   NdefMap->MapCompletionInfo.Context = NdefMap;
4924   NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
4925 
4926   /* next state (update sector index) */
4927   NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WRITE_SEC;
4928 
4929   /* Buffer Check */
4930   if (NdefMap->SendRecvBuf != NULL) {
4931     NdefMap->SendRecvBuf[10] = 0x00;
4932     NdefMap->SendRecvBuf[10] = NdefMap->SendRecvBuf[9] |
4933                                PH_FRINFC_MIFARESTD_MASK_GPB_WR; /* WR bits 11*/
4934 
4935     /*The NdefMap->SendRecvBuf already has the sector trailor.
4936     modify the bits to make Read Only */
4937     NdefMap->SendRecvBuf[1] =
4938         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
4939     NdefMap->SendRecvBuf[2] =
4940         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
4941     NdefMap->SendRecvBuf[3] =
4942         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
4943     NdefMap->SendRecvBuf[4] =
4944         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
4945     NdefMap->SendRecvBuf[5] =
4946         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
4947     NdefMap->SendRecvBuf[6] =
4948         PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
4949 
4950     NdefMap->SendRecvBuf[7] =
4951         PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6; /* 0x0F */
4952     NdefMap->SendRecvBuf[8] =
4953         PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7; /* 0x07 */
4954     NdefMap->SendRecvBuf[9] =
4955         PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8; /* 0x8F */
4956 
4957     NdefMap->SendRecvBuf[11] = NdefMap->StdMifareContainer.UserScrtKeyB[0];
4958     NdefMap->SendRecvBuf[12] = NdefMap->StdMifareContainer.UserScrtKeyB[1];
4959     NdefMap->SendRecvBuf[13] = NdefMap->StdMifareContainer.UserScrtKeyB[2];
4960     NdefMap->SendRecvBuf[14] = NdefMap->StdMifareContainer.UserScrtKeyB[3];
4961     NdefMap->SendRecvBuf[15] = NdefMap->StdMifareContainer.UserScrtKeyB[4];
4962     NdefMap->SendRecvBuf[16] = NdefMap->StdMifareContainer.UserScrtKeyB[5];
4963 
4964     /* Write to Ndef Sector Block */
4965     NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] =
4966         NdefMap->StdMifareContainer.currentBlock;
4967 
4968     /* Copy Ndef Sector Block into buffer */
4969     memcpy(NdefMap->StdMifareContainer.Buffer,
4970            &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]),
4971            PH_FRINFC_MIFARESTD_BLOCK_BYTES);
4972 
4973     /* Write from here */
4974     NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE;
4975     NdefMap->Cmd.MfCmd = phHal_eMifareWrite16;
4976     *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
4977 
4978     /* Call the Overlapped HAL Transceive function */
4979     status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, NdefMap->Cmd,
4980                                       NdefMap->SendRecvBuf, NdefMap->SendLength,
4981                                       NdefMap->SendRecvLength);
4982   } else {
4983     /* Error: The control should not ideally come here.
4984        Return Error.*/
4985     status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED);
4986   }
4987 
4988   return status;
4989 }
4990 
4991 /******************************************************************************
4992  * Function         phFriNfc_MifStd_H_ProWrSectorTrailor
4993  *
4994  * Description      This function makes next NDEF compliant Sector ReadOnly.
4995  *
4996  * Returns          This function return NFCSTATUS_SUCCESS in case of success
4997  *                  In case of failure returns other failure value.
4998  *
4999  ******************************************************************************/
phFriNfc_MifStd_H_ProWrSectorTrailor(phFriNfc_NdefMap_t * NdefMap)5000 static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor(
5001     phFriNfc_NdefMap_t* NdefMap) {
5002   NFCSTATUS status = NFCSTATUS_FAILED;
5003   uint8_t sectorTrailerBlockNo = 0;
5004 
5005   /*Increment Sector Index */
5006   NdefMap->StdMifareContainer.ReadOnlySectorIndex++;
5007 
5008   /* skip if MAD2 */
5009   if (PH_FRINFC_MIFARESTD_SECTOR_NO16 ==
5010       NdefMap->StdMifareContainer.ReadOnlySectorIndex) {
5011     NdefMap->StdMifareContainer.ReadOnlySectorIndex++;
5012   }
5013 
5014   /* if current sector index exceeds total sector index then
5015      all ndef sectors are made readonly then return success
5016      If a NON def sector is encountered return success*/
5017   if (NdefMap->StdMifareContainer.ReadOnlySectorIndex >=
5018           NdefMap->StdMifareContainer.TotalNoSectors ||
5019       PH_FRINFC_MIFARESTD_NON_NDEF_COMP ==
5020           NdefMap->StdMifareContainer
5021               .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) {
5022     status = NFCSTATUS_SUCCESS;
5023   } else if (PH_FRINFC_MIFARESTD_NDEF_COMP ==
5024              NdefMap->StdMifareContainer
5025                  .aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex]) {
5026     /* Convert next NDEF sector to read only */
5027     sectorTrailerBlockNo = phFriNfc_MifStd_H_GetSectorTrailerBlkNo(
5028         NdefMap->StdMifareContainer.ReadOnlySectorIndex);
5029     NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo;
5030     NdefMap->StdMifareContainer.SectorTrailerBlockNo = sectorTrailerBlockNo;
5031 
5032     status = phFriNfc_MifStd_H_AuthSector(NdefMap);
5033   }
5034 
5035   return status;
5036 }
5037 
5038 /******************************************************************************
5039  * Function         phFriNfc_MifStd_H_ProWrSectorTrailor
5040  *
5041  * Description      This function checks mapping spec version.
5042  *
5043  * Returns          This function return NFCSTATUS_SUCCESS in case of success
5044  *                  In case of failure returns other failure value.
5045  *
5046  ******************************************************************************/
phFriNfc_MapTool_ChkSpcVer(const phFriNfc_NdefMap_t * NdefMap,uint8_t VersionIndex)5047 static NFCSTATUS phFriNfc_MapTool_ChkSpcVer(const phFriNfc_NdefMap_t* NdefMap,
5048                                             uint8_t VersionIndex) {
5049   NFCSTATUS status = NFCSTATUS_SUCCESS;
5050 
5051   uint8_t TagVerNo = NdefMap->SendRecvBuf[VersionIndex];
5052 
5053   if (TagVerNo == 0) {
5054     /* Return Status Error invalid format */
5055     status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT);
5056   } else {
5057     switch (NdefMap->CardType) {
5058       case PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD:
5059       case PH_FRINFC_NDEFMAP_MIFARE_STD_2K_CARD:
5060       case PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD: {
5061         /* calculate the major and minor version number of Mifare std version
5062          * number */
5063         status =
5064             ((((PH_NFCFRI_MFSTDMAP_NFCDEV_MAJOR_VER_NUM ==
5065                 PH_NFCFRI_MFSTDMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) &&
5066                (PH_NFCFRI_MFSTDMAP_NFCDEV_MINOR_VER_NUM ==
5067                 PH_NFCFRI_MFSTDMAP_GET_MINOR_TAG_VERNO(TagVerNo))) ||
5068               ((PH_NFCFRI_MFSTDMAP_NFCDEV_MAJOR_VER_NUM ==
5069                 PH_NFCFRI_MFSTDMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) &&
5070                (PH_NFCFRI_MFSTDMAP_NFCDEV_MINOR_VER_NUM <
5071                 PH_NFCFRI_MFSTDMAP_GET_MINOR_TAG_VERNO(TagVerNo))))
5072                  ? NFCSTATUS_SUCCESS
5073                  : PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT));
5074         break;
5075       }
5076 
5077       default: {
5078         /* calculate the major and minor version number of T3VerNo */
5079         if (((PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM ==
5080               PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) &&
5081              (PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM ==
5082               PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo))) ||
5083             ((PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM ==
5084               PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) &&
5085              (PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM <
5086               PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo)))) {
5087           status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
5088         } else {
5089           if ((PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM <
5090                PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)) ||
5091               (PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM >
5092                PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo))) {
5093             status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_FORMAT);
5094           }
5095         }
5096         break;
5097       }
5098     }
5099   }
5100 
5101   return (status);
5102 }
5103