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