/*
*                    Copyright (c), NXP Semiconductors
*
*                       (C) NXP Semiconductors 2018
*
*         All rights are reserved. Reproduction in whole or in part is
*        prohibited without the written consent of the copyright owner.
*    NXP reserves the right to make changes without notice at any time.
*   NXP makes no warranty, expressed, implied or statutory, including but
*   not limited to any implied warranty of merchantability or fitness for any
*  particular purpose, or that the use will not infringe any third party patent,
*   copyright or trademark. NXP must not be liable for any loss or damage
*                            arising from its use.
*/

#ifndef NDEF_RECORD_H_
#define NDEF_RECORD_H_

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */

/* ********************************************************************************************
* Includes
* ******************************************************************************************* */
#include <stdint.h>
#include "NDEF_Config.h"
#include "NDEF_Status.h"


/** \defgroup Rec  Generic Record Interface
*
* \brief
* @{
*/

/* ********************************************************************************************
* MACROS/Defines
* ******************************************************************************************* */
#define NDEF_HEADER_TNF_MAX_VAL		0x07u
#define NDEF_HEADER_FLAG_MASK		0xF8u
#define NDEF_HEADER_TNF_MASK		0x07u

#define NDEF_HEADER_FLAG_MB	0x80u
#define NDEF_HEADER_FLAG_ME	0x40u
#define NDEF_HEADER_FLAG_CF 0x20u
#define NDEF_HEADER_FLAG_SR 0x10u
#define NDEF_HEADER_FLAG_IL 0x08u

#define NDEF_HEADER_FLAGS_TNF_LEN	1
#define NDEF_HEADER_TYPELEN_LEN		1
#define NDEF_HEADER_SR_PAYLOAD_LEN	1
#define NDEF_HEADER_PAYLOAD_LEN		4
#define NDEF_HEADER_IDLEN_LEN		1

#define NDEF_HEADER_SR_PAYLOAD_THRESHOLD 0xFFu


/* ********************************************************************************************
* Types/Structure Declarations
* ******************************************************************************************* */
/**
* \brief Type name format enumeration
*/
typedef enum
{
	EmptyRecord = 0x00,
	WellKnownTypeRecord,
	MimeRecord,
	AbsoluteUriRecord,
	ExternalRecord,
	UnknownRecord,
	UnchangedRecord,
	
}NDEF_Record_Header_Tnf_t;


/**
* \brief Internal record type identification used to distinguish between record structures
*/
typedef enum
{
	Not_initialized = 0x00,
	Type_Generic,
	Type_Aar,
	Type_BtsspBrEdr,
	Type_BtsspLe,
	Type_HandoverSelect,
	Type_AlterantiveCarrier,
	Type_Phdc,
	Type_Text,
	Type_Uri,
	Type_WlcCap,
	Type_WlcTiPol,
	Type_WlcTiLis,
	TypeIdMax
}RecordTypeId_t;

/**
* \brief Internal information about record
*/
typedef struct 
{
	RecordTypeId_t eId;				/**< Internal  Type Identification  */
	uint32_t dwHeapUsedByPayload;	/**< Size of heap in use by record	>*/
}RecordInfo_t;


/**
* \brief Record header structure
*/
typedef struct
{
	uint8_t bFlagsTnf;				/**< Header flags and TypeNameFormat */
	uint8_t bTypeLength;			/**< Length of Type  */
	uint32_t dwPayloadLength;		/**< Length of Payload */
	uint8_t bIdLength;				/**< Length of Id*/
	uint8_t * pRecordType;			/**< Type field */
	uint8_t * pRecordId;			/**< Id field */
} NDEF_Record_Header_t;


/**
* \brief Generic casting structure
*/
typedef struct
{
	RecordInfo_t INT_sRecordInfo;		/**< Internal record information. */
	NDEF_Record_Header_t sHeader;		/**< Record header structure. */
}NDEF_Rec_GenericCasting_t;





/* ********************************************************************************************
* Function Prototypes
* ******************************************************************************************* */
/**
 * \briefThis function is used to store the Id(null terminated) on heap and set the reference into record specified by handle.
 *
 * @param[in] pRecord	   		Generic  handle.
 * @param[in] pId     			Pointer to Id.
 *
 *
 * @return Status of the API
 * @retval NDEF_STATUS_SUCCESS				Function returned successfully.
 * @retval NDEF_STATUS_ERROR_INVALID_PARAM	Null/Invalid function parameter.
 * @retval NDEF_STATUS_ERROR_NULL_PTR		Failed malloc.
 */
extern Status_t NDEF_Rec_SetId(void * pRecord, const char * pId);


/**
 * \brief This function is used to store the Type(null terminated) on heap and set the reference into record specified by handle.
 *
 * @param[in] pRecord	   		Generic  handle.
 * @param[in] pType     		Pointer to Type.

 *
 * @return Status of the API
 * @retval NDEF_STATUS_SUCCESS				Function returned successfully.
 * @retval NDEF_STATUS_ERROR_INVALID_PARAM	Null/Invalid function parameter.
 * @retval NDEF_STATUS_ERROR_NULL_PTR		Failed malloc.
 */
extern Status_t NDEF_Rec_SetType(void * pRecord, const char * pType);


