Utility library to read and write Ndef messages from/to a Type4 NFC tag

Dependents:   NFC M2M_2016_STM32 MyongjiElec_capstone1 IDW01M1_Cloud_IBM ... more

Fork of NDefLib by ST Expansion SW Team

NDEF NFC library

This library provides an abstract API to create NDEF formatted messages and records and to read/write them from/to a Type4 NFC Tag.

Implementations

At the moment, the NDEF API is implemented by X_NUCLEO_NFC01A1 and X_NUCLEO_NFC02A1 Dynamic NFC Tag libraries respectively driving the X-NUCLEO-NFC01A1 and X-NUCLEO-NFC02A1 boards.

RecordHeader.h

Committer:
giovannivisentini
Date:
2015-12-22
Revision:
8:473f6e0b03df
Parent:
7:1ebd6049fa57
Child:
12:ed4d9b8d1410

File content as of revision 8:473f6e0b03df:

/**
 ******************************************************************************
 * @file    RecordHeader.h
 * @author  ST / Central Labs
 * @version V1.0.0
 * @date    30 Nov 2015
 * @brief   Record header class 
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of STMicroelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */

#ifndef NDEFLIB_RECORDHEADER_H_
#define NDEFLIB_RECORDHEADER_H_

#include <stdint.h>

namespace NDefLib {

/**
 * Record header class
 * @see NFC Data Exchange Format (NDEF) Technical Specification NDEF 1.0
 */
class RecordHeader {

public:

	/**
	 * record type format
	 */
	typedef enum TypeNameFormat {
		Empty = 0x00,          //!< Empty
		NFC_well_known = 0x01, //!< NFC_well_known
		Mime_media_type = 0x02,//!< Mime_media_type
		Absolute_URI = 0x03,   //!< Absolute_URI
		NFC_external = 0x04,   //!< NFC_external
		Unknown = 0x05,        //!< Unknown
		Unchanged = 0x06,      //!< Unchanged
		Reserved = 0x07        //!< Reserved
	} TypeNameFormat_t;


	RecordHeader() :
			headerFlags(0), typeLength(0), payloadLength(0) {
		setSR(true);
	}

	/**
	 * set the message begin flag
	 * @param value true if the record is the first of the message
	 */
	void setMB(bool value) {
		if (value)
			headerFlags |= 0x80;
		else
			headerFlags &= ~0x80;
	}//setMB

	/**
	 * get the message being flag
	 * @return true if it is the first record in the message
	 */
	bool getMB() const {
		return (headerFlags & 0x80) != 0;
	}//getMB

	/**
	 * set the message end flag
	 * @param value true if it is the last record in the message
	 */
	void setME(bool value) {
		if (value)
			headerFlags |= 0x40;
		else
			headerFlags &= ~0x40;
	}//setME

	/**
	 * get the message end flag
	 * @return true if it is the last record in the message
	 */
	bool getME() const {
		return (headerFlags & 0x40) != 0;
	}//getME

	/**
	 * set the Chunk flag
	 * @param value true if the record is in the first record chunk or a middle record
	 * chunk of a chunked payload
	 */
	void setCF(bool value) {
		if (value)
			headerFlags |= 0x20;
		else
			headerFlags &= ~0x20;
	}//getCF

	/**
	 * get the Chunk flag value
	 * @return true if the record is in the first record chunk or a middle record
	 * chunk of a chunked payload
	 */
	bool getCF() const {
		return (headerFlags & 0x20) != 0;
	}//getCF

	/**
	 * set the short record flag value
	 * @param value true if the record size can be encoded with 8 bits
	 */
	void setSR(bool value) {
		if (value)
			headerFlags |= 0x10;
		else
			headerFlags &= ~0x10;
	}//setSR

	/**
	 * get the Short record flag
	 * @return true if we are using the short range header format
	 */
	bool getSR() const {
		return (headerFlags & 0x10) != 0;
	}//getSR

