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
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@4:eaf6c49a86e4, 2015-12-01 (annotated)
- Committer:
- giovannivisentini
- Date:
- Tue Dec 01 08:30:27 2015 +0000
- Revision:
- 4:eaf6c49a86e4
- Child:
- 6:739e3211749d
add the possibility to change the record content + add doc
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
giovannivisentini | 4:eaf6c49a86e4 | 1 | /* |
giovannivisentini | 4:eaf6c49a86e4 | 2 | * RecordHeader.h |
giovannivisentini | 4:eaf6c49a86e4 | 3 | * |
giovannivisentini | 4:eaf6c49a86e4 | 4 | * Created on: Nov 30, 2015 |
giovannivisentini | 4:eaf6c49a86e4 | 5 | * Author: giovanni visentini |
giovannivisentini | 4:eaf6c49a86e4 | 6 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 7 | |
giovannivisentini | 4:eaf6c49a86e4 | 8 | #ifndef NDEFLIB_RECORDHEADER_H_ |
giovannivisentini | 4:eaf6c49a86e4 | 9 | #define NDEFLIB_RECORDHEADER_H_ |
giovannivisentini | 4:eaf6c49a86e4 | 10 | |
giovannivisentini | 4:eaf6c49a86e4 | 11 | #include <stdint.h> |
giovannivisentini | 4:eaf6c49a86e4 | 12 | |
giovannivisentini | 4:eaf6c49a86e4 | 13 | namespace NDefLib { |
giovannivisentini | 4:eaf6c49a86e4 | 14 | |
giovannivisentini | 4:eaf6c49a86e4 | 15 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 16 | * Record header class |
giovannivisentini | 4:eaf6c49a86e4 | 17 | * @see NFC Data Exchange Format (NDEF) Technical Specification NDEF 1.0 |
giovannivisentini | 4:eaf6c49a86e4 | 18 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 19 | class RecordHeader { |
giovannivisentini | 4:eaf6c49a86e4 | 20 | |
giovannivisentini | 4:eaf6c49a86e4 | 21 | public: |
giovannivisentini | 4:eaf6c49a86e4 | 22 | |
giovannivisentini | 4:eaf6c49a86e4 | 23 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 24 | * record type format |
giovannivisentini | 4:eaf6c49a86e4 | 25 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 26 | typedef enum TypeNameFormat { |
giovannivisentini | 4:eaf6c49a86e4 | 27 | Empty = 0x00, //!< Empty |
giovannivisentini | 4:eaf6c49a86e4 | 28 | NFC_well_known = 0x01, //!< NFC_well_known |
giovannivisentini | 4:eaf6c49a86e4 | 29 | Mime_media_type = 0x02,//!< Mime_media_type |
giovannivisentini | 4:eaf6c49a86e4 | 30 | Absolute_URI = 0x03, //!< Absolute_URI |
giovannivisentini | 4:eaf6c49a86e4 | 31 | NFC_external = 0x04, //!< NFC_external |
giovannivisentini | 4:eaf6c49a86e4 | 32 | Unknown = 0x05, //!< Unknown |
giovannivisentini | 4:eaf6c49a86e4 | 33 | Unchanged = 0x06, //!< Unchanged |
giovannivisentini | 4:eaf6c49a86e4 | 34 | Reserved = 0x07 //!< Reserved |
giovannivisentini | 4:eaf6c49a86e4 | 35 | } TypeNameFormat_t; |
giovannivisentini | 4:eaf6c49a86e4 | 36 | |
giovannivisentini | 4:eaf6c49a86e4 | 37 | |
giovannivisentini | 4:eaf6c49a86e4 | 38 | RecordHeader() : |
giovannivisentini | 4:eaf6c49a86e4 | 39 | headerFlags(0), typeLength(0), playloadLength(0) { |
giovannivisentini | 4:eaf6c49a86e4 | 40 | } |
giovannivisentini | 4:eaf6c49a86e4 | 41 | |
giovannivisentini | 4:eaf6c49a86e4 | 42 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 43 | * set the message begin flag |
giovannivisentini | 4:eaf6c49a86e4 | 44 | * @param value true if the record is the first of the message |
giovannivisentini | 4:eaf6c49a86e4 | 45 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 46 | void setMB(bool value) { |
giovannivisentini | 4:eaf6c49a86e4 | 47 | if (value) |
giovannivisentini | 4:eaf6c49a86e4 | 48 | headerFlags |= 0x80; |
giovannivisentini | 4:eaf6c49a86e4 | 49 | else |
giovannivisentini | 4:eaf6c49a86e4 | 50 | headerFlags &= 0x7F; |
giovannivisentini | 4:eaf6c49a86e4 | 51 | }//setMB |
giovannivisentini | 4:eaf6c49a86e4 | 52 | |
giovannivisentini | 4:eaf6c49a86e4 | 53 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 54 | * get the message being flag |
giovannivisentini | 4:eaf6c49a86e4 | 55 | * @return true if it is the first record in the message |
giovannivisentini | 4:eaf6c49a86e4 | 56 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 57 | bool getMB() const { |
giovannivisentini | 4:eaf6c49a86e4 | 58 | return (headerFlags & 0x80) != 0; |
giovannivisentini | 4:eaf6c49a86e4 | 59 | }//getMB |
giovannivisentini | 4:eaf6c49a86e4 | 60 | |
giovannivisentini | 4:eaf6c49a86e4 | 61 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 62 | * set the message end flag |
giovannivisentini | 4:eaf6c49a86e4 | 63 | * @param value true if it is the last record in the message |
giovannivisentini | 4:eaf6c49a86e4 | 64 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 65 | void setME(bool value) { |
giovannivisentini | 4:eaf6c49a86e4 | 66 | if (value) |
giovannivisentini | 4:eaf6c49a86e4 | 67 | headerFlags |= 0x40; |
giovannivisentini | 4:eaf6c49a86e4 | 68 | else |
giovannivisentini | 4:eaf6c49a86e4 | 69 | headerFlags &= 0xBF; |
giovannivisentini | 4:eaf6c49a86e4 | 70 | }//setME |
giovannivisentini | 4:eaf6c49a86e4 | 71 | |
giovannivisentini | 4:eaf6c49a86e4 | 72 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 73 | * get the message end flag |
giovannivisentini | 4:eaf6c49a86e4 | 74 | * @return true if it is the last record in the message |
giovannivisentini | 4:eaf6c49a86e4 | 75 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 76 | bool getME() const { |
giovannivisentini | 4:eaf6c49a86e4 | 77 | return (headerFlags & 0x40) != 0; |
giovannivisentini | 4:eaf6c49a86e4 | 78 | }//getME |
giovannivisentini | 4:eaf6c49a86e4 | 79 | |
giovannivisentini | 4:eaf6c49a86e4 | 80 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 81 | * set the Chunk flag |
giovannivisentini | 4:eaf6c49a86e4 | 82 | * @param value true if the record is in the first record chunk or a middle record |
giovannivisentini | 4:eaf6c49a86e4 | 83 | * chunk of a chunked payload |
giovannivisentini | 4:eaf6c49a86e4 | 84 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 85 | void setCF(bool value) { |
giovannivisentini | 4:eaf6c49a86e4 | 86 | if (value) |
giovannivisentini | 4:eaf6c49a86e4 | 87 | headerFlags |= 0x20; |
giovannivisentini | 4:eaf6c49a86e4 | 88 | else |
giovannivisentini | 4:eaf6c49a86e4 | 89 | headerFlags &= 0xDF; |
giovannivisentini | 4:eaf6c49a86e4 | 90 | }//getCF |
giovannivisentini | 4:eaf6c49a86e4 | 91 | |
giovannivisentini | 4:eaf6c49a86e4 | 92 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 93 | * get the Chunk flag value |
giovannivisentini | 4:eaf6c49a86e4 | 94 | * @return true if the record is in the first record chunk or a middle record |
giovannivisentini | 4:eaf6c49a86e4 | 95 | * chunk of a chunked payload |
giovannivisentini | 4:eaf6c49a86e4 | 96 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 97 | bool getCF() const { |
giovannivisentini | 4:eaf6c49a86e4 | 98 | return (headerFlags & 0x20) != 0; |
giovannivisentini | 4:eaf6c49a86e4 | 99 | }//getCF |
giovannivisentini | 4:eaf6c49a86e4 | 100 | |
giovannivisentini | 4:eaf6c49a86e4 | 101 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 102 | * set the short record flag value |
giovannivisentini | 4:eaf6c49a86e4 | 103 | * @param value true if the record size can be encoded with 8 bits |
giovannivisentini | 4:eaf6c49a86e4 | 104 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 105 | void setSR(bool value) { |
giovannivisentini | 4:eaf6c49a86e4 | 106 | if (value) |
giovannivisentini | 4:eaf6c49a86e4 | 107 | headerFlags |= 0x10; |
giovannivisentini | 4:eaf6c49a86e4 | 108 | else |
giovannivisentini | 4:eaf6c49a86e4 | 109 | headerFlags &= 0xCF; |
giovannivisentini | 4:eaf6c49a86e4 | 110 | }//setSR |
giovannivisentini | 4:eaf6c49a86e4 | 111 | |
giovannivisentini | 4:eaf6c49a86e4 | 112 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 113 | * get the Short record flag |
giovannivisentini | 4:eaf6c49a86e4 | 114 | * @return true if we are using the short range header format |
giovannivisentini | 4:eaf6c49a86e4 | 115 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 116 | bool getSR() const { |
giovannivisentini | 4:eaf6c49a86e4 | 117 | return (headerFlags & 0x10) != 0; |
giovannivisentini | 4:eaf6c49a86e4 | 118 | }//getSR |
giovannivisentini | 4:eaf6c49a86e4 | 119 | |
giovannivisentini | 4:eaf6c49a86e4 | 120 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 121 | * set the ID length flag |
giovannivisentini | 4:eaf6c49a86e4 | 122 | * @param value true if we will use the id length value in the record |
giovannivisentini | 4:eaf6c49a86e4 | 123 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 124 | void setIL(bool value) { |
giovannivisentini | 4:eaf6c49a86e4 | 125 | if (value) |
giovannivisentini | 4:eaf6c49a86e4 | 126 | headerFlags |= 0x08; |
giovannivisentini | 4:eaf6c49a86e4 | 127 | else |
giovannivisentini | 4:eaf6c49a86e4 | 128 | headerFlags &= 0xAF; |
giovannivisentini | 4:eaf6c49a86e4 | 129 | }//setIL |
giovannivisentini | 4:eaf6c49a86e4 | 130 | |
giovannivisentini | 4:eaf6c49a86e4 | 131 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 132 | * get the ID length flag |
giovannivisentini | 4:eaf6c49a86e4 | 133 | * @param value true if we will use the id length value in the record |
giovannivisentini | 4:eaf6c49a86e4 | 134 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 135 | bool getIL() const { |
giovannivisentini | 4:eaf6c49a86e4 | 136 | return (headerFlags & 0x08) != 0; |
giovannivisentini | 4:eaf6c49a86e4 | 137 | }//getIL |
giovannivisentini | 4:eaf6c49a86e4 | 138 | |
giovannivisentini | 4:eaf6c49a86e4 | 139 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 140 | * set the type name format field |
giovannivisentini | 4:eaf6c49a86e4 | 141 | * @param value record type name format |
giovannivisentini | 4:eaf6c49a86e4 | 142 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 143 | void setFNT(const TypeNameFormat_t value) { |
giovannivisentini | 4:eaf6c49a86e4 | 144 | uint8_t temp = (uint8_t) value; |
giovannivisentini | 4:eaf6c49a86e4 | 145 | temp &= 0x07; //keep the first 3 bits |
giovannivisentini | 4:eaf6c49a86e4 | 146 | headerFlags &= 0xF8; //clean the fist 3 bits |
giovannivisentini | 4:eaf6c49a86e4 | 147 | headerFlags |= temp; //set the fist 3 bits |
giovannivisentini | 4:eaf6c49a86e4 | 148 | }//setFNT |
giovannivisentini | 4:eaf6c49a86e4 | 149 | |
giovannivisentini | 4:eaf6c49a86e4 | 150 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 151 | * get the record type name |
giovannivisentini | 4:eaf6c49a86e4 | 152 | * @return type name format of the record |
giovannivisentini | 4:eaf6c49a86e4 | 153 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 154 | TypeNameFormat_t getFNT() const { |
giovannivisentini | 4:eaf6c49a86e4 | 155 | return (TypeNameFormat_t) (headerFlags & 0x07); |
giovannivisentini | 4:eaf6c49a86e4 | 156 | } |
giovannivisentini | 4:eaf6c49a86e4 | 157 | |
giovannivisentini | 4:eaf6c49a86e4 | 158 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 159 | * set the record playload length |
giovannivisentini | 4:eaf6c49a86e4 | 160 | * @par this function will update the SR field as needed |
giovannivisentini | 4:eaf6c49a86e4 | 161 | * @param length playload length |
giovannivisentini | 4:eaf6c49a86e4 | 162 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 163 | void setPlayloadLength(uint32_t length) { |
giovannivisentini | 4:eaf6c49a86e4 | 164 | playloadLength = length; |
giovannivisentini | 4:eaf6c49a86e4 | 165 | setSR(playloadLength <= 255); |
giovannivisentini | 4:eaf6c49a86e4 | 166 | } |
giovannivisentini | 4:eaf6c49a86e4 | 167 | |
giovannivisentini | 4:eaf6c49a86e4 | 168 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 169 | * get the playload length |
giovannivisentini | 4:eaf6c49a86e4 | 170 | * @return playload length |
giovannivisentini | 4:eaf6c49a86e4 | 171 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 172 | uint32_t getPlayloadLength() const { |
giovannivisentini | 4:eaf6c49a86e4 | 173 | return playloadLength; |
giovannivisentini | 4:eaf6c49a86e4 | 174 | } |
giovannivisentini | 4:eaf6c49a86e4 | 175 | |
giovannivisentini | 4:eaf6c49a86e4 | 176 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 177 | * set the type length |
giovannivisentini | 4:eaf6c49a86e4 | 178 | * @param size |
giovannivisentini | 4:eaf6c49a86e4 | 179 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 180 | void setTypeLength(uint8_t size) { |
giovannivisentini | 4:eaf6c49a86e4 | 181 | typeLength = size; |
giovannivisentini | 4:eaf6c49a86e4 | 182 | } |
giovannivisentini | 4:eaf6c49a86e4 | 183 | |
giovannivisentini | 4:eaf6c49a86e4 | 184 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 185 | * get the type length |
giovannivisentini | 4:eaf6c49a86e4 | 186 | * @return |
giovannivisentini | 4:eaf6c49a86e4 | 187 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 188 | uint8_t getTypeLength() const { |
giovannivisentini | 4:eaf6c49a86e4 | 189 | return typeLength; |
giovannivisentini | 4:eaf6c49a86e4 | 190 | } |
giovannivisentini | 4:eaf6c49a86e4 | 191 | |
giovannivisentini | 4:eaf6c49a86e4 | 192 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 193 | * get the number of byte needed for store this record |
giovannivisentini | 4:eaf6c49a86e4 | 194 | * @return 3 or 6 |
giovannivisentini | 4:eaf6c49a86e4 | 195 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 196 | uint16_t getRecordLength() const { |
giovannivisentini | 4:eaf6c49a86e4 | 197 | return (getSR() ? 3 : 6) + typeLength + playloadLength; |
giovannivisentini | 4:eaf6c49a86e4 | 198 | } |
giovannivisentini | 4:eaf6c49a86e4 | 199 | |
giovannivisentini | 4:eaf6c49a86e4 | 200 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 201 | * store the header information in the buffer |
giovannivisentini | 4:eaf6c49a86e4 | 202 | * @param[out] outBuffer buffer where write the header |
giovannivisentini | 4:eaf6c49a86e4 | 203 | * @return number of write bytes |
giovannivisentini | 4:eaf6c49a86e4 | 204 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 205 | uint8_t writeHeader(uint8_t *outBuffer) const { |
giovannivisentini | 4:eaf6c49a86e4 | 206 | |
giovannivisentini | 4:eaf6c49a86e4 | 207 | uint32_t index = 0; |
giovannivisentini | 4:eaf6c49a86e4 | 208 | |
giovannivisentini | 4:eaf6c49a86e4 | 209 | outBuffer[index++] = headerFlags; |
giovannivisentini | 4:eaf6c49a86e4 | 210 | outBuffer[index++] = typeLength; |
giovannivisentini | 4:eaf6c49a86e4 | 211 | if (getSR()) { |
giovannivisentini | 4:eaf6c49a86e4 | 212 | outBuffer[index++] = (uint8_t) playloadLength; |
giovannivisentini | 4:eaf6c49a86e4 | 213 | } else { |
giovannivisentini | 4:eaf6c49a86e4 | 214 | outBuffer[index++] = (uint8_t) ((playloadLength & 0xFF000000) |
giovannivisentini | 4:eaf6c49a86e4 | 215 | >> 24); |
giovannivisentini | 4:eaf6c49a86e4 | 216 | outBuffer[index++] = (uint8_t) ((playloadLength & 0x00FF0000) |
giovannivisentini | 4:eaf6c49a86e4 | 217 | >> 16); |
giovannivisentini | 4:eaf6c49a86e4 | 218 | outBuffer[index++] = (uint8_t) ((playloadLength & 0x0000FF00) |
giovannivisentini | 4:eaf6c49a86e4 | 219 | >> 8); |
giovannivisentini | 4:eaf6c49a86e4 | 220 | outBuffer[index++] = (uint8_t) (playloadLength & 0x000000FF); |
giovannivisentini | 4:eaf6c49a86e4 | 221 | } //if-else |
giovannivisentini | 4:eaf6c49a86e4 | 222 | return index; |
giovannivisentini | 4:eaf6c49a86e4 | 223 | } //writeHeader |
giovannivisentini | 4:eaf6c49a86e4 | 224 | |
giovannivisentini | 4:eaf6c49a86e4 | 225 | /** |
giovannivisentini | 4:eaf6c49a86e4 | 226 | * load an header from a buffer |
giovannivisentini | 4:eaf6c49a86e4 | 227 | * @param buffer buffer where read the header |
giovannivisentini | 4:eaf6c49a86e4 | 228 | * @return number of read bytes |
giovannivisentini | 4:eaf6c49a86e4 | 229 | */ |
giovannivisentini | 4:eaf6c49a86e4 | 230 | uint16_t loadHeader(const uint8_t * const buffer) { |
giovannivisentini | 4:eaf6c49a86e4 | 231 | uint32_t index = 0; |
giovannivisentini | 4:eaf6c49a86e4 | 232 | headerFlags = buffer[index++]; |
giovannivisentini | 4:eaf6c49a86e4 | 233 | typeLength = buffer[index++]; |
giovannivisentini | 4:eaf6c49a86e4 | 234 | if (getSR()) { |
giovannivisentini | 4:eaf6c49a86e4 | 235 | playloadLength = buffer[index++]; |
giovannivisentini | 4:eaf6c49a86e4 | 236 | } else { |
giovannivisentini | 4:eaf6c49a86e4 | 237 | playloadLength = (((uint32_t) buffer[index + 0]) << 24) |
giovannivisentini | 4:eaf6c49a86e4 | 238 | | (((uint32_t) buffer[index + 1]) << 16) |
giovannivisentini | 4:eaf6c49a86e4 | 239 | | (((uint32_t) buffer[index + 2]) << 8) |
giovannivisentini | 4:eaf6c49a86e4 | 240 | | ((uint32_t) buffer[index + 3]); |
giovannivisentini | 4:eaf6c49a86e4 | 241 | index += 4; |
giovannivisentini | 4:eaf6c49a86e4 | 242 | } //if-else |
giovannivisentini | 4:eaf6c49a86e4 | 243 | return index; |
giovannivisentini | 4:eaf6c49a86e4 | 244 | } //loadHeader |
giovannivisentini | 4:eaf6c49a86e4 | 245 | |
giovannivisentini | 4:eaf6c49a86e4 | 246 | |
giovannivisentini | 4:eaf6c49a86e4 | 247 | private: |
giovannivisentini | 4:eaf6c49a86e4 | 248 | uint8_t headerFlags; |
giovannivisentini | 4:eaf6c49a86e4 | 249 | uint8_t typeLength; |
giovannivisentini | 4:eaf6c49a86e4 | 250 | uint32_t playloadLength; |
giovannivisentini | 4:eaf6c49a86e4 | 251 | }; |
giovannivisentini | 4:eaf6c49a86e4 | 252 | |
giovannivisentini | 4:eaf6c49a86e4 | 253 | } /* namespace NDefLib */ |
giovannivisentini | 4:eaf6c49a86e4 | 254 | |
giovannivisentini | 4:eaf6c49a86e4 | 255 | #endif /* NDEFLIB_RECORDHEADER_H_ */ |