/**
* \brief This function is used to set the TypeNameFormat of a record specified by handle.
*
* @param[in] 		pRecord	   				Generic  handle.
* @param[in] 		eTnf	   				Enumeration of TypeNameFormat.
*
* @return Status of the API
* @retval NDEF_STATUS_SUCCESS				Function returned successfully.
* @retval NDEF_STATUS_ERROR_INVALID_PARAM	Null/Invalid function parameter.
*/
extern Status_t NDEF_Rec_SetTnf(void * pRecord, NDEF_Record_Header_Tnf_t eTnf);


/**
 * \brief This function is used to set the HeaderFlags of a record specified by handle.
 *  <pre>
 *   7    6    5    4    3    2    1    0
 *	---  ---  ---  ---  ---  ---  ---  ---
 *	[MB] [ME] [CF] [SR] [IL]  0    0    0
 *	</pre>
 *
 * @param[in] 		pRecord	   				Record  handle.
 * @param[in] 		bFlags	   				Header flags.
 *
 * @return Status of the API
 * @retval NDEF_STATUS_SUCCESS				Function returned successfully.
 * @retval NDEF_STATUS_ERROR_INVALID_PARAM	Null/Invalid function parameter.
 */
extern Status_t NDEF_Rec_SetFlags(void * pRecord, uint8_t bFlags);


/**
 * \brief This function is used to return the HeaderFlags of a record specified by handle.
 *  <pre>
 *   7    6    5    4    3    2    1    0
 *	---  ---  ---  ---  ---  ---  ---  ---
 *	[MB] [ME] [CF] [SR] [IL]  0    0    0
 *	</pre>
 *
 * @param[in] 		pRecord		Record handle.
 *
 * @return HeaderFlags
 * @retval In case of error returns 0.
 */
extern uint8_t NDEF_Rec_GetFlags(void * pRecord);


/**
 * \brief This function is used to return the TypeNameFormat of a record specified by handle.
 *
 * @param[in] 		pRecord		Record handle.
 *
 * @return Enumeration of TypeNameFormat - NDEF_Record_Header_Tnf_t
 * @retval In case of error returns 0.
 */
extern NDEF_Record_Header_Tnf_t NDEF_Rec_GetTnf(void * pRecord);

/**
 * \brief This function is used to return the IdLength of a record specified by handle.
 *
 * @param[in] 		pRecord	   Record handle.
 *
 * @return Record IdLength
 * @retval In case of error returns 0.
 */
extern uint8_t NDEF_Rec_GetIdLen(void * pRecord);

/**
 * \brief This function is used to return the TypeLength of a record specified by handle.
 * @param[in] 		pRecord	   	Record handle.
 *
 * @return Record TypeLength
 * @retval In case of error returns 0.
 */
extern uint8_t NDEF_Rec_GetTypeLen(void * pRecord);


/**
 * \brief This function is used to get the Id of a record specified by handle.
 *
 * @param[in] 	  pRecord   Record handle.
 * @param[out] 	  pId  		Pointer to Id output buffer.
 * @param[in] 	  wLength	Size of output buffer
 *
 * @return Status of the API
 * @retval NDEF_STATUS_SUCCESS				Function returned successfully.
 * @retval NDEF_STATUS_ERROR_INVALID_PARAM	Null/Invalid function parameter.
 * @retval NDEF_STATUS_ERROR_BUFF_OVF		Output won't fit into buffer.
 */
extern Status_t NDEF_Rec_GetId(void * pRecord, char * pId, uint16_t wLength);


/**
 * \brief This function is used to get the Type of a record specified by handle.
 *
 * @param[in] 	  pRecord   Record handle.
 * @param[in] 	  wLength	Size of output buffer.
 * @param[out] 	  pType  	Pointer to Type output buffer.
 *
 * @return Status of the API
 * @retval NDEF_STATUS_SUCCESS				Function returned successfully.
 * @retval NDEF_STATUS_ERROR_INVALID_PARAM	Null/Invalid function parameter.
 * @retval NDEF_STATUS_ERROR_BUFF_OVF		Output won't fit into buffer.
 */
extern Status_t NDEF_Rec_GetType(void * pRecord, char * pType, uint16_t wLength);



/**
* \brief This function is used to return the Payload length from a record specified by handle.
*
* @param[in] pRecord	   Record handle.
*
* @return Payload length
* @retval In case of error returns 0.
*/
extern uint32_t NDEF_Rec_GetPayloadLen(const void * pRecord);


/**
 * \brief  This function is used to free all resources used by record specified by handle . Record handle will be set to NULL on successful operation.
 *		   Note: Calling this function on a record  that is assigned to a message will not update any references in that message, which  may result in access to no longer valid heap location, therefore such use should be avoided.
 *
 * @param[in] 		ppRecord	   				Pointer to Generic handle.
 *
 * @return Status of the API
 * @retval NDEF_STATUS_SUCCESS				Function returned successfully.
 * @retval NDEF_STATUS_ERROR_INVALID_PARAM	Null/Invalid function parameter.
 */
extern Status_t NDEF_Rec_Destroy(void ** ppRecord);


/** @}
* end of Rec Ndef Generic Record Inteface
*/

#ifdef __cplusplus
} /* Extern C */
#endif

#endif /* NDEF_RECORD_H_ */