	/**
	 * set the ID length flag
	 * @param value true if we will use the id length value in the record
	 */
	void setIL(bool value) {
		if (value)
			headerFlags |= 0x08;
		else
			headerFlags &= ~0x08;
	}//setIL

	/**
	 * get the ID length flag
	 * @param value true if we will use the id length value in the record
	 */
	bool getIL() const {
		return (headerFlags & 0x08) != 0;
	}//getIL

	/**
	 * set the type name format field
	 * @param value record type name format
	 */
	void setFNT(const TypeNameFormat_t value) {
		uint8_t temp = (uint8_t) value;
		temp &= 0x07; //keep the first 3 bits
		headerFlags &= 0xF8; //clean the fist 3 bits
		headerFlags |= temp; //set the fist 3 bits
	}//setFNT

	/**
	 * get the record type name
	 * @return type name format of the record
	 */
	TypeNameFormat_t getFNT() const {
		return (TypeNameFormat_t) (headerFlags & 0x07);
	}

	/**
	 * set the record payload length
	 * @par this function will update the SR field as needed
	 * @param length payload length
	 */
	void setPayloadLength(uint32_t length) {
		payloadLength = length;
		setSR(payloadLength <= 255);
	}

	/**
	 * get the payload length
	 * @return payload length
	 */
	uint32_t getPayloadLength() const {
		return payloadLength;
	}

	/**
	 * set the type length
	 * @param size
	 */
	void setTypeLength(uint8_t size) {
		typeLength = size;
	}

	/**
	 * get the type length
	 * @return
	 */
	uint8_t getTypeLength() const {
		return typeLength;
	}

	/**
	 * get the number of byte needed for store this record
	 * @return 3 or 6
	 */
	uint16_t getRecordLength() const {
		return (getSR() ? 3 : 6) + typeLength + payloadLength;
	}

	/**
	 * store the header information in the buffer
	 * @param[out] outBuffer buffer where write the header
	 * @return number of write bytes
	 */
	uint8_t writeHeader(uint8_t *outBuffer) const {

		uint32_t index = 0;

		outBuffer[index++] = headerFlags;
		outBuffer[index++] = typeLength;
		if (getSR()) {
			outBuffer[index++] = (uint8_t) payloadLength;
		} else {
			outBuffer[index++] = (uint8_t) ((payloadLength & 0xFF000000)
					>> 24);
			outBuffer[index++] = (uint8_t) ((payloadLength & 0x00FF0000)
					>> 16);
			outBuffer[index++] = (uint8_t) ((payloadLength & 0x0000FF00)
					>> 8);
			outBuffer[index++] = (uint8_t) (payloadLength & 0x000000FF);
		} //if-else
		return index;
	} //writeHeader

	/**
	 * load an header from a buffer
	 * @param buffer buffer where read the header
	 * @return number of read bytes
	 */
	uint16_t loadHeader(const uint8_t * const buffer) {
		uint32_t index = 0;
		headerFlags = buffer[index++];
		typeLength = buffer[index++];
		if (getSR()) {
			payloadLength = buffer[index++];
		} else {
			payloadLength = (((uint32_t) buffer[index + 0]) << 24)
					| (((uint32_t) buffer[index + 1]) << 16)
					| (((uint32_t) buffer[index + 2]) << 8)
					| ((uint32_t) buffer[index + 3]);
			index += 4;
		} //if-else
		return index;
	} //loadHeader

	/**
	 * equal operator
	 * @param other other object to compare
	 * @return true if the 2 record header are equals
	 */
	bool operator==(const RecordHeader &other) const{
		return (headerFlags==other.headerFlags) &&
				(typeLength==other.typeLength) &&
				(payloadLength==other.payloadLength);
	}

	bool operator!=(const RecordHeader &other) const{
		return !(*this==other);
	}

private:
	uint8_t headerFlags;
	uint8_t typeLength;
	uint32_t payloadLength;
};

} /* namespace NDefLib */

#endif /* NDEFLIB_RECORDHEADER_H_ */