2 * Copyright (C) 2010 NXP Semiconductors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * \file phFriNfc_NdefRecord.c
19 * \brief NFC Ndef Record component file.
23 * $Date: Thu Jun 25 11:01:24 2009 $
26 * $Aliases: NFC_FRI1.1_WK926_R28_1,NFC_FRI1.1_WK928_R29_1,NFC_FRI1.1_WK930_R30_1,NFC_FRI1.1_WK934_PREP_1,NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $
31 /*! \ingroup grp_file_attributes
32 * \name \name NDEF Record Tools Header
34 * File: \ref phFriNfc_NdefRecord.h
38 #define PHFRINFCNDEFRECORD_FILEREVISION "$Revision: 1.4 $"
39 #define PHFRINFCNDEFRECORD_FILEALIASES "$Aliases: NFC_FRI1.1_WK926_R28_1,NFC_FRI1.1_WK928_R29_1,NFC_FRI1.1_WK930_R30_1,NFC_FRI1.1_WK934_PREP_1,NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $"
42 #include <phFriNfc_NdefRecord.h>
43 #include <phNfcCompId.h>
46 /* Harsha: To Fix: 0000358: phFriNfc_NdefRecord.h: includes should be moved */
52 * Get a specific NDEF record from the data, provided by the caller. The data is a buffer holding
53 * one or more (nested) NDEF records within a NDEF packet (received via the NFC link, for example).
55 * \param[in] Buffer The data buffer holding the NDEF Message, as provided by the caller.
56 * \param[in] BufferLength The data length, as provided by the caller.
57 * \param[in,out] RawRecords Array of pointers, receiving the references to the found Ndef Records
58 * in the Message. The caller has to provide the array of pointers.
59 * The array is filled with valid pointers up to the number of records
60 * found or the array size if the number of found records exceeds the size.
61 * If the value is NULL the function only yields the number of records
62 * without filling in pointers.
63 * \param[in] IsChunked This boolean tells the user that the record of a certain position within
64 * an array has the CHUNKED flag set (is a partial record). The number
65 * of caller-provided array positions has to be the same as "NumberOfRawRecords".
66 * In case that this parameter is NULL the function ignores it.
67 * \param[in,out] NumberOfRawRecords Length of the Record pointer array. The caller has to provide
68 * the number of pointers provided in the NDEF Type array. \n
69 * The value is set by the extracting function to the actual number of
70 * records found in the data. If the user specifies 0 (zero) the function
71 * only yields the number of records without filling in pointers.\n
72 * The value of NULL is invalid.
74 * \retval NFCSTATUS_SUCCESS Operation successful.
75 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
77 * \note The correct number of found records is returned by the function also in case that:
78 * - The "RawRecords" array is too short to hold all values: It is filled up to the allowed maximum.
79 * - The "RawRecords" array is NULL: Only the number is returned.
80 * - The "NumberOfRawRecords" parameter is 0 (zero): The array is not filled, just the number is returned.
82 * This can be exploited for targeted memory allocation: Specify NULL for "RawRecords" and/or
83 * 0 (zero) for "NumberOfRawRecords" and the function yields the correct array size to allocate
87 NFCSTATUS phFriNfc_NdefRecord_GetRecords( uint8_t *Buffer,
88 uint32_t BufferLength,
89 uint8_t *RawRecords[],
91 uint32_t *NumberOfRawRecords)
93 NFCSTATUS Status = NFCSTATUS_SUCCESS;
94 uint8_t PayloadLengthByte = 0,
98 NoOfRecordsReturnFlag = 0,
104 /* Validate the input parameters */
105 if (Buffer == NULL || BufferLength == 0 || NumberOfRawRecords == NULL)
107 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
108 NFCSTATUS_INVALID_PARAMETER);
112 if((*NumberOfRawRecords) > 0)
114 /* The number of caller-provided array positions for the array IsChunked
115 has to be the same as NumberOfRawRecords. Hence,
116 if NumberOfRawRecords > 0, the array IsChunked cannot be null */
117 if(IsChunked == NULL)
119 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
120 NFCSTATUS_INVALID_PARAMETER);
125 /* Check Raw Records input is NULL and Number of Raw records is 0*/
126 if ( RawRecords == NULL || *NumberOfRawRecords == 0)
128 /* This flag is set, to return only number of records
129 this is done when the Raw Records is NULL or
130 Number of Raw records is 0 */
131 NoOfRecordsReturnFlag = 1;
134 /* Check for the MB bit*/
135 if ((*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_MB) !=
136 PH_FRINFC_NDEFRECORD_FLAGS_MB )
139 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
140 NFCSTATUS_INVALID_FORMAT);
142 /* Number of valid records found in the message is 0 */
143 *NumberOfRawRecords = 0;
147 /* Check for Tnf bits 0x07 is reserved for future use */
148 if ((*Buffer & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) ==
149 PH_FRINFC_NDEFRECORD_TNF_RESERVED)
152 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
153 NFCSTATUS_INVALID_FORMAT);
154 /* Number of valid records found in the message is 0 */
155 *NumberOfRawRecords = 0;
159 /* Check the First Record(MB = 0) for TNF = 0x06(Unchanged) */
160 if ((*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_MB) == PH_FRINFC_NDEFRECORD_FLAGS_MB &&
161 (*Buffer & PH_FRINFC_NDEFRECORD_TNF_UNCHANGED) == PH_FRINFC_NDEFRECORD_TNF_UNCHANGED)
163 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
164 NFCSTATUS_INVALID_FORMAT);
165 /* Number of valid records found in the message is 0 */
166 *NumberOfRawRecords = 0;
170 /* First Record i.e., MB = 1, TNF != 0x05 and TypeLength = 0 */
171 if ( (*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_MB) == PH_FRINFC_NDEFRECORD_FLAGS_MB &&
172 (*Buffer & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) != PH_FRINFC_NDEFRECORD_TNF_UNKNOWN &&
173 (*Buffer & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) != PH_FRINFC_NDEFRECORD_TNF_EMPTY &&
176 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
177 NFCSTATUS_INVALID_FORMAT);
178 /* Number of valid records found in the message is 0 */
179 *NumberOfRawRecords = 0;
183 /* Check till Buffer Length exceeds */
184 while ( BytesTraversed < BufferLength )
186 /* For Each Record Check whether it contains the ME bit set and CF bit Set
187 if YES return ERROR*/
188 if ((*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_CF) ==
189 PH_FRINFC_NDEFRECORD_FLAGS_CF &&
190 (*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_ME) ==
191 PH_FRINFC_NDEFRECORD_FLAGS_ME)
193 /* CF and ME Error */
194 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
195 NFCSTATUS_INVALID_FORMAT);
199 if (NoOfRecordsReturnFlag == 0)
201 /* Harsha: Fix for 0000241: [gk], NDEF Tools: GetRecords() overshoots
202 a given array boundary if the number of records != 0. */
203 /* Actual Number of Records should not exceed Number of records
205 if(Count >= *NumberOfRawRecords)
209 /* To fix the mantis entry 0388 */
210 if(RawRecords!=NULL)/*QMOR FIX*/
212 RawRecords[Count] = Buffer;
216 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
217 NFCSTATUS_INVALID_PARAMETER);
222 /* To Calculate the IDLength and PayloadLength for
223 short or normal record */
224 Status = phFriNfc_NdefRecord_RecordIDCheck ( Buffer,
231 if (Status != NFCSTATUS_SUCCESS)
236 /* Check for the Chunk Flag */
237 if (NoOfRecordsReturnFlag == 0)
239 /* If NoOfRecordsReturnFlag = 0, that means we have enough space */
240 /* in the array IsChunked, to write */
241 if ((*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_CF) ==
242 PH_FRINFC_NDEFRECORD_FLAGS_CF)
244 IsChunked [Count] = PHFRINFCNDEFRECORD_CHUNKBIT_SET;
248 IsChunked [Count] = PHFRINFCNDEFRECORD_CHUNKBIT_SET_ZERO;
252 /* Check the record is not the first record */
255 /* Not a first record, if chunk record is present and IL bit is set
256 also if the MB bit is set */
257 if(((*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_CF) == PH_FRINFC_NDEFRECORD_FLAGS_CF &&
258 (*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_IL) == PH_FRINFC_NDEFRECORD_FLAGS_IL &&
259 (*Buffer & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) == PH_FRINFC_NDEFRECORD_TNF_UNCHANGED) ||
260 (*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_MB) == PH_FRINFC_NDEFRECORD_FLAGS_MB)
263 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
264 NFCSTATUS_INVALID_FORMAT);
268 /* Check for the Chunk Flag */
269 if (NoOfRecordsReturnFlag == 0)
271 /* If NoOfRecordsReturnFlag = 0, that means the array IsChunked
272 contains valid values. So, cannot check the value
273 of IsChunked if NoOfRecordsReturnFlag = 1. */
275 /* Check whether the previous record has the chunk flag and
276 TNF of present record is not 0x06 */
277 if (IsChunked [Count - 1] == PHFRINFCNDEFRECORD_CHUNKBIT_SET &&
278 (*Buffer & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) !=
279 PH_FRINFC_NDEFRECORD_TNF_UNCHANGED)
281 /* CF or TNF Error */
282 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
283 NFCSTATUS_INVALID_FORMAT);
287 /* Check whether the previous record doesnot have the chunk flag and
288 TNF of present record is 0x06 */
289 if (IsChunked [Count - 1] == PHFRINFCNDEFRECORD_CHUNKBIT_SET_ZERO &&
290 (*Buffer & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) ==
291 PH_FRINFC_NDEFRECORD_TNF_UNCHANGED)
293 /* CF or TNF Error */
294 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
295 NFCSTATUS_INVALID_FORMAT);
299 /* Check for the last chunk */
300 if (IsChunked [Count - 1] == PHFRINFCNDEFRECORD_CHUNKBIT_SET &&
301 IsChunked [Count] == PHFRINFCNDEFRECORD_CHUNKBIT_SET_ZERO)
303 /* Check for the TypeLength, IDLength = 0 */
304 if (TypeLength != 0 || IDLength != 0)
306 /* last chunk record Error */
307 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
308 NFCSTATUS_INVALID_FORMAT);
312 } /* if (NoOfRecordsReturnFlag == 0) */
313 } /* if (Count > 0) */
315 /* Calculate the bytes already traversed. */
316 BytesTraversed = (BytesTraversed + PayloadLengthByte + IDLengthByte + TypeLength
317 + IDLength + TypeLengthByte + PayloadLength
318 + PH_FRINFC_NDEFRECORD_BUF_INC1);
320 if(BytesTraversed == BufferLength)
322 /* We have reached the last record, and everything is fine. */
323 /* Check for the ME Byte */
324 if ((*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_ME) ==
325 PH_FRINFC_NDEFRECORD_FLAGS_ME)
332 /* Each message must have ME flag in the last record, Since
333 ME is not set raise an error */
334 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
335 NFCSTATUS_INVALID_FORMAT);
341 /* Buffer Overshoot: Inconsistency in the message length
342 and actual value of the bytes in the message detected.
344 if(BytesTraversed > BufferLength)
346 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
347 NFCSTATUS_INVALID_FORMAT);
351 /* For Each Record Check whether it contains the ME bit set
353 if ((*Buffer & PH_FRINFC_NDEFRECORD_FLAGS_ME) ==
354 PH_FRINFC_NDEFRECORD_FLAGS_ME)
360 /* +1 is for first byte */
361 Buffer = (Buffer + PayloadLengthByte + IDLengthByte + TypeLength
362 + TypeLengthByte + IDLength + PayloadLength
363 + PH_FRINFC_NDEFRECORD_BUF_INC1);
365 /* Increment the number of valid records found in the message */
369 /* Whatever is the error, update the NumberOfRawRecords with the number
370 of proper records found till the error was detected in the message. */
371 *NumberOfRawRecords = Count;
375 /* to check the bitfields in the Flags Byte and return the status flag */
376 static uint8_t phFriNfc_NdefRecord_NdefFlag(uint8_t Flags,uint8_t Mask)
378 uint8_t check_flag = 0x00;
379 check_flag = Flags & Mask;
383 uint32_t phFriNfc_NdefRecord_GetLength(phFriNfc_NdefRecord_t *Record)
385 uint32_t RecordLength=1;
388 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Tnf,PH_FRINFC_NDEFRECORD_TNFBYTE_MASK);
389 /* Type length is present only for following TNF
390 PH_FRINFC_NDEFRECORD_TNF_NFCWELLKNOWN
391 PH_FRINFC_NDEFRECORD_TNF_MEDIATYPE
392 PH_FRINFC_NDEFRECORD_TNF_ABSURI
393 PH_FRINFC_NDEFRECORD_TNF_NFCEXT
396 /* ++ is for the Type Length Byte */
398 if( FlagCheck != PH_FRINFC_NDEFRECORD_TNF_EMPTY &&
399 FlagCheck != PH_FRINFC_NDEFRECORD_TNF_UNKNOWN &&
400 FlagCheck != PH_FRINFC_NDEFRECORD_TNF_UNCHANGED )
402 RecordLength += Record->TypeLength;
405 /* to check if payloadlength is 8bit or 32bit*/
406 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Flags,PH_FRINFC_NDEFRECORD_FLAGS_SR);
409 /* ++ is for the Payload Length Byte */
410 RecordLength++;/* for short record*/
414 /* + PHFRINFCNDEFRECORD_NORMAL_RECORD_BYTE is for the Payload Length Byte */
415 RecordLength += PHFRINFCNDEFRECORD_NORMAL_RECORD_BYTE;/* for normal record*/
418 /* for non empty record */
419 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Tnf,PH_FRINFC_NDEFRECORD_TNFBYTE_MASK);
420 if(FlagCheck != PH_FRINFC_NDEFRECORD_TNF_EMPTY)
422 RecordLength += Record->PayloadLength;
425 /* ID and IDlength are present only if IL flag is set*/
426 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Flags,PH_FRINFC_NDEFRECORD_FLAGS_IL);
429 RecordLength +=Record->IdLength;
430 /* ++ is for the ID Length Byte */
438 * Extract a specific NDEF record from the data, provided by the caller. The data is a buffer holding
439 * at least the entire NDEF record (received via the NFC link, for example).
441 * \param[out] Record The NDEF record structure. The storage for the structure has to be provided by the
442 * caller matching the requirements for \b Extraction, as described in the compound
444 * \param[in] RawRecord The Pointer to the buffer, selected out of the array returned by
445 * the \ref phFriNfc_NdefRecord_GetRecords function.
447 * \retval NFCSTATUS_SUCCESS Operation successful.
448 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
450 * \note There are some caveats:
451 * - The "RawRecord" Data buffer must exist at least as long as the function execution time plus the time
452 * needed by the caller to evaluate the extracted information. No copying of the contained data is done.
453 * - Using the "RawRecord" and "RawRecordMaxSize" parameters the function internally checks whether the
454 * data to extract are within the bounds of the buffer.
458 NFCSTATUS phFriNfc_NdefRecord_Parse(phFriNfc_NdefRecord_t *Record,
461 NFCSTATUS Status = NFCSTATUS_SUCCESS;
462 uint8_t PayloadLengthByte = 0,
468 uint32_t PayloadLength = 0;
470 if (Record == NULL || RawRecord == NULL)
472 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
473 NFCSTATUS_INVALID_PARAMETER);
479 /* Calculate the Flag Value */
480 Record->Flags = phFriNfc_NdefRecord_RecordFlag ( RawRecord);
482 /* Calculate the Type Namr format of the record */
483 Tnf = phFriNfc_NdefRecord_TypeNameFormat( RawRecord);
487 /* To Calculate the IDLength and PayloadLength for short or normal record */
488 Status = phFriNfc_NdefRecord_RecordIDCheck ( RawRecord,
495 Record->TypeLength = TypeLength;
496 Record->PayloadLength = PayloadLength;
497 Record->IdLength = IDLength;
498 RawRecord = (RawRecord + PayloadLengthByte + IDLengthByte + TypeLengthByte + PH_FRINFC_NDEFRECORD_BUF_INC1);
499 Record->Type = RawRecord;
501 RawRecord = (RawRecord + Record->TypeLength);
503 if (Record->IdLength != 0)
505 Record->Id = RawRecord;
508 RawRecord = RawRecord + Record->IdLength;
509 Record->PayloadData = RawRecord;
513 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
514 NFCSTATUS_INVALID_PARAMETER);
523 * The function writes one NDEF record to a specified memory location. Called within a loop, it is possible to
524 * write more records into a contiguous buffer, in each cycle advancing by the number of bytes written for
527 * \param[in] Record The Array of NDEF record structures to append. The structures
528 * have to be filled by the caller matching the requirements for
529 * \b Composition, as described in the documentation of
530 * the \ref phFriNfc_NdefRecord_t "NDEF Record" structure.
531 * \param[in] Buffer The pointer to the buffer.
532 * \param[in] MaxBufferSize The data buffer's maximum size, provided by the caller.
533 * \param[out] BytesWritten The actual number of bytes written to the buffer. This can be used by
534 * the caller to serialise more than one record into the same buffer before
535 * handing it over to another instance.
537 * \retval NFCSTATUS_SUCCESS Operation successful.
538 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
539 * \retval NFCSTATUS_BUFFER_TOO_SMALL The data buffer, provided by the caller is to small to
540 * hold the composed NDEF record. The existing content is not changed.
543 NFCSTATUS phFriNfc_NdefRecord_Generate(phFriNfc_NdefRecord_t *Record,
545 uint32_t MaxBufferSize,
546 uint32_t *BytesWritten)
554 if(Record==NULL ||Buffer==NULL||BytesWritten==NULL||MaxBufferSize == 0)
556 return (PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD, NFCSTATUS_INVALID_PARAMETER));
559 if (Record->Tnf == PH_FRINFC_NDEFRECORD_TNF_RESERVED)
561 return (PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD, NFCSTATUS_INVALID_FORMAT));
564 /* calculate the length of the record and check with the buffersize if it exceeds return */
565 i_data=phFriNfc_NdefRecord_GetLength(Record);
566 if(i_data > MaxBufferSize)
568 return (PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD, NFCSTATUS_BUFFER_TOO_SMALL));
570 *BytesWritten = i_data;
572 /*fill the first byte of the message(all the flags) */
573 /*increment the buffer*/
574 *Buffer = ( (Record->Flags & PH_FRINFC_NDEFRECORD_FLAG_MASK) | (Record->Tnf & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK));
577 /* check the TypeNameFlag for PH_FRINFC_NDEFRECORD_TNF_EMPTY */
578 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Tnf,PH_FRINFC_NDEFRECORD_TNFBYTE_MASK);
579 if(FlagCheck == PH_FRINFC_NDEFRECORD_TNF_EMPTY)
581 /* fill the typelength idlength and payloadlength with zero(empty message)*/
584 *Buffer=PH_FRINFC_NDEFRECORD_BUF_TNF_VALUE;
587 return (PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS));
590 /* check the TypeNameFlag for PH_FRINFC_NDEFRECORD_TNF_RESERVED */
591 /* TNF should not be reserved one*/
592 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Tnf,PH_FRINFC_NDEFRECORD_TNFBYTE_MASK);
593 if(FlagCheck == PH_FRINFC_NDEFRECORD_TNF_RESERVED)
595 return (PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD, NFCSTATUS_INVALID_PARAMETER));
598 /* check for TNF Unknown or Unchanged */
599 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Tnf,PH_FRINFC_NDEFRECORD_TNFBYTE_MASK);
600 if(FlagCheck == PH_FRINFC_NDEFRECORD_TNF_UNKNOWN || \
601 FlagCheck == PH_FRINFC_NDEFRECORD_TNF_UNCHANGED)
603 *Buffer = PH_FRINFC_NDEFRECORD_BUF_TNF_VALUE;
608 *Buffer = Record->TypeLength;
613 /* check for the short record bit if it is then payloadlength is only one byte */
614 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Flags,PH_FRINFC_NDEFRECORD_FLAGS_SR);
617 *Buffer = (uint8_t)(Record->PayloadLength & 0x000000ff);
622 /* if it is normal record payloadlength is 4 byte(32 bit)*/
623 *Buffer = (uint8_t)((Record->PayloadLength & 0xff000000) >> PHNFCSTSHL24);
625 *Buffer = (uint8_t)((Record->PayloadLength & 0x00ff0000) >> PHNFCSTSHL16);
627 *Buffer = (uint8_t)((Record->PayloadLength & 0x0000ff00) >> PHNFCSTSHL8);
629 *Buffer = (uint8_t)((Record->PayloadLength & 0x000000ff));
633 /*check for IL bit set(Flag), if so then IDlength is present*/
634 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Flags,PH_FRINFC_NDEFRECORD_FLAGS_IL);
637 *Buffer=Record->IdLength;
641 /*check for TNF and fill the Type*/
645 for(i=0;i<(Record->TypeLength);i++)
653 /*check for IL bit set(Flag), if so then IDlength is present and fill the ID*/
654 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Flags,PH_FRINFC_NDEFRECORD_FLAGS_IL);
658 for(i=0;i<(Record->IdLength);i++)
666 temp=Record->PayloadData;
667 /*check for SR bit and then correspondingly use the payload length*/
668 FlagCheck=phFriNfc_NdefRecord_NdefFlag(Record->Flags,PH_FRINFC_NDEFRECORD_FLAGS_SR);
669 for(i_data=0;i_data < (Record->PayloadLength) ;i_data++)
676 return (PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS));
679 /* Calculate the Flags of the record */
680 static uint8_t phFriNfc_NdefRecord_RecordFlag ( uint8_t *Record)
684 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_MB) == PH_FRINFC_NDEFRECORD_FLAGS_MB )
686 flag = flag | PH_FRINFC_NDEFRECORD_FLAGS_MB;
688 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_ME) == PH_FRINFC_NDEFRECORD_FLAGS_ME )
690 flag = flag | PH_FRINFC_NDEFRECORD_FLAGS_ME;
692 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_CF) == PH_FRINFC_NDEFRECORD_FLAGS_CF )
694 flag = flag | PH_FRINFC_NDEFRECORD_FLAGS_CF;
696 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_SR) == PH_FRINFC_NDEFRECORD_FLAGS_SR )
698 flag = flag | PH_FRINFC_NDEFRECORD_FLAGS_SR;
700 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_IL) == PH_FRINFC_NDEFRECORD_FLAGS_IL )
702 flag = flag | PH_FRINFC_NDEFRECORD_FLAGS_IL;
707 /* Calculate the Type Name Format for the record */
708 static uint8_t phFriNfc_NdefRecord_TypeNameFormat ( uint8_t *Record)
712 switch (*Record & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK)
714 case PH_FRINFC_NDEFRECORD_TNF_EMPTY:
715 tnf = PH_FRINFC_NDEFRECORD_TNF_EMPTY;
718 case PH_FRINFC_NDEFRECORD_TNF_NFCWELLKNOWN:
719 tnf = PH_FRINFC_NDEFRECORD_TNF_NFCWELLKNOWN;
722 case PH_FRINFC_NDEFRECORD_TNF_MEDIATYPE:
723 tnf = PH_FRINFC_NDEFRECORD_TNF_MEDIATYPE;
726 case PH_FRINFC_NDEFRECORD_TNF_ABSURI:
727 tnf = PH_FRINFC_NDEFRECORD_TNF_ABSURI;
730 case PH_FRINFC_NDEFRECORD_TNF_NFCEXT:
731 tnf = PH_FRINFC_NDEFRECORD_TNF_NFCEXT;
734 case PH_FRINFC_NDEFRECORD_TNF_UNKNOWN:
735 tnf = PH_FRINFC_NDEFRECORD_TNF_UNKNOWN;
738 case PH_FRINFC_NDEFRECORD_TNF_UNCHANGED:
739 tnf = PH_FRINFC_NDEFRECORD_TNF_UNCHANGED;
742 case PH_FRINFC_NDEFRECORD_TNF_RESERVED:
743 tnf = PH_FRINFC_NDEFRECORD_TNF_RESERVED;
751 static NFCSTATUS phFriNfc_NdefRecord_RecordIDCheck ( uint8_t *Record,
753 uint8_t *TypeLengthByte,
754 uint8_t *PayloadLengthByte,
755 uint32_t *PayloadLength,
756 uint8_t *IDLengthByte,
759 NFCSTATUS Status = NFCSTATUS_SUCCESS;
761 /* Check for Tnf bits 0x07 is reserved for future use */
762 if ((*Record & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) ==
763 PH_FRINFC_NDEFRECORD_TNF_RESERVED)
766 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
767 NFCSTATUS_INVALID_FORMAT);
771 /* Check for Type Name Format depending on the TNF, Type Length value is set*/
772 if ((*Record & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK)==
773 PH_FRINFC_NDEFRECORD_TNF_EMPTY)
775 *TypeLength = *(Record + PH_FRINFC_NDEFRECORD_BUF_INC1);
777 if (*(Record + PH_FRINFC_NDEFRECORD_BUF_INC1) != 0)
779 /* Type Length Error */
780 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
781 NFCSTATUS_INVALID_FORMAT);
787 /* Check for Short Record */
788 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_SR) == PH_FRINFC_NDEFRECORD_FLAGS_SR)
790 /* For Short Record, Payload Length Byte is 1 */
791 *PayloadLengthByte = 1;
792 /* 1 for Header byte */
793 *PayloadLength = *(Record + *TypeLengthByte + 1);
794 if (*PayloadLength != 0)
796 /* PayloadLength Error */
797 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
798 NFCSTATUS_INVALID_FORMAT);
804 /* For Normal Record, Payload Length Byte is 4 */
805 *PayloadLengthByte = PHFRINFCNDEFRECORD_NORMAL_RECORD_BYTE;
806 *PayloadLength = ((((uint32_t)(*(Record + PH_FRINFC_NDEFRECORD_BUF_INC2))) << PHNFCSTSHL24) +
807 (((uint32_t)(*(Record + PH_FRINFC_NDEFRECORD_BUF_INC3))) << PHNFCSTSHL16) +
808 (((uint32_t)(*(Record + PH_FRINFC_NDEFRECORD_BUF_INC4))) << PHNFCSTSHL8) +
809 *(Record + PH_FRINFC_NDEFRECORD_BUF_INC5));
810 if (*PayloadLength != 0)
812 /* PayloadLength Error */
813 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
814 NFCSTATUS_INVALID_FORMAT);
819 /* Check for ID Length existence */
820 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_IL) == PH_FRINFC_NDEFRECORD_FLAGS_IL)
822 /* Length Byte exists and it is 1 byte */
824 /* 1 for Header byte */
825 *IDLength = (uint8_t)*(Record + *PayloadLengthByte + *TypeLengthByte + PH_FRINFC_NDEFRECORD_BUF_INC1);
829 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
830 NFCSTATUS_INVALID_FORMAT);
842 if ((*Record & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK)== PH_FRINFC_NDEFRECORD_TNF_UNKNOWN
843 || (*Record & PH_FRINFC_NDEFRECORD_TNFBYTE_MASK) ==
844 PH_FRINFC_NDEFRECORD_TNF_UNCHANGED)
846 if (*(Record + PH_FRINFC_NDEFRECORD_BUF_INC1) != 0)
848 /* Type Length Error */
849 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_RECORD,
850 NFCSTATUS_INVALID_FORMAT);
858 /* 1 for Header byte */
859 *TypeLength = *(Record + PH_FRINFC_NDEFRECORD_BUF_INC1);
863 /* Check for Short Record */
864 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_SR) ==
865 PH_FRINFC_NDEFRECORD_FLAGS_SR)
867 /* For Short Record, Payload Length Byte is 1 */
868 *PayloadLengthByte = 1;
869 /* 1 for Header byte */
870 *PayloadLength = *(Record + *TypeLengthByte + PH_FRINFC_NDEFRECORD_BUF_INC1);
874 /* For Normal Record, Payload Length Byte is 4 */
875 *PayloadLengthByte = PHFRINFCNDEFRECORD_NORMAL_RECORD_BYTE;
876 *PayloadLength = ((((uint32_t)(*(Record + PH_FRINFC_NDEFRECORD_BUF_INC2))) << PHNFCSTSHL24) +
877 (((uint32_t)(*(Record + PH_FRINFC_NDEFRECORD_BUF_INC3))) << PHNFCSTSHL16) +
878 (((uint32_t)(*(Record + PH_FRINFC_NDEFRECORD_BUF_INC4))) << PHNFCSTSHL8) +
879 *(Record + PH_FRINFC_NDEFRECORD_BUF_INC5));
882 /* Check for ID Length existence */
883 if ((*Record & PH_FRINFC_NDEFRECORD_FLAGS_IL) ==
884 PH_FRINFC_NDEFRECORD_FLAGS_IL)
887 /* 1 for Header byte */
888 *IDLength = (uint8_t)*(Record + *PayloadLengthByte + *TypeLengthByte + PH_FRINFC_NDEFRECORD_BUF_INC1);