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_TopazMap.c
19 * \brief NFC Ndef Mapping For Remote Devices.
20 *
21 * Project: NFC-FRI
22 *
23 * $Date: Mon Dec 13 14:14:14 2010 $
24 * $Author: ing02260 $
25 * $Revision: 1.23 $
26 * $Aliases: $
27 *
28 */
29
30
31
32 #include <phFriNfc_NdefMap.h>
33 #include <phFriNfc_TopazMap.h>
34 #include <phFriNfc_MapTools.h>
35 #include <phFriNfc_OvrHal.h>
36
37 #ifndef PH_FRINFC_MAP_TOPAZ_DISABLED
38 /*! \ingroup grp_file_attributes
39 * \name NDEF Mapping
40 *
41 * File: \ref phFriNfcNdefMap.c
42 *
43 */
44 /*@{*/
45 #define PHFRINFCTOPAZMAP_FILEREVISION "$Revision: 1.23 $"
46 #define PHFRINFCTOPAZMAP_FILEALIASES "$Aliases: $"
47 /*@}*/
48 /****************** Start of macros ********************/
49 /* Below MACRO is used for the WRITE error scenario,
50 in case PN544 returns error for any WRITE, then
51 read the written block and byte number, to check the data
52 written to the card is correct or not
53 */
54 /* #define TOPAZ_RF_ERROR_WORKAROUND */
55
56 #ifdef FRINFC_READONLY_NDEF
57
58 #define CC_BLOCK_NUMBER (0x01U)
59 #define LOCK_BLOCK_NUMBER (0x0EU)
60
61 #define LOCK0_BYTE_NUMBER (0x00U)
62 #define LOCK0_BYTE_VALUE (0xFFU)
63
64 #define LOCK1_BYTE_NUMBER (0x01U)
65 #define LOCK1_BYTE_VALUE (0x7FU)
66
67 #define CC_RWA_BYTE_NUMBER (0x03U)
68 #define CC_READ_ONLY_VALUE (0x0FU)
69
70 #endif /* #ifdef FRINFC_READONLY_NDEF */
71
72 #ifdef TOPAZ_RF_ERROR_WORKAROUND
73
74 /* Below MACROs are added for the error returned from HAL, if the
75 below error has occured during the WRITE, then read the error
76 returned blocks to confirm */
77 #define FRINFC_RF_TIMEOUT_89 (0x89U)
78 #define FRINFC_RF_TIMEOUT_90 (0x90U)
79
80 /* State specific to read after the RF ERROR for the WRITE */
81 #define PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ (0x0FU)
82
83 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
84
85 /****************** End of macros ********************/
86
87 /*!
88 * \name Topaz Mapping - Helper Functions
89 *
90 */
91 /*@{*/
92
93 /*!
94 * \brief \copydoc page_ovr Helper function for Topaz. This function shall read 8 bytes
95 * from the card.
96 */
97 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,
98 uint16_t BlockNo,
99 uint16_t ByteNo);
100
101 /*!
102 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
103 * read id command
104 */
105 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap);
106
107 /*!
108 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process
109 * read all command
110 */
111 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap);
112
113 /*!
114 * \brief \copydoc page_ovr Helper function for Topaz. This function depends on
115 * function called by the user
116 */
117 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap);
118
119 /*!
120 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the CC
121 * bytes
122 */
123 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap);
124
125 /*!
126 * \brief \copydoc page_ovr Helper function for Topaz. This function finds
127 * NDEF TLV
128 */
129 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap);
130
131 /*!
132 * \brief \copydoc page_ovr Helper function for Topaz. This function writes a
133 * byte into the card
134 */
135 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,
136 uint16_t BlockNo,
137 uint16_t ByteNo,
138 uint8_t ByteVal
139 );
140
141 /*!
142 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the
143 * NMN write
144 */
145 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap);
146
147 /*!
148 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the length field of
149 * the NDEF TLV
150 */
151 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap);
152
153 /*!
154 * \brief \copydoc page_ovr Helper function for Topaz. This function updates length field
155 * of the NDEF TLV after complete write.
156 */
157 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t *NdefMap);
158
159 /*!
160 * \brief \copydoc page_ovr Helper function for Topaz. This function copies the card data
161 * to the user buffer
162 */
163 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf( phFriNfc_NdefMap_t *NdefMap);
164
165 /*!
166 * \brief \copydoc page_ovr Helper function for Topaz. This function shall process the
167 * written data
168 */
169 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData( phFriNfc_NdefMap_t *NdefMap);
170
171 /*!
172 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the block
173 * number is correct or not
174 */
175 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t *NdefMap);
176
177 /*!
178 * \brief \copydoc page_ovr Helper function for Topaz. This function writes the 0th
179 * byte of block 1 has Zero
180 */
181 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t *NdefMap);
182
183 /*!
184 * \brief \copydoc page_ovr Helper function for Topaz. This function calls the
185 * completion routine
186 */
187 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t *NdefMap,
188 NFCSTATUS Status);
189
190 /*!
191 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
192 * the CC byte in check ndef function
193 */
194 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t *NdefMap);
195
196 /*!
197 * \brief \copydoc page_ovr Helper function for Topaz check ndef. This function checks
198 * the lock bits and set a card state
199 */
200 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t *NdefMap);
201
202 /*!
203 * \brief \copydoc page_ovr Helper function for Topaz. This function writes CC bytes or
204 * type of the TLV
205 */
206 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t *NdefMap);
207
208 #ifdef TOPAZ_RF_ERROR_WORKAROUND
209
210 /*!
211 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written
212 * value after the
213 */
214 static
215 NFCSTATUS
216 phFriNfc_Tpz_H_CheckWrittenData (
217 phFriNfc_NdefMap_t *psNdefMap,
218 uint8_t state_rf_error);
219
220 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
221
222 /*!
223 * \brief \copydoc page_ovr Helper function for Topaz. This function checks the written
224 * CC bytes are correct
225 */
226 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t *NdefMap);
227 /*@}*/
phFriNfc_TopazMap_H_Reset(phFriNfc_NdefMap_t * NdefMap)228 void phFriNfc_TopazMap_H_Reset(phFriNfc_NdefMap_t *NdefMap)
229 {
230 /* Initialising the Topaz structure variable */
231 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_INVALID_OPE;
232 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
233 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
234 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_VAL0;
235 (void)memset(NdefMap->TopazContainer.ReadBuffer, PH_FRINFC_TOPAZ_VAL0,
236 sizeof(NdefMap->TopazContainer.ReadBuffer));
237 NdefMap->TopazContainer.ReadWriteCompleteFlag = PH_FRINFC_TOPAZ_FLAG0;
238 NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_VAL0;
239 (void)memset(NdefMap->TopazContainer.UID, PH_FRINFC_TOPAZ_VAL0,
240 sizeof(NdefMap->TopazContainer.UID));
241 NdefMap->TopazContainer.Cur_RW_Index=0;
242 NdefMap->TopazContainer.ByteRWFrmCard =0;
243 }
244
245 /*!
246 * \brief Check whether a particular Remote Device is NDEF compliant.
247 *
248 * The function checks whether the peer device is NDEF compliant.
249 *
250 * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t
251 * structure describing the component context.
252 *
253 * \retval NFCSTATUS_PENDING The action has been successfully triggered.
254 * \retval Others An error has occurred.
255 *
256 */
257
phFriNfc_TopazMap_ChkNdef(phFriNfc_NdefMap_t * NdefMap)258 NFCSTATUS phFriNfc_TopazMap_ChkNdef( phFriNfc_NdefMap_t *NdefMap)
259 {
260 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
261 NFCSTATUS_INVALID_PARAMETER);
262 if ( NdefMap != NULL)
263 {
264 /* Update the previous operation */
265 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
266 /* Update the CR index to know from which operation completion
267 routine has to be called */
268 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_CHK_NDEF;
269 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
270 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
271
272 /* Set card state */
273 NdefMap->CardType = PH_FRINFC_NDEFMAP_TOPAZ_CARD;
274
275 /* Change the state to Check Ndef Compliant */
276 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READID;
277 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_CHECK_OPE;
278
279 #ifdef TOPAZ_RAW_SUPPORT
280 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
281 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID;
282 #else
283 #ifdef PH_HAL4_ENABLE
284 NdefMap->Cmd.JewelCmd = phHal_eJewel_RID;
285 #else
286 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRid;
287 #endif
288 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
289
290 Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
291 NdefMap->TopazContainer.ByteNumber);
292 }
293 return Result;
294 }
295
296 #ifdef FRINFC_READONLY_NDEF
297
298 NFCSTATUS
phFriNfc_TopazMap_ConvertToReadOnly(phFriNfc_NdefMap_t * NdefMap)299 phFriNfc_TopazMap_ConvertToReadOnly (
300 phFriNfc_NdefMap_t *NdefMap)
301 {
302 NFCSTATUS result = NFCSTATUS_SUCCESS;
303
304 result = phFriNfc_Tpz_H_WrAByte (NdefMap, CC_BLOCK_NUMBER,
305 CC_RWA_BYTE_NUMBER, CC_READ_ONLY_VALUE);
306
307 if (NFCSTATUS_PENDING == PHNFCSTATUS(result))
308 {
309 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE;
310 }
311 return result;
312 }
313
314 #endif /* #ifdef FRINFC_READONLY_NDEF */
315
316 /*!
317 * \brief Initiates Reading of NDEF information from the Remote Device.
318 *
319 * The function initiates the reading of NDEF information from a Remote Device.
320 * It performs a reset of the state and starts the action (state machine).
321 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
322 * has been triggered.
323 */
phFriNfc_TopazMap_RdNdef(phFriNfc_NdefMap_t * NdefMap,uint8_t * PacketData,uint32_t * PacketDataLength,uint8_t Offset)324 NFCSTATUS phFriNfc_TopazMap_RdNdef( phFriNfc_NdefMap_t *NdefMap,
325 uint8_t *PacketData,
326 uint32_t *PacketDataLength,
327 uint8_t Offset)
328 {
329 NFCSTATUS Result = NFCSTATUS_SUCCESS;
330
331 /* Copy user buffer to the context */
332 NdefMap->ApduBuffer = PacketData;
333 /* Copy user length to the context */
334 NdefMap->ApduBufferSize = *PacketDataLength;
335 /* Update the user memory size to a context variable */
336 NdefMap->NumOfBytesRead = PacketDataLength;
337 /* Number of bytes read from the card is zero.
338 This variable returns the number of bytes read
339 from the card. */
340 *NdefMap->NumOfBytesRead = PH_FRINFC_TOPAZ_VAL0;
341 /* Index to know the length read */
342 NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;
343 /* Store the offset in the context */
344 NdefMap->Offset = Offset;
345 /* Update the CR index to know from which operation completion
346 routine has to be called */
347 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_RD_NDEF;
348
349 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || ( NdefMap->PrevOperation ==
350 PH_FRINFC_NDEFMAP_WRITE_OPE))
351 {
352 /* If previous operation is not read then the read shall
353 start from BEGIN */
354 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
355 /* Initialise current block and byte number */
356 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
357 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
358 /* State has to be changed */
359 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;
360 NdefMap->TopazContainer.ReadWriteCompleteFlag =
361 PH_FRINFC_TOPAZ_FLAG0;
362 /* Topaz command = READALL */
363 #ifdef TOPAZ_RAW_SUPPORT
364 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
365 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
366 #else
367
368 #ifdef PH_HAL4_ENABLE
369 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
370 #else
371 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
372 #endif
373
374 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
375 }
376
377 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
378 /* Offset = Current, but the read has reached the End of Card */
379 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
380 (NdefMap->TopazContainer.ReadWriteCompleteFlag ==
381 PH_FRINFC_TOPAZ_FLAG1))
382 {
383 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
384 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
385 }
386 else
387 {
388 /* if the offset is begin then call READALL else copy the data
389 from the user buffer */
390 Result = ((Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
391 phFriNfc_Tpz_H_RdBytes(NdefMap,
392 NdefMap->TopazContainer.CurrentBlock,
393 NdefMap->TopazContainer.ByteNumber):
394 phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap));
395 }
396
397 return Result;
398 }
399
400 /*!
401 * \brief Initiates Writing of NDEF information to the Remote Device.
402 *
403 * The function initiates the writing of NDEF information to a Remote Device.
404 * It performs a reset of the state and starts the action (state machine).
405 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
406 * has been triggered.
407 */
phFriNfc_TopazMap_WrNdef(phFriNfc_NdefMap_t * NdefMap,uint8_t * PacketData,uint32_t * PacketDataLength,uint8_t Offset)408 NFCSTATUS phFriNfc_TopazMap_WrNdef( phFriNfc_NdefMap_t *NdefMap,
409 uint8_t *PacketData,
410 uint32_t *PacketDataLength,
411 uint8_t Offset)
412 {
413 NFCSTATUS Result = NFCSTATUS_SUCCESS;
414 uint8_t TempByteVal = 0;
415 /* Copy user buffer to the context */
416 NdefMap->ApduBuffer = PacketData;
417 /* Copy user length to the context */
418 NdefMap->ApduBufferSize = *PacketDataLength;
419 /* Index to know the length written */
420 NdefMap->ApduBuffIndex = PH_FRINFC_TOPAZ_VAL0;
421 /* Update the user memory size to a context variable */
422 NdefMap->WrNdefPacketLength = PacketDataLength;
423 /* Number of bytes written to the card is zero.
424 This variable returns the number of bytes written
425 to the card. */
426 *NdefMap->WrNdefPacketLength = PH_FRINFC_TOPAZ_VAL0;
427 /* Update the CR index to know from which operation completion
428 routine has to be called */
429 NdefMap->TopazContainer.CRIndex = PH_FRINFC_NDEFMAP_CR_WR_NDEF;
430 /* Store the offset in the context */
431 NdefMap->Offset = Offset;
432
433
434 if( (Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
435 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))
436 {
437 NdefMap->Offset = PH_FRINFC_NDEFMAP_SEEK_BEGIN;
438 /* Initialise current block and byte number */
439 NdefMap->TopazContainer.CurrentBlock = PH_FRINFC_TOPAZ_VAL1;
440 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL0;
441 /* State has to be changed */
442 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;
443 /* Topaz command = READALL */
444
445 #ifdef TOPAZ_RAW_SUPPORT
446 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
447 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
448 #else
449 #ifdef PH_HAL4_ENABLE
450 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
451 #else
452 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
453 #endif
454 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
455 NdefMap->TopazContainer.ReadWriteCompleteFlag =
456 PH_FRINFC_TOPAZ_FLAG0;
457 NdefMap->TopazContainer.RemainingSize = NdefMap->CardMemSize;
458 TempByteVal = NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1];
459 }
460 else
461 {
462 /* State has to be changed */
463 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
464 /* copy the user data to write into the card */
465 TempByteVal = NdefMap->ApduBuffer[NdefMap->ApduBuffIndex];
466 }
467
468 /* Update the previous operation to write operation */
469 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
470 if((Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
471 (NdefMap->TopazContainer.ReadWriteCompleteFlag ==
472 PH_FRINFC_TOPAZ_FLAG1))
473 {
474 /* Offset = Current, but the read has reached the End of Card */
475 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
476 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
477 }
478 else
479 {
480 /* Check the block */
481 phFriNfc_Tpz_H_BlkChk(NdefMap);
482 /* if offset is begin then call READALL else start writing */
483 Result = ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
484 phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
485 NdefMap->TopazContainer.ByteNumber):
486 phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock,
487 NdefMap->TopazContainer.ByteNumber,TempByteVal));
488 }
489
490 return Result;
491 }
492
493
494 /*!
495 * \brief Completion Routine, Processing function, needed to avoid long blocking.
496 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
497 * Routine in order to be able to notify the component that an I/O has finished and data are
498 * ready to be processed.
499 *
500 */
501
phFriNfc_TopazMap_Process(void * Context,NFCSTATUS Status)502 void phFriNfc_TopazMap_Process( void *Context,
503 NFCSTATUS Status)
504 {
505
506 phFriNfc_NdefMap_t *psNdefMap = NULL;
507
508 #ifdef TOPAZ_RF_ERROR_WORKAROUND
509
510 static uint8_t rf_error_state = 0;
511
512 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
513 #ifdef FRINFC_READONLY_NDEF
514 static uint8_t written_lock_byte = 0;
515 #endif /* #ifdef FRINFC_READONLY_NDEF */
516
517 psNdefMap = (phFriNfc_NdefMap_t *)Context;
518
519 if ((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER))
520 {
521 switch (psNdefMap->State)
522 {
523 #ifdef FRINFC_READONLY_NDEF
524 case PH_FRINFC_TOPAZ_STATE_WR_CC_BYTE:
525 {
526 if((CC_READ_ONLY_VALUE == *psNdefMap->SendRecvBuf)
527 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
528 {
529 written_lock_byte = 0;
530 #ifdef TOPAZ_RAW_SUPPORT
531 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
532 #else
533 #ifdef PH_HAL4_ENABLE
534 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
535 #else
536 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;
537 #endif /* #ifdef PH_HAL4_ENABLE */
538 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
539 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER,
540 LOCK0_BYTE_NUMBER);
541
542 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
543 {
544 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE;
545 }
546 }
547 else
548 {
549 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
550 NFCSTATUS_INVALID_RECEIVE_LENGTH);
551 }
552 break;
553 }
554
555 case PH_FRINFC_TOPAZ_STATE_RD_LOCK0_BYTE:
556 {
557 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)
558 {
559 Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER,
560 LOCK0_BYTE_NUMBER,
561 LOCK0_BYTE_VALUE);
562
563 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
564 {
565 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE;
566 }
567 }
568 break;
569 }
570
571 case PH_FRINFC_TOPAZ_STATE_WR_LOCK0_BYTE:
572 {
573 if((LOCK0_BYTE_VALUE == *psNdefMap->SendRecvBuf)
574 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
575 {
576 #ifdef TOPAZ_RAW_SUPPORT
577 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
578 #else
579 #ifdef PH_HAL4_ENABLE
580 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
581 #else
582 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;
583 #endif /* #ifdef PH_HAL4_ENABLE */
584 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
585 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, LOCK_BLOCK_NUMBER,
586 LOCK1_BYTE_NUMBER);
587
588 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
589 {
590 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE;
591 }
592 }
593 else
594 {
595 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
596 NFCSTATUS_INVALID_RECEIVE_LENGTH);
597 }
598 }
599
600 case PH_FRINFC_TOPAZ_STATE_RD_LOCK1_BYTE:
601 {
602 if (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength)
603 {
604 written_lock_byte = (uint8_t)(*psNdefMap->SendRecvBuf | LOCK1_BYTE_VALUE);
605 Status = phFriNfc_Tpz_H_WrAByte (psNdefMap, LOCK_BLOCK_NUMBER,
606 LOCK1_BYTE_NUMBER,
607 written_lock_byte);
608
609 if (NFCSTATUS_PENDING == PHNFCSTATUS(Status))
610 {
611 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE;
612 }
613 }
614 break;
615 }
616
617 case PH_FRINFC_TOPAZ_STATE_WR_LOCK1_BYTE:
618 {
619 if((written_lock_byte == *psNdefMap->SendRecvBuf)
620 && (PH_FRINFC_TOPAZ_VAL1 == *psNdefMap->SendRecvLength))
621 {
622 written_lock_byte = 0;
623 /* Do nothing */
624 }
625 else
626 {
627 written_lock_byte = 0;
628 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
629 NFCSTATUS_INVALID_RECEIVE_LENGTH);
630 }
631 }
632 #endif /* #ifdef FRINFC_READONLY_NDEF */
633 case PH_FRINFC_TOPAZ_STATE_WRITE:
634 {
635 Status = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);
636 break;
637 }
638
639 case PH_FRINFC_TOPAZ_STATE_READID:
640 {
641 Status = phFriNfc_Tpz_H_ProReadID (psNdefMap);
642 break;
643 }
644
645 case PH_FRINFC_TOPAZ_STATE_READALL:
646 {
647 Status = phFriNfc_Tpz_H_ProReadAll (psNdefMap);
648 break;
649 }
650
651 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
652 {
653 Status = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);
654 break;
655 }
656
657 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
658 {
659 Status = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);
660 break;
661 }
662
663 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
664 {
665 Status = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);
666 break;
667 }
668
669 #ifdef TOPAZ_RF_ERROR_WORKAROUND
670
671 case PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ:
672 {
673 Status = phFriNfc_Tpz_H_CheckWrittenData (psNdefMap,
674 rf_error_state);
675 break;
676 }
677
678 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
679
680 default:
681 {
682 Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_MAP,
683 NFCSTATUS_INVALID_DEVICE_REQUEST);
684 break;
685 }
686 }
687 }
688 else
689 {
690 #ifdef TOPAZ_RF_ERROR_WORKAROUND
691
692 if ((FRINFC_RF_TIMEOUT_89 == PHNFCSTATUS (Status)) ||
693 (FRINFC_RF_TIMEOUT_90 == PHNFCSTATUS (Status)) ||
694 (NFCSTATUS_RF_TIMEOUT == PHNFCSTATUS (Status)))
695 {
696 uint8_t byte_number = 0;
697 uint8_t block_number = 0;
698
699 rf_error_state = psNdefMap->State;
700
701 #ifdef TOPAZ_RAW_SUPPORT
702
703 *psNdefMap->SendRecvBuf = PH_FRINFC_TOPAZ_CMD_READ;
704
705 #else
706
707 #ifdef PH_HAL4_ENABLE
708
709 psNdefMap->Cmd.JewelCmd = phHal_eJewel_Read1;
710
711 #else
712
713 psNdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelRead1;
714
715 #endif /* #ifdef PH_HAL4_ENABLE */
716
717 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
718
719 /* Update the state variable to the new work around state*/
720 psNdefMap->State = PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ;
721
722 /* Switch is used to know, if the error occured during WRITE or READ */
723 switch (rf_error_state)
724 {
725 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
726 {
727 /* Block and byte number is updated for NMN */
728 byte_number = PH_FRINFC_TOPAZ_VAL0;
729 block_number = PH_FRINFC_TOPAZ_VAL1;
730 break;
731 }
732
733 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
734 {
735 /* Get the L field of the TLV block */
736 block_number = (uint8_t)(((psNdefMap->TLVStruct.NdefTLVByte +
737 PH_FRINFC_TOPAZ_VAL1) >
738 PH_FRINFC_TOPAZ_VAL7)?
739 (psNdefMap->TLVStruct.NdefTLVBlock +
740 PH_FRINFC_TOPAZ_VAL1):
741 psNdefMap->TLVStruct.NdefTLVBlock);
742 /* Get the L byte */
743 byte_number = (uint8_t)((psNdefMap->TLVStruct.NdefTLVByte +
744 PH_FRINFC_TOPAZ_VAL1) %
745 PH_FRINFC_TOPAZ_VAL8);
746 break;
747 }
748
749 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
750 {
751 switch (psNdefMap->TopazContainer.InternalState)
752 {
753 case PH_FRINFC_TOPAZ_WR_CC_BYTE0:
754 {
755 /* Block and byte number is updated for the CC byte 0 */
756 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
757 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL0;
758 break;
759 }
760
761 case PH_FRINFC_TOPAZ_WR_CC_BYTE1:
762 {
763 /* Block and byte number is updated for the CC byte 1 */
764 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
765 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
766 break;
767 }
768
769 case PH_FRINFC_TOPAZ_WR_CC_BYTE2:
770 {
771 /* Block and byte number is updated for the CC byte 2 */
772 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
773 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL2;
774 break;
775 }
776
777 case PH_FRINFC_TOPAZ_WR_CC_BYTE3:
778 {
779 /* Block and byte number is updated for the CC byte 3 */
780 block_number = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
781 byte_number = (uint8_t)PH_FRINFC_TOPAZ_VAL3;
782 break;
783 }
784
785 case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
786 {
787 /* Block and byte number is updated for the Type field of the TLV */
788 block_number = psNdefMap->TLVStruct.NdefTLVBlock;
789 byte_number = (uint8_t)psNdefMap->TLVStruct.NdefTLVByte;
790 break;
791 }
792
793 default:
794 {
795 /* Do nothing */
796 break;
797 }
798 } /* switch (psNdefMap->TopazContainer.InternalState) */
799 break;
800 }
801
802 case PH_FRINFC_TOPAZ_STATE_WRITE:
803 {
804 /* Block and byte number is updated for the written error data */
805 block_number = psNdefMap->TopazContainer.CurrentBlock;
806 byte_number = psNdefMap->TopazContainer.ByteNumber;
807 break;
808 }
809
810 default:
811 {
812 /* Error occured is not during WRITE, so update
813 state variable to the previous state */
814 psNdefMap->State = rf_error_state;
815 break;
816 }
817 } /* switch (rf_error_state) */
818
819 /* The below check is added, to know if the error is for
820 the WRITE or READ scenario,
821 If the error is for READ, then state variable is not updated
822 If the error is for WRITE, then state variable is updated with
823 PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ value */
824 if (PH_FRINFC_TOPAZ_STATE_RF_ERROR_READ == psNdefMap->State)
825 {
826 /* Read the data with the updated block and byte number */
827 Status = phFriNfc_Tpz_H_RdBytes (psNdefMap, block_number,
828 byte_number);
829 }
830 }
831
832 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
833 }
834
835 /* Call Completion Routine, if Status != PENDING */
836 if (NFCSTATUS_PENDING != Status)
837 {
838 phFriNfc_Tpz_H_Complete(psNdefMap, Status);
839 }
840 }
841
842
843 #ifdef TOPAZ_RF_ERROR_WORKAROUND
844
845 static
846 NFCSTATUS
phFriNfc_Tpz_H_CheckWrittenData(phFriNfc_NdefMap_t * psNdefMap,uint8_t state_rf_error)847 phFriNfc_Tpz_H_CheckWrittenData (
848 phFriNfc_NdefMap_t *psNdefMap,
849 uint8_t state_rf_error)
850 {
851 NFCSTATUS result = NFCSTATUS_SUCCESS;
852
853 switch (state_rf_error)
854 {
855 case PH_FRINFC_TOPAZ_STATE_WRITE:
856 {
857 result = phFriNfc_Tpz_H_ProWrUsrData (psNdefMap);
858 break;
859 }
860
861 case PH_FRINFC_TOPAZ_STATE_WRITE_NMN:
862 {
863 result = phFriNfc_Tpz_H_ProWrNMN (psNdefMap);
864 break;
865 }
866
867 case PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV:
868 {
869 result = phFriNfc_Tpz_H_ProWrTLV (psNdefMap);
870 break;
871 }
872
873 case PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV:
874 {
875 result = phFriNfc_Tpz_H_ProCCTLV (psNdefMap);
876 break;
877 }
878
879 default:
880 {
881 break;
882 }
883 }
884
885 return result;
886 }
887
888
889 #endif /* #ifdef TOPAZ_RF_ERROR_WORKAROUND */
890
phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t * NdefMap,uint16_t BlockNo,uint16_t ByteNo)891 static NFCSTATUS phFriNfc_Tpz_H_RdBytes(phFriNfc_NdefMap_t *NdefMap,
892 uint16_t BlockNo,
893 uint16_t ByteNo)
894 {
895 NFCSTATUS Result = NFCSTATUS_SUCCESS;
896 #ifdef TOPAZ_RAW_SUPPORT
897 uint8_t index = 0;
898 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
899
900 /* set the data for additional data exchange*/
901 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
902 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
903 NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
904
905 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;
906 NdefMap->MapCompletionInfo.Context = NdefMap;
907
908 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
909
910 /* Depending on the jewel command, the send length is decided */
911 #ifdef TOPAZ_RAW_SUPPORT
912 switch(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0])
913 #else
914 switch(NdefMap->Cmd.JewelCmd)
915 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
916 {
917
918 #ifdef TOPAZ_RAW_SUPPORT
919 case PH_FRINFC_TOPAZ_CMD_READID:
920 #else
921 #ifdef PH_HAL4_ENABLE
922 case phHal_eJewel_RID:
923 #else
924 case phHal_eJewelCmdListJewelRid:
925 #endif
926 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
927
928 #ifdef TOPAZ_RAW_SUPPORT
929 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
930 /*Copy command to Send Buffer*/
931 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READID;
932 index ++;
933
934 /*Copy UID of the tag to Send Buffer*/
935 (void)memset(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1]),
936 0x00,(0x06));
937 index = index + 0x06;
938
939 /* Update the length of the command buffer*/
940 NdefMap->SendLength = index;
941 #else
942 /* For READ ID and READ ALL, send length is 0 */
943 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
944 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
945 break;
946
947 #ifdef TOPAZ_RAW_SUPPORT
948 case PH_FRINFC_TOPAZ_CMD_READALL:
949 #else
950 #ifdef PH_HAL4_ENABLE
951 case phHal_eJewel_ReadAll:
952 #else
953 case phHal_eJewelCmdListJewelReadAll:
954 #endif
955 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
956
957 #ifdef TOPAZ_RAW_SUPPORT
958 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
959 /*Copy command to Send Buffer*/
960 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
961 index ++;
962
963 /*Copy 0x00 to Send Buffer*/
964 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00;
965 index ++;
966 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;
967 index ++;
968
969 /*Copy UID of the tag to Send Buffer*/
970 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),
971 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),
972 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
973
974 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
975
976 /* Update the length of the command buffer*/
977 NdefMap->SendLength = index;
978 #else
979 /* For READ ID and READ ALL, send length is 0 */
980 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL0;
981 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
982 break;
983
984 #ifdef TOPAZ_RAW_SUPPORT
985 case PH_FRINFC_TOPAZ_CMD_READ:
986 #else
987 #ifdef PH_HAL4_ENABLE
988 case phHal_eJewel_Read1:
989 #else
990 case phHal_eJewelCmdListJewelRead1:
991 #endif
992
993 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
994
995 #ifdef TOPAZ_RAW_SUPPORT
996 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
997 /*Copy command to Send Buffer*/
998 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READ;
999 index ++;
1000
1001 /*Copy Address to Send Buffer*/
1002 /* Calculate send length
1003 7 | 6 5 4 3 | 2 1 0 |
1004 | block no | byte no |
1005 */
1006 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] =
1007 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1008 ByteNo);
1009 index ++;
1010 /*Copy 0x00 to Send Buffer*/
1011 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 0x00;
1012 index ++;
1013
1014 /*Copy UID of the tag to Send Buffer*/
1015 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),
1016 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),
1017 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1018 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1019
1020 /* Update the length of the command buffer*/
1021 NdefMap->SendLength = index;
1022 #else
1023 /* Calculate send length
1024 7 | 6 5 4 3 | 2 1 0 |
1025 | block no | byte no |
1026 */
1027 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] =
1028 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1029 ByteNo);
1030 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL1;
1031 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1032
1033 break;
1034 #ifdef TOPAZ_RAW_SUPPORT
1035 #else
1036 #ifdef PH_HAL4_ENABLE
1037 case phHal_eJewel_Read:
1038 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = 0x00;
1039 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] = 0x00;
1040 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2] = 104;
1041 NdefMap->SendLength = 3;
1042 break;
1043 #endif
1044 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1045
1046 default:
1047 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1048 NFCSTATUS_INVALID_DEVICE_REQUEST);
1049 }
1050
1051 if(Result == NFCSTATUS_SUCCESS)
1052 {
1053 /* Call the Overlapped HAL Transceive function */
1054 Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1055 &NdefMap->MapCompletionInfo,
1056 NdefMap->psRemoteDevInfo,
1057 NdefMap->Cmd,
1058 &NdefMap->psDepAdditionalInfo,
1059 NdefMap->SendRecvBuf,
1060 NdefMap->SendLength,
1061 NdefMap->SendRecvBuf,
1062 NdefMap->SendRecvLength);
1063 }
1064 return Result;
1065 }
1066
phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t * NdefMap,uint16_t BlockNo,uint16_t ByteNo,uint8_t ByteVal)1067 static NFCSTATUS phFriNfc_Tpz_H_WrAByte(phFriNfc_NdefMap_t *NdefMap,
1068 uint16_t BlockNo,
1069 uint16_t ByteNo,
1070 uint8_t ByteVal
1071 )
1072 {
1073 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1074 uint8_t index = 0;
1075
1076
1077 PHNFC_UNUSED_VARIABLE(ByteVal);
1078 /* set the data for additional data exchange*/
1079 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = PH_FRINFC_TOPAZ_VAL0;
1080 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = PH_FRINFC_TOPAZ_VAL0;
1081 NdefMap->psDepAdditionalInfo.NAD = PH_FRINFC_TOPAZ_VAL0;
1082
1083 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_TopazMap_Process;
1084 NdefMap->MapCompletionInfo.Context = NdefMap;
1085
1086 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1087 /* Command used to write 1 byte */
1088 #ifdef TOPAZ_RAW_SUPPORT
1089 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1090 #else
1091 #ifdef PH_HAL4_ENABLE
1092 NdefMap->Cmd.JewelCmd = phHal_eJewel_Write1E;
1093 #else
1094 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelWriteErase1;
1095 #endif
1096 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1097
1098 #ifdef TOPAZ_RAW_SUPPORT
1099 /*Copy command to Send Buffer*/
1100 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_WRITE_1E;
1101 index ++;
1102
1103 /*Copy Address to Send Buffer*/
1104 /* Calculate send length
1105 7 | 6 5 4 3 | 2 1 0 |
1106 | block no | byte no |
1107 */
1108 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL1] =
1109 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1110 ByteNo);
1111 index ++;
1112 /*Copy Data byte to Send Buffer*/
1113 NdefMap->SendRecvBuf[index] = ByteVal;
1114 index ++;
1115
1116 /*Copy UID of the tag to Send Buffer*/
1117 (void)memcpy(&(NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL3]),
1118 &(NdefMap->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid),
1119 TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1120 index = (uint8_t)(index + TOPAZ_UID_LENGTH_FOR_READ_WRITE);
1121
1122 /* Update the length of the command buffer*/
1123 NdefMap->SendLength = index;
1124
1125 #else
1126 /* Depending on the jewel command, the send length is decided */
1127 /* Calculate send length
1128 7 | 6 5 4 3 | 2 1 0 |
1129 | block no | byte no |
1130 */
1131 NdefMap->SendRecvBuf[index] =
1132 (uint8_t)((BlockNo << PH_FRINFC_TOPAZ_SHIFT3) +
1133 ByteNo);
1134 index ++;
1135 NdefMap->SendRecvBuf[index] = ByteVal;
1136 index ++;
1137 NdefMap->SendLength = PH_FRINFC_TOPAZ_VAL2;
1138
1139 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1140
1141 /* Call the Overlapped HAL Transceive function */
1142 Result = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1143 &NdefMap->MapCompletionInfo,
1144 NdefMap->psRemoteDevInfo,
1145 NdefMap->Cmd,
1146 &NdefMap->psDepAdditionalInfo,
1147 NdefMap->SendRecvBuf,
1148 NdefMap->SendLength,
1149 NdefMap->SendRecvBuf,
1150 NdefMap->SendRecvLength);
1151
1152 return Result;
1153 }
1154
phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t * NdefMap)1155 static NFCSTATUS phFriNfc_Tpz_H_ProReadID(phFriNfc_NdefMap_t *NdefMap)
1156 {
1157 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1158 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1159
1160 if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] &
1161 PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) &&
1162 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL6))
1163 {
1164 /* Copy UID to the context, Used when the READ ALL command is used */
1165 (void)memcpy(NdefMap->TopazContainer.UID,
1166 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
1167 PH_FRINFC_TOPAZ_VAL4);
1168
1169 /* State has to be changed */
1170 NdefMap->State = PH_FRINFC_TOPAZ_STATE_READALL;
1171 /* Topaz command = READALL */
1172 #ifdef TOPAZ_RAW_SUPPORT
1173 NdefMap->Cmd.JewelCmd = phHal_eJewel_Raw;
1174 NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] = PH_FRINFC_TOPAZ_CMD_READALL;
1175 #else
1176 #ifdef PH_HAL4_ENABLE
1177 NdefMap->Cmd.JewelCmd = phHal_eJewel_ReadAll;
1178 #else
1179 NdefMap->Cmd.JewelCmd = phHal_eJewelCmdListJewelReadAll;
1180 #endif
1181 #endif /* #ifdef TOPAZ_RAW_SUPPORT */
1182
1183 /* Read all bytes from the card */
1184 Result = phFriNfc_Tpz_H_RdBytes(NdefMap, NdefMap->TopazContainer.CurrentBlock,
1185 NdefMap->TopazContainer.ByteNumber);
1186 }
1187
1188 return Result;
1189 }
1190
phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t * NdefMap)1191 static NFCSTATUS phFriNfc_Tpz_H_ProReadAll(phFriNfc_NdefMap_t *NdefMap)
1192 {
1193 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1194 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1195 int32_t memcompare = PH_FRINFC_TOPAZ_VAL0;
1196
1197 /* Compare the UID of READ ALL command with the stored UID */
1198 #ifdef PH_HAL4_ENABLE
1199 if ((NdefMap->TopazContainer.UID[0] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2]) &&
1200 (NdefMap->TopazContainer.UID[1] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 1]) &&
1201 (NdefMap->TopazContainer.UID[2] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 2]) &&
1202 (NdefMap->TopazContainer.UID[3] == NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2 + 3]))
1203 {
1204 memcompare = PH_FRINFC_TOPAZ_VAL0;
1205 }
1206 else
1207 {
1208 memcompare = PH_FRINFC_TOPAZ_VAL1;
1209 }
1210 #else
1211 memcompare = memcmp(NdefMap->TopazContainer.UID,
1212 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL2],
1213 PH_FRINFC_TOPAZ_VAL4);
1214 #endif /* #ifdef PH_HAL4_ENABLE */
1215
1216 if(((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] &
1217 PH_FRINFC_TOPAZ_HEADROM0_CHK) == PH_FRINFC_TOPAZ_HEADROM0_VAL) &&
1218 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_READALL_RESP) &&
1219 (memcompare == PH_FRINFC_TOPAZ_VAL0))
1220 {
1221 /* Copy 96 bytes from the read/write memory space */
1222 (void)memcpy(NdefMap->TopazContainer.ReadBuffer,
1223 &NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL10],
1224 PH_FRINFC_TOPAZ_TOTAL_RWBYTES);
1225
1226 /* Check the lock bits and set the card state */
1227 phFriNfc_Tpz_H_ChkLockBits(NdefMap);
1228
1229 Result = phFriNfc_Tpz_H_CallNxtOp(NdefMap);
1230 }
1231 return Result;
1232 }
1233
phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t * NdefMap)1234 static NFCSTATUS phFriNfc_Tpz_H_CallNxtOp(phFriNfc_NdefMap_t *NdefMap)
1235 {
1236 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1237 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1238 /* Depending on the operation (check, read or write ndef), process the
1239 read data */
1240 switch(NdefMap->PrevOperation)
1241 {
1242 case PH_FRINFC_NDEFMAP_CHECK_OPE:
1243 /* Check the capabilty container values, according
1244 to the spec */
1245 Result = phFriNfc_Tpz_H_ChkCCinChkNdef(NdefMap);
1246
1247 if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_INVALID)
1248 {
1249 /* Check the spec version */
1250 Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap,
1251 NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]);
1252 /* Check the CC header size: Only valid ones are
1253 0x0C for 96 bytes. */
1254 if ((Result == NFCSTATUS_SUCCESS) &&
1255 ( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] <=
1256 PH_FRINFC_TOPAZ_CC_BYTE2_MAX))
1257 {
1258 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap);
1259 /* As there is possibility of either having or not having TLV in
1260 Topaz, no need to send the Actual status to the context*/
1261 Result = NFCSTATUS_SUCCESS;
1262 }
1263 }
1264 else
1265 {
1266 Result = NFCSTATUS_SUCCESS;
1267 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INITIALIZED;
1268 NdefMap->CardMemSize =
1269 NdefMap->TopazContainer.RemainingSize = (uint16_t)
1270 /*
1271 4 is decremented from the max size because of the 4 CC bytes
1272 2 is decremented because of the NDEF TLV T and L byte
1273 to get the actual data size
1274 */
1275 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4 -
1276 PH_FRINFC_TOPAZ_VAL2);
1277 }
1278 break;
1279
1280 case PH_FRINFC_NDEFMAP_READ_OPE:
1281 /* Check the capabilty container values, according
1282 to the spec */
1283 Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);
1284
1285 /* If success, find the ndef TLV */
1286 Result = ((Result != NFCSTATUS_SUCCESS)?
1287 (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1288 NFCSTATUS_INVALID_FORMAT)):
1289 phFriNfc_Tpz_H_findNDEFTLV(NdefMap));
1290
1291 if(Result == NFCSTATUS_SUCCESS)
1292 {
1293 NdefMap->TopazContainer.ByteNumber += PH_FRINFC_TOPAZ_VAL2;
1294 /* If success, copy the read bytes to the user buffer */
1295 Result = phFriNfc_Tpz_H_CpDataToUsrBuf(NdefMap);
1296 }
1297 break;
1298
1299 case PH_FRINFC_NDEFMAP_WRITE_OPE:
1300 default:
1301 if((NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE) ||
1302 (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED))
1303 {
1304 /* Check the capabilty container values, according
1305 to the spec */
1306 Result = phFriNfc_Tpz_H_ChkCCBytes(NdefMap);
1307 if(Result == NFCSTATUS_SUCCESS)
1308 {
1309 /* Find the NDEF TLV */
1310 Result = phFriNfc_Tpz_H_findNDEFTLV(NdefMap);
1311
1312 /* Write the TLV */
1313 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;
1314 }
1315 else
1316 {
1317 NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4;
1318 NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1;
1319 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4;
1320 /* Write the TLV */
1321 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE0;
1322 }
1323 /* Write CC bytes */
1324 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1325 }
1326 break;
1327 }
1328 return Result;
1329 }
1330
phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t * NdefMap)1331 static NFCSTATUS phFriNfc_Tpz_H_ChkCCBytes(phFriNfc_NdefMap_t *NdefMap)
1332 {
1333 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1334 NFCSTATUS_NO_NDEF_SUPPORT);
1335
1336 if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] ==
1337 PH_FRINFC_TOPAZ_CC_BYTE0)
1338 {
1339 /* Check the spec version */
1340 Result = phFriNfc_Tpz_H_ChkSpcVer( NdefMap,
1341 NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL1]);
1342 /* Check the CC header size: Only valid ones are
1343 0x0C for 96 bytes. */
1344 Result = ((( NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL2] >
1345 PH_FRINFC_TOPAZ_CC_BYTE2_MAX) || (Result !=
1346 NFCSTATUS_SUCCESS))?
1347 (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1348 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED)):
1349 Result);
1350
1351 /* Get the read/write card memory size */
1352 NdefMap->TopazContainer.RemainingSize =
1353 NdefMap->CardMemSize = ((Result == NFCSTATUS_SUCCESS)?
1354 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4):
1355 NdefMap->CardMemSize);
1356
1357 /* if the call is from write ndef then check for read write access */
1358 if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) &&
1359 (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] !=
1360 PH_FRINFC_TOPAZ_CC_BYTE3_RW) && (Result == NFCSTATUS_SUCCESS)))
1361 {
1362 Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1363 NFCSTATUS_INVALID_FORMAT));
1364 }
1365
1366 /* if the call is from read ndef then check for read only or read write access */
1367 if(((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) &&
1368 ((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] !=
1369 PH_FRINFC_TOPAZ_CC_BYTE3_RW) &&
1370 (NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] !=
1371 PH_FRINFC_TOPAZ_CC_BYTE3_RO))&& (Result == NFCSTATUS_SUCCESS)))
1372 {
1373 Result = (PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1374 NFCSTATUS_INVALID_FORMAT));
1375 }
1376 }
1377 return Result;
1378 }
1379
phFriNfc_Tpz_H_ChkSpcVer(phFriNfc_NdefMap_t * NdefMap,uint8_t VersionNo)1380 extern NFCSTATUS phFriNfc_Tpz_H_ChkSpcVer( phFriNfc_NdefMap_t *NdefMap,
1381 uint8_t VersionNo)
1382 {
1383 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1384 uint8_t TagVerNo = VersionNo;
1385
1386 /* To remove "warning (VS C4100) : unreferenced formal parameter" */
1387 PHNFC_UNUSED_VARIABLE(NdefMap);
1388
1389 if ( TagVerNo == 0 )
1390 {
1391 /*Return Status Error � Invalid Format�*/
1392 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
1393 }
1394 else
1395 {
1396 /* calculate the major and minor version number of T3VerNo */
1397 if( (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM ==
1398 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&&
1399 ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM >=
1400 PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo))) ||
1401 (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM ==
1402 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo ) )&&
1403 ( PH_NFCFRI_NDEFMAP_NFCDEV_MINOR_VER_NUM <
1404 PH_NFCFRI_NDEFMAP_GET_MINOR_TAG_VERNO(TagVerNo) )))
1405 {
1406 Result = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
1407 }
1408 else
1409 {
1410 if (( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM <
1411 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo) ) ||
1412 ( PH_NFCFRI_NDEFMAP_NFCDEV_MAJOR_VER_NUM >
1413 PH_NFCFRI_NDEFMAP_GET_MAJOR_TAG_VERNO(TagVerNo)))
1414 {
1415 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
1416 }
1417 }
1418 }
1419 return Result;
1420 }
1421
phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t * NdefMap)1422 static NFCSTATUS phFriNfc_Tpz_H_findNDEFTLV(phFriNfc_NdefMap_t *NdefMap)
1423 {
1424 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1425 NFCSTATUS_NO_NDEF_SUPPORT);
1426 uint8_t index = PH_FRINFC_TOPAZ_VAL4;
1427
1428 /* If remaining size is less than 3 then, there cant be any
1429 TLV present in the card */
1430 while((index < PH_FRINFC_TOPAZ_TOTAL_RWBYTES) &&
1431 (NdefMap->TopazContainer.RemainingSize >= PH_FRINFC_TOPAZ_VAL3))
1432 {
1433 switch(NdefMap->TopazContainer.ReadBuffer[index])
1434 {
1435 case PH_FRINFC_TOPAZ_NDEF_T:
1436 /* To get the length field of the TLV */
1437 index++;
1438 /* Type and length are not data bytes, so to know the exact
1439 remaining size in the card, the below operation is done */
1440 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2;
1441 /* Set the card state depending on the L value */
1442 Result = phFriNfc_MapTool_SetCardState(NdefMap,
1443 (uint32_t)NdefMap->TopazContainer.ReadBuffer[index]);
1444 /* Check the TLV is correct */
1445 if((NdefMap->TopazContainer.ReadBuffer[index] >
1446 NdefMap->TopazContainer.RemainingSize) ||
1447 ((NdefMap->TopazContainer.ReadBuffer[index] ==
1448 PH_FRINFC_TOPAZ_VAL0) && (NdefMap->PrevOperation ==
1449 PH_FRINFC_NDEFMAP_READ_OPE)) || (Result != NFCSTATUS_SUCCESS))
1450 {
1451 /* L field value cant be greater than the remaining size, so error */
1452 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1453 NFCSTATUS_NO_NDEF_SUPPORT);
1454 /* To break out of the loop */
1455 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1456 }
1457 else
1458 {
1459 /* So remaining size also changes, according to the position of NDEF TLV */
1460 NdefMap->TLVStruct.BytesRemainLinTLV =
1461 NdefMap->TopazContainer.ReadBuffer[index];
1462
1463 /* Get the byte number */
1464 NdefMap->TLVStruct.NdefTLVByte = (uint16_t)((index - PH_FRINFC_TOPAZ_VAL1) %
1465 PH_FRINFC_TOPAZ_VAL8);
1466 /* Get the block number */
1467 NdefMap->TLVStruct.NdefTLVBlock = (uint8_t)(((index - PH_FRINFC_TOPAZ_VAL1) /
1468 PH_FRINFC_TOPAZ_VAL8) +
1469 PH_FRINFC_TOPAZ_VAL1);
1470 /* TLV found flag is set */
1471 NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_TOPAZ_FLAG1;
1472 /* To know the position of V field in the TLV */
1473 NdefMap->TopazContainer.ByteNumber = (uint8_t)(((NdefMap->TLVStruct.NdefTLVBlock - 1) * 8) +
1474 NdefMap->TLVStruct.NdefTLVByte);
1475 /* To break out of the loop */
1476 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1477 Result = NFCSTATUS_SUCCESS;
1478 }
1479 break;
1480
1481 case PH_FRINFC_TOPAZ_NULL_T:
1482 /* Null TLV, Skip the TLV */
1483 NdefMap->TopazContainer.RemainingSize--;
1484 index++;
1485 break;
1486
1487 case PH_FRINFC_TOPAZ_TERM_T:
1488 /* No more TLV present in the card, so error */
1489 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1490 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1491 NFCSTATUS_NO_NDEF_SUPPORT);
1492 break;
1493
1494 default:
1495 /* Go till the length field of the TLV */
1496 index++;
1497 /* Type and length is not the data, so to know the exact
1498 remaining size in the card, the below operation is done */
1499 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL2;
1500 if(NdefMap->TopazContainer.ReadBuffer[index] >
1501 NdefMap->TopazContainer.RemainingSize)
1502 {
1503 /* L field value cant be greater than the remaining size, so error */
1504 index = PH_FRINFC_TOPAZ_TOTAL_RWBYTES;
1505 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1506 NFCSTATUS_NO_NDEF_SUPPORT);
1507 }
1508 else
1509 {
1510 /* Remaining size of the free space available in the card changes,
1511 according to the position of NDEF TLV */
1512 NdefMap->TopazContainer.RemainingSize =
1513 NdefMap->TopazContainer.RemainingSize -
1514 NdefMap->TopazContainer.ReadBuffer[index];
1515
1516 /* Get the position of the next TLV */
1517 index = (uint8_t)(index +
1518 (NdefMap->TopazContainer.ReadBuffer[index] +
1519 PH_FRINFC_TOPAZ_VAL1));
1520 }
1521 break;
1522 }
1523 }
1524
1525 /* If no Ndef TLV found and operation done is read */
1526 if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) &&
1527 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE))
1528 {
1529 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1530 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
1531 }
1532 if((NdefMap->TLVStruct.NdefTLVFoundFlag == PH_FRINFC_TOPAZ_FLAG0) &&
1533 ((NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) ||
1534 (NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_CHECK_OPE)))
1535 {
1536 NdefMap->TLVStruct.NdefTLVByte = PH_FRINFC_TOPAZ_VAL4;
1537 NdefMap->TLVStruct.NdefTLVBlock = PH_FRINFC_TOPAZ_VAL1;
1538 NdefMap->TopazContainer.ByteNumber = PH_FRINFC_TOPAZ_VAL4;
1539 NdefMap->TopazContainer.RemainingSize = PH_FRINFC_TOPAZ_TOTAL_RWBYTES1;
1540 }
1541 return Result;
1542 }
1543
phFriNfc_Tpz_H_CpDataToUsrBuf(phFriNfc_NdefMap_t * NdefMap)1544 static NFCSTATUS phFriNfc_Tpz_H_CpDataToUsrBuf(phFriNfc_NdefMap_t *NdefMap)
1545 {
1546 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1547
1548 /* Check the the TLV size and the user size */
1549 if(NdefMap->ApduBufferSize >=
1550 NdefMap->TLVStruct.BytesRemainLinTLV)
1551 {
1552 /* Copy the read bytes to user buffer till the value (V)
1553 of TLV ends */
1554 (void)memcpy(NdefMap->ApduBuffer,
1555 &(NdefMap->TopazContainer.ReadBuffer[
1556 NdefMap->TopazContainer.ByteNumber]),
1557 NdefMap->TLVStruct.BytesRemainLinTLV);
1558
1559 /* Update the number of read bytes to the user */
1560 *(NdefMap->NumOfBytesRead) =
1561 NdefMap->TLVStruct.BytesRemainLinTLV;
1562 /* There is no byte to read */
1563 NdefMap->TopazContainer.ByteNumber =
1564 PH_FRINFC_TOPAZ_VAL0;
1565 /* No further read is possible */
1566 NdefMap->TopazContainer.ReadWriteCompleteFlag =
1567 PH_FRINFC_TOPAZ_FLAG1;
1568 /* Remaining size in the card can be greater than length field in
1569 the TLV */
1570 NdefMap->TopazContainer.RemainingSize =
1571 NdefMap->TopazContainer.RemainingSize -
1572 NdefMap->TLVStruct.BytesRemainLinTLV;
1573 /* TLV has been completely read, no more bytes to read */
1574 NdefMap->TLVStruct.BytesRemainLinTLV =
1575 PH_FRINFC_TOPAZ_VAL0;
1576 }
1577 else
1578 {
1579 /* Copy read bytes till the user buffer size */
1580 (void)memcpy(NdefMap->ApduBuffer,
1581 &(NdefMap->TopazContainer.ReadBuffer[
1582 NdefMap->TopazContainer.ByteNumber]),
1583 NdefMap->ApduBufferSize);
1584
1585 /* Update the number of read bytes to the user */
1586 *(NdefMap->NumOfBytesRead) =
1587 NdefMap->ApduBufferSize;
1588 /* Get the next byte number to read */
1589 NdefMap->TopazContainer.ByteNumber =
1590 (uint8_t)(NdefMap->TopazContainer.ByteNumber +
1591 NdefMap->ApduBufferSize);
1592 /* Free space left in the card */
1593 NdefMap->TopazContainer.RemainingSize
1594 = NdefMap->TopazContainer.RemainingSize
1595 - (uint16_t)NdefMap->ApduBufferSize;
1596 /* Bytes left in the TLV */
1597 NdefMap->TLVStruct.BytesRemainLinTLV =
1598 NdefMap->TLVStruct.BytesRemainLinTLV -
1599 (uint16_t)NdefMap->ApduBufferSize;
1600 }
1601 return Result;
1602 }
1603
phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t * NdefMap)1604 static NFCSTATUS phFriNfc_Tpz_H_ProWrNMN(phFriNfc_NdefMap_t *NdefMap)
1605 {
1606 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1607 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1608 uint8_t BlockNo = PH_FRINFC_TOPAZ_VAL0,
1609 ByteNo = PH_FRINFC_TOPAZ_VAL0;
1610
1611 if((NdefMap->TopazContainer.InternalState ==
1612 PH_FRINFC_TOPAZ_WR_NMN_0) &&
1613 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1614 PH_FRINFC_TOPAZ_VAL0) &&
1615 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1616 {
1617 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV;
1618 /* Get the L field of the TLV block */
1619 BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) >
1620 PH_FRINFC_TOPAZ_VAL7)?
1621 (NdefMap->TLVStruct.NdefTLVBlock + PH_FRINFC_TOPAZ_VAL1):
1622 NdefMap->TLVStruct.NdefTLVBlock);
1623 /* Get the L byte */
1624 ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte + PH_FRINFC_TOPAZ_VAL1) %
1625 PH_FRINFC_TOPAZ_VAL8);
1626
1627
1628 /* Here the NMN is written 0, so internal state is used */
1629 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV_0;
1630 /* Write the length value = 0x00 , Write L field of TLV = 0 inside this*/
1631 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,
1632 PH_FRINFC_TOPAZ_VAL0);
1633 }
1634 else
1635 {
1636 if((NdefMap->TopazContainer.InternalState ==
1637 PH_FRINFC_TOPAZ_WR_NMN_E1) &&
1638 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1639 PH_FRINFC_TOPAZ_CC_BYTE0) &&
1640 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1641 {
1642 /* Card state is initialised or invalid */
1643 NdefMap->CardState = (uint8_t)((NdefMap->CardState ==
1644 PH_NDEFMAP_CARD_STATE_INITIALIZED)?
1645 PH_NDEFMAP_CARD_STATE_READ_WRITE:
1646 NdefMap->CardState);
1647 /* update the length to the user */
1648 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
1649 Result = NFCSTATUS_SUCCESS;
1650 }
1651 }
1652 return Result;
1653 }
1654
phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t * NdefMap)1655 static NFCSTATUS phFriNfc_Tpz_H_ProWrTLV(phFriNfc_NdefMap_t *NdefMap)
1656 {
1657 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1658 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1659 if((NdefMap->TopazContainer.InternalState ==
1660 PH_FRINFC_TOPAZ_WR_L_TLV_0) &&
1661 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1662 PH_FRINFC_TOPAZ_VAL0) &&
1663 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1664 {
1665 /* state is writing user data to the card */
1666 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1667
1668 NdefMap->TopazContainer.ByteNumber++;
1669 /* Check the byte number */
1670 phFriNfc_Tpz_H_BlkChk(NdefMap);
1671
1672 /* Write data to the specified location */
1673 /* Write the data to the card from the user buffer */
1674 Result = phFriNfc_Tpz_H_WrAByte( NdefMap,
1675 NdefMap->TopazContainer.CurrentBlock,
1676 NdefMap->TopazContainer.ByteNumber,
1677 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]
1678 );
1679 }
1680 else
1681 {
1682 if((NdefMap->TopazContainer.InternalState ==
1683 PH_FRINFC_TOPAZ_WR_L_TLV) &&
1684 (((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) &&
1685 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1686 NdefMap->ApduBuffIndex)) ||
1687 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
1688 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1689 (NdefMap->ApduBuffIndex + NdefMap->TLVStruct.BytesRemainLinTLV)))) &&
1690 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1691 {
1692 /* Update the L value in the context */
1693 NdefMap->TLVStruct.BytesRemainLinTLV =
1694 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
1695 NdefMap->ApduBuffIndex:
1696 (NdefMap->TLVStruct.BytesRemainLinTLV + NdefMap->ApduBuffIndex));
1697
1698 /* Write 0xE1 in block number = 1 and byte number = 0 */
1699 Result = phFriNfc_Tpz_H_WrByte0ValE1(NdefMap);
1700 }
1701 }
1702 return Result;
1703 }
1704
phFriNfc_Tpz_H_ProWrUsrData(phFriNfc_NdefMap_t * NdefMap)1705 static NFCSTATUS phFriNfc_Tpz_H_ProWrUsrData(phFriNfc_NdefMap_t *NdefMap)
1706 {
1707 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1708 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1709 /* send buffer should be equal to receive buffer */
1710 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1711 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]) &&
1712 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1713 {
1714 /* Increment the index */
1715 NdefMap->ApduBuffIndex += PH_FRINFC_TOPAZ_VAL1;
1716
1717 /* Remaining space left in the card is less by one */
1718 NdefMap->TopazContainer.RemainingSize -= PH_FRINFC_TOPAZ_VAL1;
1719
1720 /* Increment the byte number */
1721 NdefMap->TopazContainer.ByteNumber++;
1722
1723 /* Check the block number */
1724 phFriNfc_Tpz_H_BlkChk(NdefMap);
1725
1726 /* check for the user space or the card size */
1727 if((NdefMap->ApduBufferSize == NdefMap->ApduBuffIndex) ||
1728 (NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0))
1729 {
1730 /* Set write complete, if the end of card is reached */
1731 NdefMap->TopazContainer.ReadWriteCompleteFlag = (uint8_t)
1732 ((NdefMap->TopazContainer.RemainingSize == PH_FRINFC_TOPAZ_VAL0)?
1733 PH_FRINFC_TOPAZ_FLAG1:PH_FRINFC_TOPAZ_FLAG0);
1734
1735 Result = phFriNfc_Tpz_H_WrLByte(NdefMap);
1736 }
1737 else
1738 {
1739 /* State is continued to be in write */
1740 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE;
1741
1742 /* Write the byte to the specified location , and Byte to write */
1743 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, NdefMap->TopazContainer.CurrentBlock,
1744 NdefMap->TopazContainer.ByteNumber,
1745 NdefMap->ApduBuffer[NdefMap->ApduBuffIndex]
1746 );
1747 }
1748 }
1749 return Result;
1750 }
1751
phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t * NdefMap)1752 static NFCSTATUS phFriNfc_Tpz_H_WrLByte(phFriNfc_NdefMap_t *NdefMap)
1753 {
1754 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1755 uint8_t BlockNo = PH_FRINFC_TOPAZ_VAL0,
1756 ByteNo = PH_FRINFC_TOPAZ_VAL0;
1757 uint8_t TempByteVal = 0;
1758 BlockNo = (uint8_t)(((NdefMap->TLVStruct.NdefTLVByte +
1759 PH_FRINFC_TOPAZ_VAL1) >
1760 PH_FRINFC_TOPAZ_VAL7)?
1761 (NdefMap->TLVStruct.NdefTLVBlock +
1762 PH_FRINFC_TOPAZ_VAL1):
1763 NdefMap->TLVStruct.NdefTLVBlock);
1764
1765 ByteNo = (uint8_t)((NdefMap->TLVStruct.NdefTLVByte +
1766 PH_FRINFC_TOPAZ_VAL1) % PH_FRINFC_TOPAZ_VAL8);
1767 /* Update L field */
1768 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_L_TLV;
1769 /* Internal state for write */
1770 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_L_TLV;
1771 /* Update the length field depending on the offset */
1772 TempByteVal = (uint8_t)
1773 ((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN)?
1774 NdefMap->ApduBuffIndex:
1775 (NdefMap->ApduBuffIndex +
1776 NdefMap->TLVStruct.BytesRemainLinTLV));
1777 /* Write the L field */
1778 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, BlockNo, ByteNo,TempByteVal);
1779 return Result;
1780 }
1781
phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t * NdefMap)1782 static NFCSTATUS phFriNfc_Tpz_H_WrByte0ValE1(phFriNfc_NdefMap_t *NdefMap)
1783 {
1784 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1785
1786 /* Update L field */
1787 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN;
1788 /* Internal state for writing 0xE1 */
1789 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_E1;
1790 /* Update the length field depending on the offset */
1791 /* Write the L field */
1792 Result = phFriNfc_Tpz_H_WrAByte(NdefMap, PH_FRINFC_TOPAZ_VAL1,
1793 PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_CC_BYTE0);
1794 return Result;
1795 }
1796
phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t * NdefMap,NFCSTATUS Status)1797 static void phFriNfc_Tpz_H_Complete(phFriNfc_NdefMap_t *NdefMap,
1798 NFCSTATUS Status)
1799 {
1800 /* set the state back to the Reset_Init state*/
1801 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
1802
1803 /* set the completion routine*/
1804 NdefMap->CompletionRoutine[NdefMap->TopazContainer.CRIndex].
1805 CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
1806 }
1807
phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t * NdefMap)1808 static void phFriNfc_Tpz_H_BlkChk(phFriNfc_NdefMap_t *NdefMap)
1809 {
1810 NdefMap->TopazContainer.CurrentBlock =
1811 (uint8_t)((NdefMap->TopazContainer.ByteNumber >
1812 PH_FRINFC_TOPAZ_VAL7)?
1813 (NdefMap->TopazContainer.CurrentBlock +
1814 PH_FRINFC_TOPAZ_VAL1):
1815 NdefMap->TopazContainer.CurrentBlock);
1816
1817 NdefMap->TopazContainer.ByteNumber = (uint8_t)(NdefMap->TopazContainer.ByteNumber %
1818 PH_FRINFC_TOPAZ_VAL8);
1819 }
1820
phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t * NdefMap)1821 static NFCSTATUS phFriNfc_Tpz_H_ChkCCinChkNdef(phFriNfc_NdefMap_t *NdefMap)
1822 {
1823 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1824 NFCSTATUS_NO_NDEF_SUPPORT);
1825
1826 if(NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL0] ==
1827 PH_FRINFC_TOPAZ_CC_BYTE0)
1828 {
1829 /* Check the most significant nibble of byte 3 (RWA) = 0 */
1830 Result = (((NdefMap->TopazContainer.ReadBuffer[PH_FRINFC_TOPAZ_VAL3] &
1831 PH_FRINFC_TOPAZ_BYTE3_MSB)== PH_FRINFC_TOPAZ_VAL0)?
1832 NFCSTATUS_SUCCESS:
1833 Result);
1834
1835 /* Card size is initialised */
1836 NdefMap->CardMemSize = NdefMap->TopazContainer.RemainingSize =
1837 ((Result == NFCSTATUS_SUCCESS)?
1838 (PH_FRINFC_TOPAZ_MAX_CARD_SZ - PH_FRINFC_TOPAZ_VAL4):
1839 NdefMap->CardMemSize);
1840 }
1841
1842 if (NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY)
1843 {
1844 NdefMap->CardState = (uint8_t)((Result == NFCSTATUS_SUCCESS)?
1845 PH_NDEFMAP_CARD_STATE_INITIALIZED:
1846 PH_NDEFMAP_CARD_STATE_INVALID);
1847 }
1848
1849 return Result;
1850 }
1851
phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t * NdefMap)1852 static void phFriNfc_Tpz_H_ChkLockBits(phFriNfc_NdefMap_t *NdefMap)
1853 {
1854 /* Set the card state */
1855 NdefMap->CardState = (uint8_t)
1856 (((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_0] ==
1857 PH_FRINFC_TOPAZ_LOCKBIT_BYTE114) &&
1858 ((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] ==
1859 PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_1) ||
1860 (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_LOCKBIT_BYTENO_1] ==
1861 PH_FRINFC_TOPAZ_LOCKBIT_BYTE115_2)))?
1862 PH_NDEFMAP_CARD_STATE_READ_WRITE:
1863 PH_NDEFMAP_CARD_STATE_READ_ONLY);
1864
1865 /* Set the card state from CC bytes */
1866 if (NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_WRITE)
1867 {
1868 if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READWRITE)
1869 {
1870 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
1871 }
1872 else if (NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_CC_BYTENO_3] == PH_FRINFC_TOPAZ_CC_READONLY)
1873 {
1874 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
1875 }
1876 else
1877 {
1878 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
1879 }
1880 }
1881 }
1882
phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t * NdefMap)1883 static NFCSTATUS phFriNfc_Tpz_H_WrCCorTLV(phFriNfc_NdefMap_t *NdefMap)
1884 {
1885 NFCSTATUS Result = NFCSTATUS_SUCCESS;
1886 uint8_t ByteNo = PH_FRINFC_TOPAZ_VAL0,
1887 BlockNo = PH_FRINFC_TOPAZ_VAL0;
1888 uint8_t TempByteVal = 0;
1889 switch(NdefMap->TopazContainer.InternalState)
1890 {
1891 case PH_FRINFC_TOPAZ_WR_CC_BYTE0:
1892 /* To write the CC bytes */
1893 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE0;
1894 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL0;
1895 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1896 break;
1897
1898 case PH_FRINFC_TOPAZ_WR_CC_BYTE1:
1899 /* To write the CC bytes */
1900 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE1;
1901 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL1;
1902 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1903 break;
1904
1905 case PH_FRINFC_TOPAZ_WR_CC_BYTE2:
1906 /* To write the CC bytes */
1907 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE2_MAX;
1908 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL2;
1909 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1910 break;
1911
1912 case PH_FRINFC_TOPAZ_WR_CC_BYTE3:
1913 /* To write the CC bytes */
1914 TempByteVal = PH_FRINFC_TOPAZ_CC_BYTE3_RW;
1915 ByteNo = (uint8_t)PH_FRINFC_TOPAZ_VAL3;
1916 BlockNo = PH_FRINFC_TOPAZ_VAL1;
1917 break;
1918
1919 case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
1920 default:
1921 /* To write the NDEF TLV (if not present) */
1922 TempByteVal = PH_FRINFC_TOPAZ_NDEF_T;
1923 ByteNo = (uint8_t)NdefMap->TLVStruct.NdefTLVByte;
1924 BlockNo = NdefMap->TLVStruct.NdefTLVBlock;
1925 break;
1926 }
1927 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WR_CC_OR_TLV;
1928 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, BlockNo, ByteNo,TempByteVal);
1929 return Result;
1930 }
1931
phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t * NdefMap)1932 static NFCSTATUS phFriNfc_Tpz_H_ProCCTLV(phFriNfc_NdefMap_t *NdefMap)
1933 {
1934 NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1935 NFCSTATUS_INVALID_RECEIVE_LENGTH);
1936 switch(NdefMap->TopazContainer.InternalState)
1937 {
1938 case PH_FRINFC_TOPAZ_WR_CC_BYTE0:
1939 /* Process the CC byte */
1940 /* Check the response */
1941 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1942 PH_FRINFC_TOPAZ_CC_BYTE0) &&
1943 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1944 {
1945 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE1;
1946 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1947 }
1948 break;
1949
1950 case PH_FRINFC_TOPAZ_WR_CC_BYTE1:
1951 /* Process the CC byte */
1952 /* Check the response */
1953 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1954 PH_FRINFC_TOPAZ_CC_BYTE1) &&
1955 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1956 {
1957 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE2;
1958 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1959 }
1960 break;
1961
1962 case PH_FRINFC_TOPAZ_WR_CC_BYTE2:
1963 /* Process the CC byte */
1964 /* Check the response */
1965 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1966 PH_FRINFC_TOPAZ_CC_BYTE2_MAX) &&
1967 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1968 {
1969 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_CC_BYTE3;
1970 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1971 }
1972 break;
1973
1974 case PH_FRINFC_TOPAZ_WR_CC_BYTE3:
1975 /* Process the CC byte */
1976 /* Check the response */
1977 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1978 PH_FRINFC_TOPAZ_CC_BYTE3_RW) &&
1979 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1980 {
1981 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_T_OF_TLV;
1982 Result = phFriNfc_Tpz_H_WrCCorTLV(NdefMap);
1983 }
1984 break;
1985
1986 case PH_FRINFC_TOPAZ_WR_T_OF_TLV:
1987 default:
1988 /* Check the response */
1989 if((NdefMap->SendRecvBuf[PH_FRINFC_TOPAZ_VAL0] ==
1990 PH_FRINFC_TOPAZ_NDEF_T) &&
1991 (*NdefMap->SendRecvLength == PH_FRINFC_TOPAZ_VAL1))
1992 {
1993 /* Increment the Byte Number */
1994 NdefMap->TopazContainer.ByteNumber++;
1995 /* Check the block and byte number */
1996 phFriNfc_Tpz_H_BlkChk(NdefMap);
1997 /* Process the T of NDEF TLV */
1998 NdefMap->State = PH_FRINFC_TOPAZ_STATE_WRITE_NMN;
1999
2000 /* Here the NMN is written 0, so internal state is used */
2001 NdefMap->TopazContainer.InternalState = PH_FRINFC_TOPAZ_WR_NMN_0;
2002
2003 /*Inside this call Write NMN (block number 1 and byte number 0) = 0 */
2004 Result = phFriNfc_Tpz_H_WrAByte( NdefMap, PH_FRINFC_TOPAZ_VAL1,
2005 PH_FRINFC_TOPAZ_VAL0,PH_FRINFC_TOPAZ_VAL0);
2006 }
2007 break;
2008 }
2009 return Result;
2010 }
2011
2012 #ifdef UNIT_TEST
2013 #include <phUnitTestNfc_Topaz_static.c>
2014 #endif
2015
2016 #endif /* PH_FRINFC_MAP_TOPAZ_DISABLED */
2017