merge with master
[adaptation/devices/nfc-plugin-nxp.git] / src / phFriNfc_DesfireMap.c
1 /*\r
2  * Copyright (C) 2010 NXP Semiconductors\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /*!\r
18 * \file  phFriNfc_Desfire.c\r
19 * \brief This component encapsulates read/write/check ndef/process functionalities,\r
20 *        for the Desfire Card.\r
21 *\r
22 * Project: NFC-FRI\r
23 *\r
24 * $Date: Tue Jul 27 08:58:22 2010 $\r
25 * $Author: ing02260 $\r
26 * $Revision: 1.11 $\r
27 * $Aliases:  $\r
28 *\r
29 */\r
30 \r
31 #ifndef PH_FRINFC_MAP_DESFIRE_DISABLED\r
32 \r
33 #include <phFriNfc_OvrHal.h>\r
34 #include <phFriNfc_DesfireMap.h>\r
35 #include <phFriNfc_MapTools.h>\r
36 \r
37 \r
38 /*! \ingroup grp_file_attributes\r
39 *  \name NDEF Mapping\r
40 *\r
41 * File: \ref phFriNfc_Desfire.c\r
42 *\r
43 */\r
44 /*@{*/\r
45 #define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.11 $"\r
46 #define PHFRINFCNDEFMAP_FILEALIASES  "$Aliases:  $"\r
47 \r
48 /*@}*/\r
49 \r
50 /***************** Start of MACROS ********************/\r
51 #ifdef DESFIRE_EV1\r
52     #define DESFIRE_EV1_P2_OFFSET_VALUE                         (0x0CU)\r
53 #endif /* #ifdef DESFIRE_EV1 */\r
54 \r
55 /***************** End of MACROS ********************/\r
56 \r
57 /*@}*/\r
58 \r
59 /*!\r
60  * \name Desfire Mapping - Helper Functions\r
61  *\r
62  */\r
63 /*@{*/\r
64 \r
65 /*!\r
66  * \brief \copydoc page_ovr Helper function for Desfire. This function specifies\r
67  *  the card is a Desfire card or not.\r
68  */\r
69 static NFCSTATUS phFriNfc_Desfire_SelectSmartTag(  phFriNfc_NdefMap_t  *NdefMap);\r
70 \r
71 /*!\r
72  * \brief \copydoc page_ovr Helper function for Desfire. This function is used\r
73  *  to selct a file in the card.\r
74  */\r
75 static NFCSTATUS phFriNfc_Desfire_SelectFile ( phFriNfc_NdefMap_t  *NdefMap);\r
76 \r
77 /*!\r
78  * \brief \copydoc page_ovr Helper function for Desfire. This function is to\r
79  *  read the card.\r
80  */\r
81 static NFCSTATUS  phFriNfc_Desfire_ReadBinary( phFriNfc_NdefMap_t  *NdefMap);\r
82 \r
83 /*!\r
84  * \brief \copydoc page_ovr Helper function for Desfire. This function is to\r
85  *  write to the card.\r
86  */\r
87 static NFCSTATUS  phFriNfc_Desfire_UpdateBinary(   phFriNfc_NdefMap_t  *NdefMap);\r
88 \r
89 /*!\r
90  * \brief \copydoc page_ovr Helper function for Desfire. This function is to\r
91  *  update the capability container of the card.\r
92  */\r
93 static NFCSTATUS  phFriNfc_Desfire_Update_SmartTagCapContainer( phFriNfc_NdefMap_t *NdefMap);\r
94 \r
95 \r
96 /* Completion Helper*/\r
97 static void phFriNfc_Desfire_HCrHandler(    phFriNfc_NdefMap_t  *NdefMap,\r
98                                         NFCSTATUS           Status);\r
99 \r
100 /* Calculates the Le Bytes for Read Operation*/\r
101 static uint32_t phFriNfc_Desfire_HGetLeBytes(   phFriNfc_NdefMap_t  *NdefMap);\r
102 \r
103 static NFCSTATUS phFriNfc_Desf_HChkAndParseTLV( phFriNfc_NdefMap_t  *NdefMap,\r
104                                                uint8_t             BuffIndex);\r
105 \r
106 static NFCSTATUS phFriNfc_Desfire_HSetGet_NLEN( phFriNfc_NdefMap_t  *NdefMap);\r
107 \r
108 static void phFriNfc_Desfire_HProcReadData( phFriNfc_NdefMap_t  *NdefMap);\r
109 \r
110 static void phFriNfc_Desfire_HChkNDEFFileAccessRights(  phFriNfc_NdefMap_t  *NdefMap);\r
111 static NFCSTATUS phFriNfc_Desfire_HSendTransCmd(phFriNfc_NdefMap_t *NdefMap,uint8_t SendRecvLen);\r
112 \r
113 #ifdef PH_HAL4_ENABLE\r
114 \r
115 #else\r
116 \r
117 /* Following are the API's are used to get the version of the desfire card*/\r
118 static NFCSTATUS phFriNfc_Desfire_HGetHWVersion(phFriNfc_NdefMap_t    *NdefMap);\r
119 static NFCSTATUS phFriNfc_Desfire_HGetSWVersion(phFriNfc_NdefMap_t    *NdefMap);\r
120 static NFCSTATUS phFriNfc_Desfire_HGetUIDDetails(phFriNfc_NdefMap_t   *NdefMap);\r
121 static NFCSTATUS phFriNfc_Desfire_HUpdateVersionDetails(const phFriNfc_NdefMap_t *NdefMap);\r
122 \r
123 #endif /* #ifdef PH_HAL4_ENABLE */\r
124 \r
125 #ifdef PH_HAL4_ENABLE\r
126 \r
127 #else\r
128 \r
129 static NFCSTATUS phFriNfc_Desfire_HGetHWVersion(phFriNfc_NdefMap_t    *NdefMap)\r
130 {\r
131 \r
132     NFCSTATUS status = NFCSTATUS_PENDING;\r
133 \r
134     /*set the state*/\r
135     NdefMap->State = PH_FRINFC_DESF_STATE_GET_HW_VERSION;\r
136 \r
137     /* Helper routine to wrap the native desfire cmds*/\r
138     PH_FRINFC_DESF_ISO_NATIVE_WRAPPER();\r
139     status =  phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);\r
140 \r
141     return (status);\r
142 }\r
143 \r
144 static NFCSTATUS phFriNfc_Desfire_HGetSWVersion(phFriNfc_NdefMap_t *NdefMap)\r
145 {\r
146 \r
147     NFCSTATUS status = NFCSTATUS_PENDING;\r
148     if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == PH_FRINFC_DESF_NATIVE_GETVER_RESP) )\r
149     {\r
150         /*set the state*/\r
151         NdefMap->State = PH_FRINFC_DESF_STATE_GET_SW_VERSION;\r
152 \r
153         /* Helper routine to wrap the native desfire commands*/\r
154         PH_FRINFC_DESF_ISO_NATIVE_WRAPPER();\r
155         status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);\r
156     }\r
157 #ifdef PH_HAL4_ENABLE\r
158     else\r
159     {\r
160         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
161                        NFCSTATUS_INVALID_PARAMETER);\r
162     }\r
163 #endif /* #ifdef PH_HAL4_ENABLE */\r
164     return status;\r
165 }\r
166 \r
167 static NFCSTATUS phFriNfc_Desfire_HGetUIDDetails(phFriNfc_NdefMap_t *NdefMap)\r
168 {\r
169 \r
170     NFCSTATUS status = NFCSTATUS_PENDING;\r
171 \r
172     if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == PH_FRINFC_DESF_NATIVE_GETVER_RESP) )\r
173     {\r
174         /*set the state*/\r
175         NdefMap->State = PH_FRINFC_DESF_STATE_GET_UID;\r
176 \r
177         /* Helper routine to wrap the native desfire commands*/\r
178         PH_FRINFC_DESF_ISO_NATIVE_WRAPPER();\r
179 \r
180         status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);\r
181     }\r
182 #ifdef PH_HAL4_ENABLE\r
183     else\r
184     {\r
185         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
186                        NFCSTATUS_INVALID_PARAMETER);\r
187     }\r
188 #endif /* #ifdef PH_HAL4_ENABLE */\r
189     return status;\r
190 \r
191 }\r
192 \r
193 static NFCSTATUS phFriNfc_Desfire_HUpdateVersionDetails(const phFriNfc_NdefMap_t *NdefMap)\r
194 {\r
195     NFCSTATUS status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
196                        NFCSTATUS_INVALID_PARAMETER);\r
197 \r
198     if( ( NdefMap->SendRecvBuf[*(NdefMap->SendRecvLength)- 1] == 0xAF) )\r
199     {\r
200 \r
201         status = NFCSTATUS_SUCCESS;\r
202 \r
203         /* We do not need the following details presently.Retained for future use*/\r
204         #if 0\r
205         NdefMap->AddInfo.Type4Info.MajorVersion = NdefSmtCrdFmt->SendRecvBuf[3];\r
206         NdefMap->AddInfo.Type4Info.MinorVersion = NdefSmtCrdFmt->SendRecvBuf[4];\r
207         if ( ( NdefMap->AddInfo.Type4Info.MajorVersion == 0x00 )&&\r
208             ( NdefMap->AddInfo.Type4Info.MinorVersion == 0x06 ))\r
209         {\r
210             /* card size of DESFire4 type */\r
211             //NdefMap->AddInfo.Type4Info.CardSize = 0xEDE;\r
212 \r
213         }\r
214         else\r
215         {\r
216             // need to handle the Desfire8 type cards\r
217             // need to use get free memory\r
218         }\r
219         #endif\r
220     }\r
221     return status;\r
222 }\r
223 \r
224 \r
225 #endif /* #ifdef PH_HAL4_ENABLE */\r
226 \r
227 /*!\r
228 * \brief Initiates Reading of NDEF information from the Desfire Card.\r
229 *\r
230 * The function initiates the reading of NDEF information from a Remote Device.\r
231 * It performs a reset of the state and starts the action (state machine).\r
232 * A periodic call of the \ref phFriNfcNdefMap_Process has to be\r
233 * done once the action has been triggered.\r
234 */\r
235 \r
236 NFCSTATUS phFriNfc_Desfire_RdNdef(  phFriNfc_NdefMap_t  *NdefMap,\r
237                                   uint8_t             *PacketData,\r
238                                   uint32_t            *PacketDataLength,\r
239                                   uint8_t             Offset)\r
240 {\r
241     NFCSTATUS   status = NFCSTATUS_PENDING;\r
242 \r
243     NdefMap->ApduBufferSize = *PacketDataLength;\r
244     /*  To return actual number of bytes read to the caller */\r
245     NdefMap->NumOfBytesRead = PacketDataLength ;\r
246     *NdefMap->NumOfBytesRead = 0;\r
247 \r
248     /* store the offset in to map context*/\r
249     NdefMap->Offset = Offset;\r
250 \r
251     if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&\r
252         (*NdefMap->DataCount == NdefMap->DesfireCapContainer.NdefDataLen))\r
253     {\r
254         /*  No space on card for Reading : we have already\r
255         reached the end of file !\r
256         Offset is set to Continue Operation */\r
257         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
258             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);\r
259     }\r
260     else\r
261     {\r
262 \r
263         /* reset the inter flag*/\r
264         NdefMap->DesfireCapContainer.IsNlenPresentFlag = 0;\r
265         NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 0;\r
266 \r
267         /*  Set the desfire read operation  */\r
268         NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_READ_OP;\r
269 \r
270         /*  Save the packet data buffer address in the context  */\r
271         NdefMap->ApduBuffer = PacketData;\r
272 \r
273         NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;\r
274 \r
275 #ifdef DESFIRE_EV1\r
276         /* Select smart tag operation. First step for the read operation. */\r
277         if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)\r
278         {\r
279             status = phFriNfc_Desfire_SelectFile(NdefMap);\r
280         }\r
281         else\r
282 #endif /* #ifdef DESFIRE_EV1 */\r
283         {\r
284             status = phFriNfc_Desfire_SelectSmartTag(NdefMap);\r
285         }\r
286     }\r
287 \r
288     return status;\r
289 }\r
290 \r
291 /*!\r
292 * \brief Initiates Writing of NDEF information to the Remote Device.\r
293 *\r
294 * The function initiates the writing of NDEF information to a Remote Device.\r
295 * It performs a reset of the state and starts the action (state machine).\r
296 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action\r
297 * has been triggered.\r
298 */\r
299 \r
300 NFCSTATUS phFriNfc_Desfire_WrNdef(  phFriNfc_NdefMap_t  *NdefMap,\r
301                                   uint8_t             *PacketData,\r
302                                   uint32_t            *PacketDataLength,\r
303                                   uint8_t             Offset)\r
304 {\r
305     NFCSTATUS   status = NFCSTATUS_PENDING;\r
306 \r
307     NdefMap->ApduBufferSize = *PacketDataLength;\r
308     NdefMap->WrNdefPacketLength = PacketDataLength;\r
309 \r
310     /*  Now, let's initialize     *NdefMap->WrNdefPacketLength    to zero.\r
311     In case we get an error, this will be correctly set to "no byte written".\r
312     In case there is no error, this will be updated later on, in the _process function.\r
313     */\r
314     *NdefMap->WrNdefPacketLength =   0;\r
315 \r
316     /*  we have write access. */\r
317     if( *NdefMap->DataCount >= PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE)\r
318     {\r
319         /*  No space on card for writing : we have already\r
320         reached the end of file !\r
321         Offset is set to Continue Operation */\r
322         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
323             NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);\r
324     }\r
325     else\r
326     {\r
327         /*  Adapt the nb of bytes that the user would like to write */\r
328 \r
329         /*set the defire write operation*/\r
330         NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_WRITE_OP;\r
331         NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;\r
332         NdefMap->Offset = Offset;\r
333 \r
334         /*Store the packet data buffer*/\r
335         NdefMap->ApduBuffer = PacketData;\r
336 \r
337 #ifdef DESFIRE_EV1\r
338         if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)\r
339         {\r
340             status = phFriNfc_Desfire_SelectFile(NdefMap);\r
341         }\r
342         else\r
343 #endif /* #ifdef DESFIRE_EV1 */\r
344         {\r
345             /* Select smart tag operation. First step for the write operation. */\r
346             status = phFriNfc_Desfire_SelectSmartTag (NdefMap);\r
347         }\r
348     }\r
349     return status;\r
350 }\r
351 \r
352 /*!\r
353 * \brief Check whether a particular Remote Device is NDEF compliant.\r
354 *\r
355 * The function checks whether the peer device is NDEF compliant.\r
356 *\r
357 */\r
358 \r
359 NFCSTATUS phFriNfc_Desfire_ChkNdef( phFriNfc_NdefMap_t     *NdefMap)\r
360 {\r
361     NFCSTATUS    status = NFCSTATUS_PENDING;\r
362 \r
363 #ifdef PH_HAL4_ENABLE\r
364 \r
365 #ifdef DESFIRE_EV1\r
366     /* Reset card type */\r
367     NdefMap->CardType = 0;\r
368 #endif /* #ifdef DESFIRE_EV1 */\r
369         /*Set the desfire operation flag*/\r
370         NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP;\r
371 \r
372     /*Call Select Smart tag Functinality*/\r
373     status = phFriNfc_Desfire_SelectSmartTag(NdefMap);\r
374 #else\r
375         /* Need to get the version details of the card, to\r
376            identify the the desfire4card type */\r
377         status = phFriNfc_Desfire_HGetHWVersion(NdefMap);\r
378 #endif\r
379 \r
380     return (status);\r
381 }\r
382 \r
383 static NFCSTATUS phFriNfc_Desf_HChkAndParseTLV(phFriNfc_NdefMap_t     *NdefMap, uint8_t BuffIndex)\r
384 {\r
385     NFCSTATUS    status = NFCSTATUS_SUCCESS;\r
386 \r
387     if((NdefMap->SendRecvBuf[BuffIndex] <= 0x03) ||\r
388         (NdefMap->SendRecvBuf[BuffIndex] >= 0x06) )\r
389     {\r
390         status =  PHNFCSTVAL(   CID_FRI_NFC_NDEF_MAP,\r
391             NFCSTATUS_NO_NDEF_SUPPORT);\r
392     }\r
393     else\r
394     {\r
395         /* check for the type of TLV*/\r
396         NdefMap->TLVFoundFlag =\r
397             ((NdefMap->SendRecvBuf[BuffIndex] == 0x04)?\r
398             PH_FRINFC_NDEFMAP_DESF_NDEF_CNTRL_TLV:\r
399             PH_FRINFC_NDEFMAP_DESF_PROP_CNTRL_TLV);\r
400 \r
401         status =  PHNFCSTVAL(   CID_FRI_NFC_NDEF_MAP,\r
402             NFCSTATUS_SUCCESS);\r
403     }\r
404     return status;\r
405 }\r
406 \r
407 static NFCSTATUS    phFriNfc_Desfire_HSetGet_NLEN(phFriNfc_NdefMap_t *NdefMap)\r
408 {\r
409 \r
410     NFCSTATUS    status = NFCSTATUS_PENDING;\r
411 \r
412     if ( PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP == NdefMap->DespOpFlag)\r
413     {\r
414 \r
415         /*Call Select Smart tag Functinality*/\r
416         status = phFriNfc_Desfire_SelectSmartTag(NdefMap);\r
417     }\r
418     else\r
419     {\r
420 \r
421         /* Get the Data Count and set it to NoOfBytesWritten\r
422         Update the NLEN using Transceive cmd*/\r
423 \r
424         /*Form the packet for the update binary command*/\r
425         NdefMap->SendRecvBuf[0] = 0x00;\r
426         NdefMap->SendRecvBuf[1] = 0xD6;\r
427 \r
428         /* As we need to set the NLEN @ first 2 bytes of NDEF File*/\r
429         /* set the p1/p2 offsets */\r
430         NdefMap->SendRecvBuf[2] = 0x00; /* p1 */\r
431         NdefMap->SendRecvBuf[3] = 0x00; /* p2 */\r
432 \r
433         /* Set only two bytes as NLEN*/\r
434         NdefMap->SendRecvBuf[4] = 0x02;\r
435 \r
436         /* update NLEN */\r
437         NdefMap->SendRecvBuf[5] = (uint8_t)(*NdefMap->DataCount >> PH_FRINFC_NDEFMAP_DESF_SHL8);\r
438         NdefMap->SendRecvBuf[6] = (uint8_t)(*NdefMap->DataCount & (0x00ff));\r
439 \r
440         NdefMap->SendLength = 0x07 ;\r
441 \r
442         /* Change the state to Write */\r
443         NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_END;\r
444 \r
445         status =  phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);\r
446     }\r
447     return status;\r
448 }\r
449 \r
450 static void phFriNfc_Desfire_HProcReadData(phFriNfc_NdefMap_t *NdefMap)\r
451 {\r
452     NFCSTATUS   Result = NFCSTATUS_PENDING;\r
453     uint32_t    BufferSize = 0;\r
454     uint8_t     BufIndex=0;\r
455     uint16_t    SizeToCpy=0;\r
456 \r
457     /* Need to check the Actual Ndef Length before copying the data to buffer*/\r
458     /* Only NDEF data should be copied , rest all the data should be ignored*/\r
459     /* Ex : Ndef File Size 50 bytes , but only 5 bytes(NLEN) are relavent to NDEF data*/\r
460     /* component should only copy 5 bytes to user buffer*/\r
461 \r
462     /*  Data has been read successfully in the TRX buffer. */\r
463     /*  copy it to the user buffer. */\r
464 \r
465     /* while copying need check the offset if its begin need to skip the first 2 bytes\r
466     while copying. If its current no need to skip the first 2 bytes*/\r
467 \r
468     if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )\r
469     {\r
470         BufIndex = (uint8_t)(( NdefMap->DesfireCapContainer.IsNlenPresentFlag == 1 )?\r
471             0:PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES);\r
472 \r
473         /* Update the latest NLEN to context*/\r
474         NdefMap->DesfireCapContainer.NdefDataLen = ((*NdefMap->DataCount == 0)?\r
475             ( (((uint16_t)NdefMap->SendRecvBuf[\r
476                 PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_FIRST_INDEX])<<8)+ \\r
477                     NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_SECOND_INDEX]):\r
478                 NdefMap->DesfireCapContainer.NdefDataLen);\r
479 \r
480         /* Decide how many byes to be copied into user buffer: depending upon the actual NDEF\r
481            size need to copy the content*/\r
482         if ( (NdefMap->DesfireCapContainer.NdefDataLen) <= (*NdefMap->SendRecvLength - \\r
483             (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET + BufIndex)))\r
484         {\r
485             SizeToCpy = NdefMap->DesfireCapContainer.NdefDataLen;\r
486 \r
487         }\r
488         else\r
489         {\r
490             SizeToCpy = ((*NdefMap->SendRecvLength)-(PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET+BufIndex));\r
491         }\r
492 \r
493         /* Check do we have Ndef Data len > 0 present in the card.If No Ndef Data\r
494         present in the card , set the card state to Initalised and set an Error*/\r
495         if ( NdefMap->DesfireCapContainer.NdefDataLen == 0x00 )\r
496         {\r
497             NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;\r
498             Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);\r
499 #ifdef PH_HAL4_ENABLE\r
500 #else\r
501             NdefMap->PrevOperation = 0;\r
502 #endif /* #ifdef PH_HAL4_ENABLE */\r
503             phFriNfc_Desfire_HCrHandler(NdefMap,Result);\r
504         }\r
505         else\r
506         {\r
507             (void)memcpy( (&(NdefMap->ApduBuffer[\r
508             NdefMap->ApduBuffIndex])),\r
509             (&(NdefMap->SendRecvBuf[BufIndex])),\r
510             (SizeToCpy));\r
511 \r
512             /*  Increment the Number of Bytes Read, which will be returned to the caller. */\r
513             *NdefMap->NumOfBytesRead = (uint32_t)(*NdefMap->NumOfBytesRead + SizeToCpy);\r
514 \r
515             /*update the data count*/\r
516             *NdefMap->DataCount = (uint16_t)(*NdefMap->DataCount + SizeToCpy);\r
517 \r
518             /*update the buffer index of the apdu buffer*/\r
519             NdefMap->ApduBuffIndex = (uint16_t)(NdefMap->ApduBuffIndex + SizeToCpy);\r
520         }\r
521     }\r
522     else\r
523     {\r
524             (void)memcpy( (&(NdefMap->ApduBuffer[\r
525             NdefMap->ApduBuffIndex])),\r
526                 (NdefMap->SendRecvBuf),/* to avoid the length of the NDEF File*/\r
527                 (*(NdefMap->SendRecvLength)-(PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET)));\r
528 \r
529             /*  Increment the Number of Bytes Read, which will be returned to the caller. */\r
530             *NdefMap->NumOfBytesRead +=( *NdefMap->SendRecvLength - \\r
531                 (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET));\r
532 \r
533             /*update the data count*/\r
534             *NdefMap->DataCount += \\r
535                 (*NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET));\r
536 \r
537             /*update the buffer index of the apdu buffer*/\r
538             NdefMap->ApduBuffIndex += \\r
539                 *NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET );\r
540     }\r
541 \r
542     /*  check whether we still have to read some more data. */\r
543     if (*NdefMap->DataCount < NdefMap->DesfireCapContainer.NdefDataLen )\r
544     {\r
545         /*  we have some bytes to read. */\r
546 \r
547         /*  Now check, we still have bytes left in the user buffer. */\r
548         BufferSize = NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex;\r
549         if(BufferSize != 0)\r
550         {\r
551             /* Before read need to set the flag to intimate the module to\r
552             dont skip the first 2 bytes as we are in mode reading next\r
553             continues available bytes, which will not contain the NLEN\r
554             information in the begining part that is 2 bytes*/\r
555             NdefMap->DesfireCapContainer.IsNlenPresentFlag = 1;\r
556             /* Read Operation is not complete */\r
557             Result = phFriNfc_Desfire_ReadBinary( NdefMap );\r
558             /* handle the error in Transc function*/\r
559             if  ( (Result & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER) )\r
560             {\r
561                 /* call respective CR */\r
562                 phFriNfc_Desfire_HCrHandler(NdefMap,Result);\r
563             }\r
564         }\r
565         else\r
566         {\r
567             /*  There are some more bytes to read, but\r
568             no space in the user buffer */\r
569             Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);\r
570             NdefMap->ApduBuffIndex =0;\r
571             /* call respective CR */\r
572             phFriNfc_Desfire_HCrHandler(NdefMap,Result);\r
573         }\r
574     }\r
575     else\r
576     {\r
577         if (*NdefMap->DataCount == NdefMap->DesfireCapContainer.NdefDataLen )\r
578         {\r
579             /*  we have read all the bytes available in the card. */\r
580             Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);\r
581 #ifdef PH_HAL4_ENABLE\r
582             /* Do nothing */\r
583 #else\r
584             NdefMap->PrevOperation = 0;\r
585 #endif /* #ifndef PH_HAL4_ENABLE */\r
586         }\r
587         else\r
588         {\r
589             /*  The control should not come here. */\r
590             /*  we have actually read more byte than available in the card. */\r
591             NdefMap->PrevOperation = 0;\r
592 #ifndef PH_HAL4_ENABLE\r
593             Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
594                 NFCSTATUS_CMD_ABORTED);\r
595 #else\r
596             Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
597                 NFCSTATUS_FAILED);\r
598 #endif\r
599         }\r
600 \r
601 \r
602         NdefMap->ApduBuffIndex = 0;\r
603 \r
604         /* call respective CR */\r
605         phFriNfc_Desfire_HCrHandler(NdefMap,Result);\r
606     }\r
607 }\r
608 \r
609 \r
610 \r
611 /*!\r
612 * \brief Completion Routine, Processing function, needed to avoid long blocking.\r
613 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion\r
614 *       Routine in order to be able to notify the component that an I/O has finished and data are\r
615 *       ready to be processed.\r
616 *\r
617 */\r
618 \r
619 void phFriNfc_Desfire_Process(void       *Context,\r
620                               NFCSTATUS   Status)\r
621 {\r
622     /*Set the context to Map Module*/\r
623     phFriNfc_NdefMap_t  *NdefMap = (phFriNfc_NdefMap_t *)Context;\r
624     uint8_t             ErrFlag = 0;\r
625     uint16_t            NLength = 0,\r
626                         SendRecLen=0;\r
627     uint32_t            BytesRead = 0;\r
628 \r
629 \r
630     /*  Sujatha P: Fix for 0000255/0000257:[gk] MAP:Handling HAL Errors */\r
631     if ( Status == NFCSTATUS_SUCCESS )\r
632     {\r
633         switch (NdefMap->State)\r
634         {\r
635 \r
636 #ifdef PH_HAL4_ENABLE\r
637 #else\r
638 \r
639             case PH_FRINFC_DESF_STATE_GET_HW_VERSION :\r
640 \r
641                 /* Check and store the h/w and s/w specific details.\r
642                 Ex: Major/Minor version, memory storage info. */\r
643                 Status = phFriNfc_Desfire_HGetSWVersion(NdefMap);\r
644 \r
645                 /* handle the error in Transc function*/\r
646                 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))\r
647                 {\r
648                     /* call respective CR */\r
649                     phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
650                 }\r
651 \r
652                 break;\r
653 \r
654             case PH_FRINFC_DESF_STATE_GET_SW_VERSION :\r
655 \r
656                 /* Check and store the h/w and s/w specific details.\r
657                 Ex: Major/Minor version, memory storage info. */\r
658 \r
659                 Status = phFriNfc_Desfire_HUpdateVersionDetails(NdefMap);\r
660                 if ( Status == NFCSTATUS_SUCCESS )\r
661                 {\r
662                     Status = phFriNfc_Desfire_HGetUIDDetails(NdefMap);\r
663                     /* handle the error in Transc function*/\r
664                     if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))\r
665                     {\r
666                         /* call respective CR */\r
667                         phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
668                     }\r
669                 }\r
670 \r
671                 break;\r
672 \r
673             case PH_FRINFC_DESF_STATE_GET_UID :\r
674 \r
675                 /*Set the desfire operation flag*/\r
676                 NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP;\r
677 \r
678                 /*Call Select Smart tag Functinality*/\r
679                 Status = phFriNfc_Desfire_SelectSmartTag(NdefMap);\r
680 \r
681                 break;\r
682 #endif /* #ifdef PH_HAL4_ENABLE */\r
683 \r
684 #ifdef DESFIRE_EV1\r
685             case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG_EV1:\r
686             {\r
687                 if(( NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 2)] ==\r
688                     PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
689                     (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 1)] ==\r
690                     PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))\r
691                 {\r
692                     NdefMap->CardType = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;\r
693 \r
694                     Status = phFriNfc_Desfire_SelectFile(NdefMap);\r
695 \r
696                     /* handle the error in Transc function*/\r
697                     if ((Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))\r
698                     {\r
699                         /* call respective CR */\r
700                         phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
701                     }\r
702                 }\r
703                 else\r
704                 {\r
705                     NdefMap->CardType = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;\r
706                     /* The card is not the new desfire, so send select smart tag command\r
707                     of the old desfire */\r
708                     Status = phFriNfc_Desfire_SelectSmartTag(NdefMap);\r
709 \r
710 \r
711                 }\r
712                 break;\r
713             }\r
714 #endif /* #ifdef DESFIRE_EV1 */\r
715 \r
716         case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG:\r
717 #ifdef DESFIRE_EV1\r
718             if(( NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 2)] ==\r
719                     PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
720                     (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength) - 1)] ==\r
721                     PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))\r
722 #else\r
723             if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] ==\r
724                 PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
725                 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] ==\r
726                 PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))\r
727 #endif /* #ifdef DESFIRE_EV1 */\r
728             {\r
729                 Status = phFriNfc_Desfire_SelectFile(NdefMap);\r
730 \r
731                 /* handle the error in Transc function*/\r
732                 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))\r
733                 {\r
734                     /* call respective CR */\r
735                     phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
736                 }\r
737             }\r
738             else\r
739             {\r
740                 /*Error " Smart Tag Functionality Not Supported"*/\r
741                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\\r
742                     NFCSTATUS_SMART_TAG_FUNC_NOT_SUPPORTED);\r
743 #ifdef DESFIRE_EV1\r
744                 NdefMap->CardType = 0;\r
745 #endif /* #ifdef DESFIRE_EV1 */\r
746 \r
747                 /* call respective CR */\r
748                 phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
749 \r
750             }\r
751 \r
752             break;\r
753 \r
754         case PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_FILE :\r
755 \r
756             if(( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
757                 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))\r
758             {\r
759                 /*check for the which operation */\r
760                 if( (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_READ_OP) ||\r
761                     (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP) ||\r
762                     (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP ))\r
763                 {\r
764                     /* call for read binary operation*/\r
765                     Status = phFriNfc_Desfire_ReadBinary(NdefMap);\r
766 \r
767                     /* handle the error in Transc function*/\r
768                     if  ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER) )\r
769                     {\r
770                         /* call respective CR */\r
771                         phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
772                     }\r
773                 }\r
774                 /*its a write Operation*/\r
775                 else if(NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_WRITE_OP )\r
776                 {\r
777                     Status = phFriNfc_Desfire_UpdateBinary (NdefMap);\r
778                     /* handle the error in Transc function*/\r
779                     if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))\r
780                     {\r
781                         /* call respective CR */\r
782                         phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
783                     }\r
784                 }\r
785                 else\r
786                 {\r
787                     /* unknown/invalid desfire operations*/\r
788                     Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\\r
789                         NFCSTATUS_INVALID_REMOTE_DEVICE);\r
790 \r
791                     /* call respective CR */\r
792                     phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
793                 }\r
794             }\r
795             else\r
796             {\r
797                 /*return Error " Select File Operation Failed"*/\r
798                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\\r
799                     NFCSTATUS_INVALID_REMOTE_DEVICE);\r
800 \r
801                 /* call respective CR */\r
802                 phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
803             }\r
804             break;\r
805 \r
806         case PH_FRINFC_NDEFMAP_DESF_STATE_READ_CAP_CONT:\r
807             if( (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength)-2)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
808                 (NdefMap->SendRecvBuf[(*(NdefMap->SendRecvLength)-1)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))\r
809             {\r
810                 /*  Read successful. */\r
811                 /*Update the smart tag capability container*/\r
812                 Status = phFriNfc_Desfire_Update_SmartTagCapContainer(NdefMap);\r
813 \r
814                 if ( Status == NFCSTATUS_SUCCESS)\r
815                 {\r
816                     NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP;\r
817 #ifdef DESFIRE_EV1\r
818                     if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)\r
819                     {\r
820                         Status = phFriNfc_Desfire_SelectFile(NdefMap);\r
821                     }\r
822                     else\r
823 #endif /* #ifdef DESFIRE_EV1 */\r
824                     {\r
825                         Status = phFriNfc_Desfire_HSetGet_NLEN(NdefMap);\r
826                     }\r
827                     /* handle the error in Transc function*/\r
828                     if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))\r
829                     {\r
830                         /* call respective CR */\r
831                         phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
832                     }\r
833                 }\r
834                 else\r
835                 {\r
836                     /* call respective CR */\r
837                     phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
838 \r
839                 }\r
840 \r
841             }\r
842             else\r
843             {\r
844                 /*return Error " Capability Container Not Found"*/\r
845                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
846                     NFCSTATUS_INVALID_REMOTE_DEVICE);\r
847                 /* call respective CR */\r
848                 phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
849             }\r
850             break;\r
851 \r
852         case  PH_FRINFC_NDEFMAP_DESF_STATE_READ_BIN:\r
853 \r
854             /* Check how many bytes have been read/returned from the card*/\r
855             BytesRead = phFriNfc_Desfire_HGetLeBytes(NdefMap);\r
856 \r
857             /* set the send recev len*/\r
858             SendRecLen = *NdefMap->SendRecvLength - (PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET );\r
859             if ( (NdefMap->DesfireCapContainer.SkipNlenBytesFlag  == 1) && ((BytesRead == 1) || (BytesRead == 2 )))\r
860             {\r
861                 BytesRead += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES; /* to take care of first 2 len bytes*/\r
862 \r
863             }\r
864             else\r
865             {\r
866                 /* Nothing to process*/\r
867                 ;\r
868             }\r
869             /* Read More Number Of Bytes than Expected*/\r
870             if ( ( BytesRead == SendRecLen ) &&\r
871                 ((NdefMap->SendRecvBuf[(*NdefMap->SendRecvLength-2)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
872                 (NdefMap->SendRecvBuf[(*NdefMap->SendRecvLength-1)] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE)))\r
873 \r
874             {\r
875                 /* this is to check the card state in first Read Operation*/\r
876                 if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP )\r
877                 {\r
878                     /* check the actual length of the ndef data : NLEN*/\r
879                     NLength = ( (((uint16_t)NdefMap->SendRecvBuf[0])<<PH_FRINFC_NDEFMAP_DESF_SHL8)+ \\r
880                         NdefMap->SendRecvBuf[1]);\r
881                     if (( NLength > PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE )||\r
882                         ( NLength == 0xFFFF))\r
883                     {\r
884                         ErrFlag = 1;\r
885                         Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
886                             NFCSTATUS_NO_NDEF_SUPPORT);\r
887                     }\r
888                     else\r
889                     {\r
890                         /* Store the NLEN into the context  */\r
891                         NdefMap->DesfireCapContainer.NdefDataLen = NLength;\r
892 \r
893                         Status = phFriNfc_MapTool_SetCardState( NdefMap,\r
894                             NLength);\r
895                         if ( Status == NFCSTATUS_SUCCESS )\r
896                         {\r
897                             /*Set the card type to Desfire*/\r
898 #ifndef DESFIRE_EV1\r
899                             NdefMap->CardType = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;\r
900 #endif /* #ifdef DESFIRE_EV1 */\r
901                             /*Set the state to specify True for Ndef Compliant*/\r
902                             NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_CHK_NDEF;\r
903 \r
904                             /*set the data count back to zero*/;\r
905                             *NdefMap->DataCount = 0;\r
906                             /*set the apdu buffer index to zero*/\r
907                             NdefMap->ApduBuffIndex = 0;\r
908                             /* Set the Operationg flag to Complete check NDEF Operation*/\r
909                             NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP;\r
910 \r
911                         }\r
912                          /* call respective CR */\r
913                         phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
914                     }/* End ofNdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP*/\r
915                 }\r
916                 else if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_READ_OP )\r
917                 {\r
918                     phFriNfc_Desfire_HProcReadData(NdefMap);\r
919                 }\r
920                 else\r
921                 {\r
922                     /* Invalid Desfire Operation  */\r
923                     Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
924                         NFCSTATUS_INVALID_REMOTE_DEVICE);\r
925                     phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
926                 }\r
927 \r
928             }\r
929             else\r
930             {\r
931                 /*handle the  Error case*/\r
932                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\\r
933                     NFCSTATUS_READ_FAILED);\r
934                 ErrFlag =1;\r
935             }\r
936             if( ErrFlag == 1)\r
937             {\r
938                 *NdefMap->DataCount = 0;\r
939 \r
940                 /*set the buffer index back to zero*/\r
941                 NdefMap->ApduBuffIndex = 0;\r
942 \r
943                 /* call respective CR */\r
944                 phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
945             }\r
946 \r
947             break;\r
948 \r
949         case  PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_BEGIN:\r
950             if( (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
951                 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))\r
952             {\r
953                 /*  Write operation was successful. */\r
954                 /*  NdefMap->NumOfBytesWritten have been written on to the card.\r
955                 Update the DataCount and the ApduBufferIndex */\r
956                 *NdefMap->DataCount = (uint16_t)(*NdefMap->DataCount +\r
957                                                 NdefMap->NumOfBytesWritten);\r
958                 NdefMap->ApduBuffIndex = (uint16_t)(NdefMap->ApduBuffIndex +\r
959                                                 NdefMap->NumOfBytesWritten);\r
960 \r
961                 /*  Update the user-provided buffer size to write */\r
962                 *NdefMap->WrNdefPacketLength += NdefMap->NumOfBytesWritten;\r
963 \r
964                 /*  Call Upadte Binary function to check if some more bytes are to be written. */\r
965                 Status = phFriNfc_Desfire_UpdateBinary( NdefMap );\r
966             }\r
967             else\r
968             {\r
969                 /*handle the  Error case*/\r
970                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\\r
971                     NFCSTATUS_WRITE_FAILED);\r
972 \r
973                 /*set the buffer index back to zero*/\r
974                 NdefMap->ApduBuffIndex = 0;\r
975 \r
976                 /* call respective CR */\r
977                 phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
978             }\r
979             break;\r
980         case PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_END :\r
981             if((NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW1_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE) &&\r
982                 (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_SW2_INDEX] == PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE))\r
983             {\r
984                 /*  Updating NLEN operation was successful. */\r
985                 /* Entire Write Operation is complete*/\r
986                 /*  Reset the relevant parameters. */\r
987                 Status = PHNFCSTVAL(CID_NFC_NONE,\\r
988                     NFCSTATUS_SUCCESS);\r
989 \r
990                 /* set the state & Data len into context*/\r
991                 NdefMap->CardState = (uint8_t)((NdefMap->CardState ==\r
992                                             PH_NDEFMAP_CARD_STATE_INITIALIZED)?\r
993                                             PH_NDEFMAP_CARD_STATE_READ_WRITE :\r
994                                             NdefMap->CardState);\r
995 \r
996                 NdefMap->DesfireCapContainer.NdefDataLen = (uint16_t)(*NdefMap->WrNdefPacketLength);\r
997 #ifdef PH_HAL4_ENABLE\r
998             /* Do nothing */\r
999 #else\r
1000                 NdefMap->PrevOperation = 0;\r
1001 #endif /* #ifndef PH_HAL4_ENABLE */\r
1002 \r
1003             }\r
1004             else\r
1005             {\r
1006                 NdefMap->PrevOperation = 0;\r
1007                 /*handle the  Error case*/\r
1008                 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\\r
1009                     NFCSTATUS_WRITE_FAILED);\r
1010             }\r
1011 \r
1012             /*set the buffer index back to zero*/\r
1013             NdefMap->ApduBuffIndex = 0;\r
1014 \r
1015             /* call respective CR */\r
1016             phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
1017             break;\r
1018 \r
1019         default:\r
1020             /*define the invalid state*/\r
1021             Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\\r
1022                 NFCSTATUS_INVALID_DEVICE_REQUEST);\r
1023             phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
1024             break;\r
1025         }\r
1026     }\r
1027     else\r
1028     {\r
1029         /* call respective CR */\r
1030         phFriNfc_Desfire_HCrHandler(NdefMap,Status);\r
1031     }\r
1032 }\r
1033 \r
1034 \r
1035 \r
1036 /*!\r
1037 * \brief this shall select the smart tag functinality of the Desfire card.\r
1038 *\r
1039 * Only when this command returns command completed it is a Smart Tag\r
1040 * compatible product.\r
1041 *\r
1042 */\r
1043 static\r
1044 NFCSTATUS   phFriNfc_Desfire_SelectSmartTag(phFriNfc_NdefMap_t *NdefMap)\r
1045 {\r
1046 \r
1047     NFCSTATUS                   status = NFCSTATUS_PENDING;\r
1048 #ifdef DESFIRE_EV1\r
1049     uint8_t                     card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;\r
1050 #endif /* #ifdef DESFIRE_EV1 */\r
1051 \r
1052     /*form the packet for Select smart tag command*/\r
1053     NdefMap->SendRecvBuf[0]  = 0x00; /* cls */\r
1054     NdefMap->SendRecvBuf[1]  = 0xa4; /* ins */\r
1055     NdefMap->SendRecvBuf[2]  = 0x04; /* p1 */\r
1056     NdefMap->SendRecvBuf[3]  = 0x00; /* p2 */\r
1057     NdefMap->SendRecvBuf[4]  = 0x07; /* lc */\r
1058 \r
1059     /* next 7 bytes specify the DF Name*/\r
1060     NdefMap->SendRecvBuf[5]  = 0xd2;\r
1061     NdefMap->SendRecvBuf[6]  = 0x76;\r
1062     NdefMap->SendRecvBuf[7]  = 0x00;\r
1063     NdefMap->SendRecvBuf[8]  = 0x00;\r
1064     NdefMap->SendRecvBuf[9]  = 0x85;\r
1065     NdefMap->SendRecvBuf[10] = 0x01;\r
1066 \r
1067 #ifdef DESFIRE_EV1\r
1068 \r
1069     switch (NdefMap->DespOpFlag)\r
1070     {\r
1071         case PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP:\r
1072         {\r
1073             /* First select the smart tag using the new desfire EV1 and increment the\r
1074                 "sel_index" and if it fails then try the old desfire select smart tag\r
1075                 command */\r
1076             if (0 == NdefMap->CardType)\r
1077             {\r
1078                 /* p2\r
1079                 NdefMap->SendRecvBuf[3]  = DESFIRE_EV1_P2_OFFSET_VALUE; */\r
1080                 NdefMap->SendRecvBuf[11] = 0x01;\r
1081                 /* Le */\r
1082                 NdefMap->SendRecvBuf[12] = 0x00;\r
1083                 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG_EV1;\r
1084                 card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;\r
1085             }\r
1086             else\r
1087             {\r
1088                 NdefMap->SendRecvBuf[3]  = 0x00; /* p2 */\r
1089                 NdefMap->SendRecvBuf[11] = 0x00;\r
1090                 NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG;\r
1091                 card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;\r
1092             }\r
1093             break;\r
1094         }\r
1095 \r
1096         case PH_FRINFC_NDEFMAP_DESF_READ_OP:\r
1097         default :\r
1098         {\r
1099             if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)\r
1100             {\r
1101                 NdefMap->SendRecvBuf[11] = 0x01;\r
1102                 NdefMap->SendRecvBuf[12] = 0x00;\r
1103                 NdefMap->State = (uint8_t)PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG_EV1;\r
1104                 card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1;\r
1105             }\r
1106             else\r
1107             {\r
1108                 NdefMap->SendRecvBuf[11] = 0x00;\r
1109                 NdefMap->State = (uint8_t)PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG;\r
1110                 card_type = PH_FRINFC_NDEFMAP_ISO14443_4A_CARD;\r
1111             }\r
1112             break;\r
1113         }\r
1114     }\r
1115 \r
1116 #else /* #ifdef DESFIRE_EV1 */\r
1117 \r
1118     NdefMap->SendRecvBuf[11] = 0x00;\r
1119 \r
1120 #endif /* #ifdef DESFIRE_EV1 */\r
1121 \r
1122     /*Set the Send length*/\r
1123     NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_SMARTTAG_PKT_SIZE;\r
1124 #ifdef DESFIRE_EV1\r
1125 \r
1126     if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == card_type)\r
1127     {\r
1128         /* Send length is updated for the NEW DESFIRE EV1 */\r
1129         NdefMap->SendLength = (uint16_t)(NdefMap->SendLength + 1);\r
1130     }\r
1131 \r
1132 #else\r
1133     /* Change the state to Select Smart Tag */\r
1134     NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG;\r
1135 #endif /* #ifdef DESFIRE_EV1 */\r
1136 \r
1137     status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);\r
1138 \r
1139     return status;\r
1140 }\r
1141 \r
1142 /*!\r
1143 * \brief this shall select/access the capability container of the Desfire\r
1144 * card.\r
1145 *\r
1146 * This shall be used to identify, if NDEF data structure do exist on\r
1147 * the smart tag, we receive command completed status.\r
1148 *\r
1149 */\r
1150 static\r
1151 NFCSTATUS phFriNfc_Desfire_SelectFile (phFriNfc_NdefMap_t  *NdefMap)\r
1152 {\r
1153 \r
1154     NFCSTATUS                   status = NFCSTATUS_PENDING;\r
1155 \r
1156     /* check for the invalid/unknown desfire operations*/\r
1157     if ((NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP)&& \\r
1158         (NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_READ_OP)&&\\r
1159         ( NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_WRITE_OP) &&\r
1160         ( NdefMap->DespOpFlag != PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP))\r
1161     {\r
1162         status  =   PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE);\r
1163     }\r
1164     else\r
1165     {\r
1166 \r
1167         /*  Set the command*/\r
1168         //NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd;\r
1169 \r
1170         /*  Form the packet for select file command either for the\r
1171         Check Ndef/Read/Write functionalities*/\r
1172         NdefMap->SendRecvBuf[0] = 0x00; /* cls */\r
1173         NdefMap->SendRecvBuf[1] = 0xa4; /* ins */\r
1174         NdefMap->SendRecvBuf[2] = 0x00; /* p1 */\r
1175         NdefMap->SendRecvBuf[3] = 0x00; /* p2 */\r
1176         NdefMap->SendRecvBuf[4] = 0x02; /* lc */\r
1177 \r
1178 #ifdef DESFIRE_EV1\r
1179         if (PH_FRINFC_NDEFMAP_ISO14443_4A_CARD_EV1 == NdefMap->CardType)\r
1180         {\r
1181             NdefMap->SendRecvBuf[3]  = DESFIRE_EV1_P2_OFFSET_VALUE; /* p2 */\r
1182         }\r
1183 #endif /* #ifdef DESFIRE_EV1 */\r
1184 \r
1185         if ( (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP))\r
1186 \r
1187         {\r
1188             /* cap container file identifier*/\r
1189             NdefMap->SendRecvBuf[5] = 0xe1;\r
1190             NdefMap->SendRecvBuf[6] = 0x03;\r
1191         }\r
1192         /* Mantis entry 0394 fixed */\r
1193         else\r
1194         {\r
1195             NdefMap->SendRecvBuf[5] = (uint8_t)((NdefMap->DesfireCapContainer.NdefMsgFid) >> PH_FRINFC_NDEFMAP_DESF_SHL8);\r
1196             NdefMap->SendRecvBuf[6] = (uint8_t)((NdefMap->DesfireCapContainer.NdefMsgFid) & (0x00ff));\r
1197         }\r
1198         /*Set the Send length*/\r
1199         NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_SELECT_FILE_PKT_SIZE;\r
1200 \r
1201         /* Change the state to Select File */\r
1202         NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_FILE;\r
1203 \r
1204         status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);\r
1205 \r
1206     }\r
1207 \r
1208     return status;\r
1209 \r
1210 }\r
1211 \r
1212 /*!\r
1213 * \brief this shall read the data from Desfire card.\r
1214 *\r
1215 * This is used in two cases namely Reading the Capability container\r
1216 * data( le == 0 ) and reading the file data.Maximum bytes to be read during\r
1217 * a single read binary is known after the reading the data from the capability\r
1218 * conatainer.\r
1219 *\r
1220 */\r
1221 static\r
1222 NFCSTATUS  phFriNfc_Desfire_ReadBinary(phFriNfc_NdefMap_t    *NdefMap)\r
1223 {\r
1224     NFCSTATUS    status = NFCSTATUS_PENDING;\r
1225     uint32_t     BytesToRead = 0;\r
1226     uint8_t      BufIndex=0,OperFlag=0;\r
1227     uint16_t     DataCnt=0;\r
1228 \r
1229     /* to read the capability container data*/\r
1230     if (NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP )\r
1231     {\r
1232         /*specifies capability container shall be read*/\r
1233         NdefMap->SendRecvBuf[0] = 0x00;\r
1234         NdefMap->SendRecvBuf[1] = 0xb0;\r
1235         NdefMap->SendRecvBuf[2] = 0x00; /* p1 */\r
1236         NdefMap->SendRecvBuf[3] = 0x00; /* p2 */\r
1237         NdefMap->SendRecvBuf[4] = 0x0F; /* le */\r
1238 \r
1239         NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_READ_BIN_PKT_SIZE;\r
1240 \r
1241         /* Change the state to Cap Container Read */\r
1242         NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_READ_CAP_CONT;\r
1243 \r
1244         /* set the send receive buffer length*/\r
1245         OperFlag = 1;\r
1246     }\r
1247     /*desfire file read operation*/\r
1248     else\r
1249     {\r
1250         NdefMap->SendRecvBuf[0] = 0x00;\r
1251         NdefMap->SendRecvBuf[1] = 0xb0;\r
1252 \r
1253         /*TBD the NLEN bytes*/\r
1254         if( *NdefMap->DataCount == 0 )\r
1255         {\r
1256             /* first read */\r
1257             /* set the offset p1 and p2*/\r
1258             NdefMap->SendRecvBuf[2] = 0;\r
1259             NdefMap->SendRecvBuf[3] = 0;\r
1260         }\r
1261         else\r
1262         {\r
1263             /* as the p1 of the 8bit is 0, p1 and p2 are used to store the\r
1264             ofset value*/\r
1265             DataCnt = *NdefMap->DataCount;\r
1266             DataCnt += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;\r
1267             NdefMap->SendRecvBuf[2] = (uint8_t)((DataCnt)>> PH_FRINFC_NDEFMAP_DESF_SHL8);\r
1268             NdefMap->SendRecvBuf[3] = (uint8_t)((DataCnt)& (0x00ff));\r
1269         }\r
1270         /* calculate the Le Byte*/\r
1271         BytesToRead = phFriNfc_Desfire_HGetLeBytes(NdefMap);\r
1272 \r
1273         if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )\r
1274         {\r
1275             /* BufIndex represents the 2 NLEN bytes and decides about the presence of\r
1276             2 bytes NLEN data*/\r
1277 \r
1278             BufIndex = (uint8_t)(( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1 ) ?\r
1279             PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES:0);\r
1280 \r
1281             if( ((BytesToRead == 1) || (BytesToRead == 2)) && (NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1))\r
1282             {\r
1283                 BytesToRead += BufIndex;\r
1284             }\r
1285         }\r
1286 \r
1287         /* set the Le byte*/\r
1288         /* This following code is true for get nlen  and current offset set*/\r
1289         NdefMap->SendRecvBuf[4]=(uint8_t) BytesToRead  ;\r
1290 \r
1291         /* Change the state to Read */\r
1292         NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_READ_BIN;\r
1293 \r
1294         /*set the send length*/\r
1295         NdefMap->SendLength = PH_FRINFC_NDEFMAP_DESF_CAPDU_READ_BIN_PKT_SIZE;\r
1296         OperFlag = 2;\r
1297     }\r
1298 \r
1299     if (OperFlag == 1 )\r
1300     {\r
1301         status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_MAX_SEND_RECV_BUF_SIZE);\r
1302     }\r
1303     else\r
1304     {\r
1305         status = phFriNfc_Desfire_HSendTransCmd(NdefMap,(uint8_t)(BytesToRead +PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET));\r
1306     }\r
1307     return (status);\r
1308 }\r
1309 \r
1310 /*!\r
1311 * \brief this shall write the data to Desfire card.\r
1312 * Maximum bytes to be written during a single update binary\r
1313 * is known after the reading the data from the capability\r
1314 * conatainer.\r
1315 *\r
1316 * le filed specifes , how many bytes of data to be written to the\r
1317 * Card.\r
1318 *\r
1319 */\r
1320 static\r
1321 NFCSTATUS  phFriNfc_Desfire_UpdateBinary(phFriNfc_NdefMap_t  *NdefMap)\r
1322 {\r
1323 \r
1324     NFCSTATUS   status = NFCSTATUS_PENDING;\r
1325     uint16_t    noOfBytesToWrite = 0, DataCnt=0,\r
1326         index=0;\r
1327 \r
1328     /*  Do we have space in the file to write? */\r
1329     if ( (*NdefMap->DataCount < PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) &&\r
1330         (NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize))\r
1331     {\r
1332         /*  Yes, we have some bytes to write */\r
1333         /*  Check and set the card memory size , if user sent bytes are more than the\r
1334         card memory size*/\r
1335         if( (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >\\r
1336             (uint16_t)(PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE - *NdefMap->DataCount))\r
1337         {\r
1338             NdefMap->ApduBufferSize =( (PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) - (*NdefMap->DataCount + NdefMap->ApduBuffIndex));\r
1339         }\r
1340 \r
1341         /*  Now, we have space in the card to write the data, */\r
1342         /*Form the packet for the update binary command*/\r
1343         NdefMap->SendRecvBuf[0] = 0x00;\r
1344         NdefMap->SendRecvBuf[1] = 0xD6;\r
1345 \r
1346         if( *NdefMap->DataCount == 0)\r
1347         {\r
1348             /* set the p1/p2 offsets */\r
1349             NdefMap->SendRecvBuf[2] = 0x00; /* p1 */\r
1350             NdefMap->SendRecvBuf[3] = 0x00; /* p2 */\r
1351             NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 0;\r
1352         }\r
1353         else\r
1354         {\r
1355             /*  as the p1 of the 8bit is 0, p1 and p2 are used to store the\r
1356             ofset value*/\r
1357             /*  This sets card offset in a card for a write operation. + 2 is\r
1358             added as first 2 offsets represents the size of the NDEF Len present\r
1359             in the file*/\r
1360 \r
1361             DataCnt = *NdefMap->DataCount;\r
1362             DataCnt += PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;\r
1363             NdefMap->SendRecvBuf[2] = (uint8_t)((DataCnt)>> PH_FRINFC_NDEFMAP_DESF_SHL8);\r
1364             NdefMap->SendRecvBuf[3] = (uint8_t)((DataCnt)& (0x00ff));\r
1365             /* No need to attach 2 NLEN bytes at the begining.\r
1366             as we have already attached in the first write operation.*/\r
1367             NdefMap->DesfireCapContainer.SkipNlenBytesFlag = 1;\r
1368 \r
1369         }\r
1370 \r
1371         /*  Calculate the bytes to write */\r
1372         if( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)( NdefMap->DesfireCapContainer.MaxCmdSize ))\r
1373 \r
1374         {\r
1375             noOfBytesToWrite = ( ( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1) ?\r
1376                 NdefMap->DesfireCapContainer.MaxCmdSize :\r
1377             (NdefMap->DesfireCapContainer.MaxCmdSize - PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES));\r
1378         }\r
1379         else\r
1380         {\r
1381             /*  Read only till the available buffer space */\r
1382             noOfBytesToWrite = (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);\r
1383         }\r
1384 \r
1385         if ( NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )\r
1386         {\r
1387             if ( NdefMap->DesfireCapContainer.SkipNlenBytesFlag == 1 )\r
1388             {\r
1389                 index = 5;\r
1390                 /* To Specify the NDEF data len written : updated at the of write cycle*/\r
1391                 NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite;\r
1392             }\r
1393             else\r
1394             {\r
1395                 /* Leave space to update NLEN */\r
1396                 NdefMap->SendRecvBuf[5] = 0x00;\r
1397                 NdefMap->SendRecvBuf[6] = 0x00;\r
1398                 index =7;\r
1399                 /* To Specify the NDEF data len written : updated at the of write cycle*/\r
1400                 NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite + PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;\r
1401             }\r
1402 \r
1403             /* copy the data to SendRecvBuf from the apdu buffer*/\r
1404             (void)memcpy( &NdefMap->SendRecvBuf[index],\r
1405                 &NdefMap->ApduBuffer[NdefMap->ApduBuffIndex],\r
1406                 noOfBytesToWrite);\r
1407             NdefMap->SendLength = (noOfBytesToWrite + index);\r
1408         }\r
1409         else\r
1410         {\r
1411             NdefMap->SendRecvBuf[4] = (uint8_t)noOfBytesToWrite;\r
1412 \r
1413             /* copy the data to SendRecvBuf from the apdu buffer*/\r
1414             (void)memcpy( &NdefMap->SendRecvBuf[5],\r
1415                 &NdefMap->ApduBuffer[NdefMap->ApduBuffIndex],\r
1416                 noOfBytesToWrite);\r
1417             NdefMap->SendLength = (noOfBytesToWrite + 5);\r
1418         }\r
1419 \r
1420         /*  Store the number of bytes being written in the context structure, so that\r
1421         the parameters can be updated, after a successful write operation. */\r
1422         NdefMap->NumOfBytesWritten = noOfBytesToWrite;\r
1423 \r
1424         /* Change the state to Write */\r
1425         NdefMap->State = PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_BEGIN;\r
1426 \r
1427         status = phFriNfc_Desfire_HSendTransCmd(NdefMap,PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET);\r
1428 \r
1429     }   /*  if(NdefMap->ApduBuffIndex < NdefMap->ApduBufferSize) */\r
1430     else\r
1431     {\r
1432         if ( (*NdefMap->DataCount == PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) ||\r
1433             (NdefMap->ApduBuffIndex == NdefMap->ApduBufferSize))\r
1434         {\r
1435             /* The NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_SET_LEN_OP is not\r
1436                 required, because the DespOpFlag shall be WRITE_OP\r
1437                 */\r
1438             /* Update the NLEN Bytes*/\r
1439 #ifdef PH_HAL4_ENABLE\r
1440             /* Do nothing */\r
1441 #else\r
1442             NdefMap->DespOpFlag = PH_FRINFC_NDEFMAP_DESF_SET_LEN_OP;\r
1443 #endif /* #ifdef PH_HAL4_ENABLE */\r
1444             status = phFriNfc_Desfire_HSetGet_NLEN(NdefMap);\r
1445         }\r
1446         else\r
1447         {\r
1448             /*  The control should not come here.\r
1449             wrong internal calculation.\r
1450             we have actually written more than the space available\r
1451             in the card ! */\r
1452 #ifndef PH_HAL4_ENABLE\r
1453             status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1454                 NFCSTATUS_CMD_ABORTED);\r
1455 #else\r
1456             status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1457                 NFCSTATUS_FAILED);\r
1458 #endif\r
1459             /*  Reset the relevant parameters. */\r
1460             NdefMap->ApduBuffIndex = 0;\r
1461             NdefMap->PrevOperation = 0;\r
1462 \r
1463             /* call respective CR */\r
1464             phFriNfc_Desfire_HCrHandler(NdefMap,status);\r
1465         }\r
1466 \r
1467     }\r
1468     /*  if(*NdefMap->DataCount < PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE) */\r
1469 \r
1470     return status;\r
1471 }\r
1472 \r
1473 \r
1474 static void phFriNfc_Desfire_HChkNDEFFileAccessRights(phFriNfc_NdefMap_t *NdefMap)\r
1475 {\r
1476     if ( (NdefMap->DesfireCapContainer.ReadAccess  == 0x00) &&\r
1477         (NdefMap->DesfireCapContainer.WriteAccess == 0x00 ))\r
1478     {\r
1479         /* Set the card state to Read/write State*/\r
1480         /* This state can be either INITIALISED or READWRITE. but default\r
1481         is INITIALISED */\r
1482         NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;\r
1483 \r
1484     }\r
1485     else if((NdefMap->DesfireCapContainer.ReadAccess  == 0x00) &&\r
1486         (NdefMap->DesfireCapContainer.WriteAccess == 0xFF ))\r
1487     {\r
1488         /* Set the card state to Read Only State*/\r
1489         NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;\r
1490     }\r
1491     else\r
1492     {\r
1493         /* Set the card state to invalid State*/\r
1494         NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;\r
1495     }\r
1496 }\r
1497 \r
1498 /*!\r
1499 * \brief this shall update the Desfire capability container structure.\r
1500 *\r
1501 * This function shall store version,maximum Ndef data structure size,\r
1502 * Read Access permissions, Write Access permissions , Maximum data size\r
1503 * that can be sent using a single Update Binary, maximum data size that\r
1504 * can be read from the Desfire using a singlr read binary.\r
1505 * These vaues shall be stored and used during the read/update binary\r
1506 * operations.\r
1507 *\r
1508 */\r
1509 static\r
1510 NFCSTATUS  phFriNfc_Desfire_Update_SmartTagCapContainer(phFriNfc_NdefMap_t    *NdefMap)\r
1511 {\r
1512     uint16_t    CapContSize = 0,\r
1513         /* this is initalised 2 because CCLEN includes the field size bytes i.e 2bytes*/\r
1514         CCLen= 0;\r
1515     uint8_t     ErrFlag = 0;\r
1516 \r
1517     NFCSTATUS status= NFCSTATUS_SUCCESS;\r
1518 \r
1519     /*Check the Size of Cap Container */\r
1520     CapContSize = ( (((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_FIRST_INDEX])<<8)+ \\r
1521         NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_SECOND_INDEX]);\r
1522 \r
1523     CCLen += 2;\r
1524 \r
1525     if ( (CapContSize < 0x0f) || (CapContSize == 0xffff))\r
1526     {\r
1527         ErrFlag =1;\r
1528     }\r
1529     else\r
1530     {\r
1531         /*Version : Smart Tag Spec version */\r
1532         /* check for the validity of Major and Minor Version numbers*/\r
1533         status = phFriNfc_MapTool_ChkSpcVer (   NdefMap,\r
1534             PH_FRINFC_NDEFMAP_DESF_VER_INDEX);\r
1535         if ( status  !=  NFCSTATUS_SUCCESS )\r
1536         {\r
1537             ErrFlag =1;\r
1538         }\r
1539         else\r
1540         {\r
1541             CCLen += 1;\r
1542 \r
1543             /*Get Response APDU data size\r
1544             to check the integration s/w response size*/\r
1545 #ifdef PH_HAL4_ENABLE\r
1546                         {\r
1547                                 uint16_t        max_rsp_size =\r
1548                                         ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_FIRST_INDEX]) << 8)\\r
1549                                         + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_SECOND_INDEX]);\r
1550                                 NdefMap->DesfireCapContainer.MaxRespSize =\r
1551                                                                 ((max_rsp_size > PHHAL_MAX_DATASIZE)?\r
1552                                                                 (PHHAL_MAX_DATASIZE) : max_rsp_size);\r
1553                         }\r
1554 #else\r
1555                         NdefMap->DesfireCapContainer.MaxRespSize =\r
1556                                 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_FIRST_INDEX]) << 8)\\r
1557                 +NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_SECOND_INDEX]);\r
1558 #endif /* #ifdef PH_HAL4_ENABLE */\r
1559 \r
1560             /*Get Command APDU data size*/\r
1561 #ifdef PH_HAL4_ENABLE\r
1562                         {\r
1563                                 uint16_t        max_cmd_size =\r
1564                                         ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_FIRST_INDEX])<<8)\\r
1565                                         + NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_SECOND_INDEX]);\r
1566 \r
1567                                 NdefMap->DesfireCapContainer.MaxCmdSize =\r
1568                                                                 ((max_cmd_size > PHHAL_MAX_DATASIZE)?\r
1569                                                                 (PHHAL_MAX_DATASIZE): max_cmd_size);\r
1570                         }\r
1571 #else\r
1572                         NdefMap->DesfireCapContainer.MaxCmdSize =\r
1573                                 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_FIRST_INDEX])<<8)\\r
1574                 +NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_SECOND_INDEX]);\r
1575 #endif /* #ifdef PH_HAL4_ENABLE */\r
1576             /* Check for the Validity of Cmd & Resp Size*/\r
1577             /* check the Validity of the Cmd Size*/\r
1578             if( (NdefMap->DesfireCapContainer.MaxRespSize < 0x0f) ||\r
1579                 ( NdefMap->DesfireCapContainer.MaxCmdSize == 0x00))\r
1580             {\r
1581                 ErrFlag=1;\r
1582 \r
1583             }\r
1584             else\r
1585             {\r
1586                 CCLen += 4;\r
1587 \r
1588                 /* Check and Parse the TLV structure */\r
1589                 /* In future this chk can be extended to Propritery TLV */\r
1590                 //status = phFriNfc_ChkAndParseTLV(NdefMap);\r
1591                 status = phFriNfc_Desf_HChkAndParseTLV(NdefMap,PH_FRINFC_NDEFMAP_DESF_TLV_INDEX);\r
1592                 if ( (status == NFCSTATUS_SUCCESS) && (NdefMap->TLVFoundFlag == PH_FRINFC_NDEFMAP_DESF_NDEF_CNTRL_TLV))\r
1593                 {\r
1594                     CCLen += 1;\r
1595 \r
1596                     /* check the TLV length*/\r
1597                     if ( (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) > 0x00 ) &&\r
1598                         (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) <= 0xFE )&&\r
1599                         (( NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX]) == 0x06 ))\r
1600                     {\r
1601                         CCLen +=1;\r
1602                         /* store the contents in to the container structure*/\r
1603                         NdefMap->DesfireCapContainer.NdefMsgFid = ( (((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_FIRST_INDEX])<<PH_FRINFC_NDEFMAP_DESF_SHL8)+ \\r
1604                             NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_SECOND_INDEX]);\r
1605 \r
1606                         CCLen +=2;\r
1607 \r
1608                         /* Invalid Msg File Id : User Can't Have read/write Opeartion*/\r
1609                         if (    (NdefMap->DesfireCapContainer.NdefMsgFid == 0xFFFF) ||\r
1610                             (NdefMap->DesfireCapContainer.NdefMsgFid == 0xE102) ||\r
1611                             (NdefMap->DesfireCapContainer.NdefMsgFid == 0xE103) ||\r
1612                             (NdefMap->DesfireCapContainer.NdefMsgFid == 0x3F00) ||\r
1613                             (NdefMap->DesfireCapContainer.NdefMsgFid == 0x3FFF ) )\r
1614                         {\r
1615 \r
1616                             ErrFlag=1;\r
1617                         }\r
1618                         else\r
1619                         {\r
1620                             /*Get Ndef Size*/\r
1621                             NdefMap->DesfireCapContainer.NdefFileSize =\r
1622                                 ((((uint16_t)NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_FIRST_INDEX])<<8)\r
1623                                 | (NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_SECOND_INDEX] & 0x00ff));\r
1624 \r
1625 \r
1626                             /*Check Ndef Size*/\r
1627                             /* TBD : Do we need to minus 2 bytes of size it self?*/\r
1628                             if ( ((NdefMap->DesfireCapContainer.NdefFileSize -2) <= 0x0004 ) ||\r
1629                                 ((NdefMap->DesfireCapContainer.NdefFileSize -2) == 0xFFFD ) )\r
1630                             {\r
1631                                 ErrFlag=1;\r
1632                             }\r
1633                             else\r
1634                             {\r
1635                                 CCLen +=2;\r
1636 \r
1637                                 /*Ndef File Read Access*/\r
1638                                 NdefMap->DesfireCapContainer.ReadAccess = NdefMap->\\r
1639                                     SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILERD_ACCESS_INDEX] ;\r
1640 \r
1641                                 /*Ndef File Write Access*/\r
1642                                 NdefMap->DesfireCapContainer.WriteAccess = NdefMap->SendRecvBuf[PH_FRINFC_NDEFMAP_DESF_NDEF_FILEWR_ACCESS_INDEX];\r
1643 \r
1644                                 CCLen +=2;\r
1645 \r
1646                                 phFriNfc_Desfire_HChkNDEFFileAccessRights(NdefMap);\r
1647                             }\r
1648                         }\r
1649                     }\r
1650                     else\r
1651                     {\r
1652 \r
1653                         /* TLV Lenth is of two byte value\r
1654                         TBD: As the length of TLV is fixed for 6 bytes. We need not\r
1655                         handle the 2 byte value*/\r
1656 \r
1657 \r
1658                     }\r
1659                 }\r
1660                 else\r
1661                 {\r
1662                     if ( NdefMap->TLVFoundFlag == PH_FRINFC_NDEFMAP_DESF_PROP_CNTRL_TLV )\r
1663                     {\r
1664                         /*TBD: To Handle The Proprietery TLV*/\r
1665                     }\r
1666                     else\r
1667                     {\r
1668                         /*Invalid T found case*/\r
1669                         ErrFlag =1;\r
1670                     }\r
1671                 }\r
1672                 /* check for the entire LENGTH Validity\r
1673                 CCLEN + TLV L value == CCLEN*/\r
1674                 if ( CapContSize != CCLen )\r
1675                 {\r
1676                     ErrFlag=1;\r
1677                 }\r
1678 \r
1679             }/* if NdefMap->DesfireCapContainer.MaxRespSize < 0x0f */\r
1680         }/* Chkeck Map Version*/\r
1681     }/* CC size invalid*/\r
1682     if( ErrFlag == 1 )\r
1683     {\r
1684         status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\r
1685             NFCSTATUS_NO_NDEF_SUPPORT);\r
1686     }\r
1687     return ( status );\r
1688 }\r
1689 \r
1690 static uint32_t phFriNfc_Desfire_HGetLeBytes(phFriNfc_NdefMap_t *NdefMap)\r
1691 {\r
1692     /*Represents the LE byte*/\r
1693     uint16_t BytesToRead =0;\r
1694 \r
1695     if ( NdefMap->DespOpFlag == PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP )\r
1696     {\r
1697         BytesToRead = PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES;\r
1698          NdefMap->DesfireCapContainer.SkipNlenBytesFlag =0;\r
1699     }\r
1700     else\r
1701     {\r
1702 \r
1703         /* Calculate Le bytes : No of bytes to read*/\r
1704         /* Check for User Apdu Buffer Size and Msg Size of Desfire Capability container */\r
1705         if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= NdefMap->DesfireCapContainer.MaxRespSize)\r
1706         {\r
1707             /*  We have enough buffer space to read the whole capability container\r
1708             size bytes\r
1709             Now, check do we have NdefMap->DesfireCapContainer.MaxRespSize to read ? */\r
1710 \r
1711             BytesToRead = (((NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount) >=\r
1712                 NdefMap->DesfireCapContainer.MaxRespSize) ?\r
1713                 NdefMap->DesfireCapContainer.MaxRespSize :\r
1714             (NdefMap->DesfireCapContainer.NdefDataLen -\r
1715                 *NdefMap->DataCount));\r
1716         }\r
1717         else\r
1718         {\r
1719             /*  Read only till the available buffer space */\r
1720             BytesToRead = (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);\r
1721             if(BytesToRead >= (uint16_t)(NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount))\r
1722             {\r
1723                 BytesToRead = (NdefMap->DesfireCapContainer.NdefDataLen - *NdefMap->DataCount);\r
1724             }\r
1725         }\r
1726 \r
1727         NdefMap->DesfireCapContainer.SkipNlenBytesFlag =\r
1728             (uint8_t)(((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )&&( *NdefMap->DataCount == 0 )) ?\r
1729             1 : 0);\r
1730 \r
1731     }\r
1732     return (BytesToRead);\r
1733 }\r
1734 \r
1735 \r
1736 \r
1737 /*!\r
1738 * \brief this shall notify the integration software with respective\r
1739 *  success/error status along with the completion routines.\r
1740 *\r
1741 *  This routine is called from the desfire process function.\r
1742 *\r
1743 */\r
1744 \r
1745 static void phFriNfc_Desfire_HCrHandler(    phFriNfc_NdefMap_t  *NdefMap,\r
1746                                         NFCSTATUS           Status)\r
1747 {\r
1748     /* set the state back to the Reset_Init state*/\r
1749     NdefMap->State =  PH_FRINFC_NDEFMAP_STATE_RESET_INIT;\r
1750 \r
1751     switch(NdefMap->DespOpFlag)\r
1752     {\r
1753         /* check which routine has the problem and set the CR*/\r
1754     case PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP :\r
1755         /* set the completion routine*/\r
1756         NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_CHK_NDEF].\\r
1757             CompletionRoutine(NdefMap->CompletionRoutine->Context,\\r
1758             Status);\r
1759         break;\r
1760 \r
1761     case PH_FRINFC_NDEFMAP_DESF_READ_OP :\r
1762         /* set the completion routine*/\r
1763         NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_RD_NDEF].\\r
1764             CompletionRoutine(NdefMap->CompletionRoutine->Context,\\r
1765             Status);\r
1766         break;\r
1767 \r
1768     case PH_FRINFC_NDEFMAP_DESF_WRITE_OP :\r
1769         /* set the completion routine*/\r
1770         NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_WR_NDEF].\\r
1771             CompletionRoutine(NdefMap->CompletionRoutine->Context,\\r
1772             Status);\r
1773         break;\r
1774 \r
1775     default :\r
1776         /* set the completion routine*/\r
1777         NdefMap->CompletionRoutine[PH_FRINFC_NDEFMAP_CR_INVALID_OPE].\\r
1778             CompletionRoutine(NdefMap->CompletionRoutine->Context,\\r
1779             Status);\r
1780         break;\r
1781 \r
1782     }\r
1783 }\r
1784 \r
1785 static NFCSTATUS phFriNfc_Desfire_HSendTransCmd(phFriNfc_NdefMap_t *NdefMap,uint8_t SendRecvLen)\r
1786 {\r
1787 \r
1788     NFCSTATUS status =  NFCSTATUS_SUCCESS;\r
1789 \r
1790     /* set the command type*/\r
1791 #ifndef PH_HAL4_ENABLE\r
1792     NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_CmdListTClCmd;\r
1793 #else\r
1794     NdefMap->Cmd.Iso144434Cmd = phHal_eIso14443_4_Raw;\r
1795 #endif\r
1796 \r
1797     /* set the Additional Info*/\r
1798     NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;\r
1799     NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;\r
1800 \r
1801     /*set the completion routines for the desfire card operations*/\r
1802     NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Desfire_Process;\r
1803     NdefMap->MapCompletionInfo.Context = NdefMap;\r
1804 \r
1805     /* set the receive length */\r
1806     *NdefMap->SendRecvLength = ((uint16_t)(SendRecvLen));\r
1807 \r
1808 \r
1809     /*Call the Overlapped HAL Transceive function */\r
1810     status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,\r
1811         &NdefMap->MapCompletionInfo,\r
1812         NdefMap->psRemoteDevInfo,\r
1813         NdefMap->Cmd,\r
1814         &NdefMap->psDepAdditionalInfo,\r
1815         NdefMap->SendRecvBuf,\r
1816         NdefMap->SendLength,\r
1817         NdefMap->SendRecvBuf,\r
1818         NdefMap->SendRecvLength);\r
1819 \r
1820     return (status);\r
1821 \r
1822 \r
1823 }\r
1824 \r
1825 \r
1826 #ifdef UNIT_TEST\r
1827 #include <phUnitTestNfc_Desfire_static.c>\r
1828 #endif\r
1829 \r
1830 #endif  /* PH_FRINFC_MAP_DESFIRE_DISABLED */\r