Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PN532 by
NdefMessage.cpp@5:51f820fbd18a, 2014-10-07 (annotated)
- Committer:
- icefeet
- Date:
- Tue Oct 07 15:09:46 2014 +0000
- Revision:
- 5:51f820fbd18a
- Parent:
- 3:4189a10038e6
Added support for Ultralight Write
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| yihui | 3:4189a10038e6 | 1 | #include "NdefMessage.h" |
| yihui | 3:4189a10038e6 | 2 | #include "PN532_debug.h" |
| yihui | 3:4189a10038e6 | 3 | |
| yihui | 3:4189a10038e6 | 4 | NdefMessage::NdefMessage(void) |
| yihui | 3:4189a10038e6 | 5 | { |
| yihui | 3:4189a10038e6 | 6 | _recordCount = 0; |
| yihui | 3:4189a10038e6 | 7 | } |
| yihui | 3:4189a10038e6 | 8 | |
| yihui | 3:4189a10038e6 | 9 | NdefMessage::NdefMessage(const uint8_t * data, const int numuint8_ts) |
| yihui | 3:4189a10038e6 | 10 | { |
| yihui | 3:4189a10038e6 | 11 | #ifdef NDEF_DEBUG |
| yihui | 3:4189a10038e6 | 12 | DMSG("Decoding "));Serial.print(numuint8_ts);DMSG(F(" uint8_ts"); |
| yihui | 3:4189a10038e6 | 13 | PrintHexChar(data, numuint8_ts); |
| yihui | 3:4189a10038e6 | 14 | //DumpHex(data, numuint8_ts, 16); |
| yihui | 3:4189a10038e6 | 15 | #endif |
| yihui | 3:4189a10038e6 | 16 | |
| yihui | 3:4189a10038e6 | 17 | _recordCount = 0; |
| yihui | 3:4189a10038e6 | 18 | |
| yihui | 3:4189a10038e6 | 19 | int index = 0; |
| yihui | 3:4189a10038e6 | 20 | |
| yihui | 3:4189a10038e6 | 21 | while (index <= numuint8_ts) |
| yihui | 3:4189a10038e6 | 22 | { |
| yihui | 3:4189a10038e6 | 23 | |
| yihui | 3:4189a10038e6 | 24 | // decode tnf - first uint8_t is tnf with bit flags |
| yihui | 3:4189a10038e6 | 25 | // see the NFDEF spec for more info |
| yihui | 3:4189a10038e6 | 26 | uint8_t tnf_uint8_t = data[index]; |
| yihui | 3:4189a10038e6 | 27 | bool mb = (tnf_uint8_t & 0x80) != 0; |
| yihui | 3:4189a10038e6 | 28 | bool me = (tnf_uint8_t & 0x40) != 0; |
| yihui | 3:4189a10038e6 | 29 | bool cf = (tnf_uint8_t & 0x20) != 0; |
| yihui | 3:4189a10038e6 | 30 | bool sr = (tnf_uint8_t & 0x10) != 0; |
| yihui | 3:4189a10038e6 | 31 | bool il = (tnf_uint8_t & 0x8) != 0; |
| yihui | 3:4189a10038e6 | 32 | uint8_t tnf = (tnf_uint8_t & 0x7); |
| yihui | 3:4189a10038e6 | 33 | |
| yihui | 3:4189a10038e6 | 34 | NdefRecord record = NdefRecord(); |
| yihui | 3:4189a10038e6 | 35 | record.setTnf(tnf); |
| yihui | 3:4189a10038e6 | 36 | |
| yihui | 3:4189a10038e6 | 37 | index++; |
| yihui | 3:4189a10038e6 | 38 | int typeLength = data[index]; |
| yihui | 3:4189a10038e6 | 39 | |
| yihui | 3:4189a10038e6 | 40 | int payloadLength = 0; |
| yihui | 3:4189a10038e6 | 41 | if (sr) |
| yihui | 3:4189a10038e6 | 42 | { |
| yihui | 3:4189a10038e6 | 43 | index++; |
| yihui | 3:4189a10038e6 | 44 | payloadLength = data[index]; |
| yihui | 3:4189a10038e6 | 45 | } |
| yihui | 3:4189a10038e6 | 46 | else |
| yihui | 3:4189a10038e6 | 47 | { |
| yihui | 3:4189a10038e6 | 48 | payloadLength = ((0xFF & data[++index]) << 24) | ((0xFF & data[++index]) << 26) | |
| yihui | 3:4189a10038e6 | 49 | ((0xFF & data[++index]) << 8) | (0xFF & data[++index]); |
| yihui | 3:4189a10038e6 | 50 | } |
| yihui | 3:4189a10038e6 | 51 | |
| yihui | 3:4189a10038e6 | 52 | int idLength = 0; |
| yihui | 3:4189a10038e6 | 53 | if (il) |
| yihui | 3:4189a10038e6 | 54 | { |
| yihui | 3:4189a10038e6 | 55 | index++; |
| yihui | 3:4189a10038e6 | 56 | idLength = data[index]; |
| yihui | 3:4189a10038e6 | 57 | } |
| yihui | 3:4189a10038e6 | 58 | |
| yihui | 3:4189a10038e6 | 59 | index++; |
| yihui | 3:4189a10038e6 | 60 | record.setType(&data[index], typeLength); |
| yihui | 3:4189a10038e6 | 61 | index += typeLength; |
| yihui | 3:4189a10038e6 | 62 | |
| yihui | 3:4189a10038e6 | 63 | if (il) |
| yihui | 3:4189a10038e6 | 64 | { |
| yihui | 3:4189a10038e6 | 65 | record.setId(&data[index], idLength); |
| yihui | 3:4189a10038e6 | 66 | index += idLength; |
| yihui | 3:4189a10038e6 | 67 | } |
| yihui | 3:4189a10038e6 | 68 | |
| yihui | 3:4189a10038e6 | 69 | record.setPayload(&data[index], payloadLength); |
| yihui | 3:4189a10038e6 | 70 | index += payloadLength; |
| yihui | 3:4189a10038e6 | 71 | |
| yihui | 3:4189a10038e6 | 72 | addRecord(record); |
| yihui | 3:4189a10038e6 | 73 | |
| yihui | 3:4189a10038e6 | 74 | if (me) break; // last message |
| yihui | 3:4189a10038e6 | 75 | } |
| yihui | 3:4189a10038e6 | 76 | |
| yihui | 3:4189a10038e6 | 77 | } |
| yihui | 3:4189a10038e6 | 78 | |
| yihui | 3:4189a10038e6 | 79 | NdefMessage::NdefMessage(const NdefMessage& rhs) |
| yihui | 3:4189a10038e6 | 80 | { |
| yihui | 3:4189a10038e6 | 81 | |
| yihui | 3:4189a10038e6 | 82 | _recordCount = rhs._recordCount; |
| yihui | 3:4189a10038e6 | 83 | for (int i = 0; i < _recordCount; i++) |
| yihui | 3:4189a10038e6 | 84 | { |
| yihui | 3:4189a10038e6 | 85 | _records[i] = rhs._records[i]; |
| yihui | 3:4189a10038e6 | 86 | } |
| yihui | 3:4189a10038e6 | 87 | |
| yihui | 3:4189a10038e6 | 88 | } |
| yihui | 3:4189a10038e6 | 89 | |
| yihui | 3:4189a10038e6 | 90 | NdefMessage::~NdefMessage() |
| yihui | 3:4189a10038e6 | 91 | { |
| yihui | 3:4189a10038e6 | 92 | } |
| yihui | 3:4189a10038e6 | 93 | |
| yihui | 3:4189a10038e6 | 94 | NdefMessage& NdefMessage::operator=(const NdefMessage& rhs) |
| yihui | 3:4189a10038e6 | 95 | { |
| yihui | 3:4189a10038e6 | 96 | |
| yihui | 3:4189a10038e6 | 97 | if (this != &rhs) |
| yihui | 3:4189a10038e6 | 98 | { |
| yihui | 3:4189a10038e6 | 99 | |
| yihui | 3:4189a10038e6 | 100 | // delete existing records |
| yihui | 3:4189a10038e6 | 101 | for (int i = 0; i < _recordCount; i++) |
| yihui | 3:4189a10038e6 | 102 | { |
| yihui | 3:4189a10038e6 | 103 | // TODO Dave: is this the right way to delete existing records? |
| yihui | 3:4189a10038e6 | 104 | _records[i] = NdefRecord(); |
| yihui | 3:4189a10038e6 | 105 | } |
| yihui | 3:4189a10038e6 | 106 | |
| yihui | 3:4189a10038e6 | 107 | _recordCount = rhs._recordCount; |
| yihui | 3:4189a10038e6 | 108 | for (int i = 0; i < _recordCount; i++) |
| yihui | 3:4189a10038e6 | 109 | { |
| yihui | 3:4189a10038e6 | 110 | _records[i] = rhs._records[i]; |
| yihui | 3:4189a10038e6 | 111 | } |
| yihui | 3:4189a10038e6 | 112 | } |
| yihui | 3:4189a10038e6 | 113 | return *this; |
| yihui | 3:4189a10038e6 | 114 | } |
| yihui | 3:4189a10038e6 | 115 | |
| yihui | 3:4189a10038e6 | 116 | unsigned int NdefMessage::getRecordCount() |
| yihui | 3:4189a10038e6 | 117 | { |
| yihui | 3:4189a10038e6 | 118 | return _recordCount; |
| yihui | 3:4189a10038e6 | 119 | } |
| yihui | 3:4189a10038e6 | 120 | |
| yihui | 3:4189a10038e6 | 121 | int NdefMessage::getEncodedSize() |
| yihui | 3:4189a10038e6 | 122 | { |
| yihui | 3:4189a10038e6 | 123 | int size = 0; |
| yihui | 3:4189a10038e6 | 124 | for (int i = 0; i < _recordCount; i++) |
| yihui | 3:4189a10038e6 | 125 | { |
| yihui | 3:4189a10038e6 | 126 | size += _records[i].getEncodedSize(); |
| yihui | 3:4189a10038e6 | 127 | } |
| yihui | 3:4189a10038e6 | 128 | return size; |
| yihui | 3:4189a10038e6 | 129 | } |
| yihui | 3:4189a10038e6 | 130 | |
| yihui | 3:4189a10038e6 | 131 | // TODO change this to return uint8_t* |
| yihui | 3:4189a10038e6 | 132 | void NdefMessage::encode(uint8_t* data) |
| yihui | 3:4189a10038e6 | 133 | { |
| yihui | 3:4189a10038e6 | 134 | // assert sizeof(data) >= getEncodedSize() |
| yihui | 3:4189a10038e6 | 135 | uint8_t* data_ptr = &data[0]; |
| yihui | 3:4189a10038e6 | 136 | |
| yihui | 3:4189a10038e6 | 137 | for (int i = 0; i < _recordCount; i++) |
| yihui | 3:4189a10038e6 | 138 | { |
| yihui | 3:4189a10038e6 | 139 | _records[i].encode(data_ptr, i == 0, (i + 1) == _recordCount); |
| yihui | 3:4189a10038e6 | 140 | // TODO can NdefRecord.encode return the record size? |
| yihui | 3:4189a10038e6 | 141 | data_ptr += _records[i].getEncodedSize(); |
| yihui | 3:4189a10038e6 | 142 | } |
| yihui | 3:4189a10038e6 | 143 | |
| yihui | 3:4189a10038e6 | 144 | } |
| yihui | 3:4189a10038e6 | 145 | |
| yihui | 3:4189a10038e6 | 146 | bool NdefMessage::addRecord(NdefRecord& record) |
| yihui | 3:4189a10038e6 | 147 | { |
| yihui | 3:4189a10038e6 | 148 | |
| yihui | 3:4189a10038e6 | 149 | if (_recordCount < MAX_NDEF_RECORDS) |
| yihui | 3:4189a10038e6 | 150 | { |
| yihui | 3:4189a10038e6 | 151 | _records[_recordCount] = record; |
| yihui | 3:4189a10038e6 | 152 | _recordCount++; |
| yihui | 3:4189a10038e6 | 153 | return true; |
| yihui | 3:4189a10038e6 | 154 | } |
| yihui | 3:4189a10038e6 | 155 | else |
| yihui | 3:4189a10038e6 | 156 | { |
| yihui | 3:4189a10038e6 | 157 | DMSG("WARNING: Too many records. Increase MAX_NDEF_RECORDS."); |
| yihui | 3:4189a10038e6 | 158 | return false; |
| yihui | 3:4189a10038e6 | 159 | } |
| yihui | 3:4189a10038e6 | 160 | } |
| yihui | 3:4189a10038e6 | 161 | |
| yihui | 3:4189a10038e6 | 162 | void NdefMessage::addMimeMediaRecord(string mimeType, string payload) |
| yihui | 3:4189a10038e6 | 163 | { |
| yihui | 3:4189a10038e6 | 164 | |
| yihui | 3:4189a10038e6 | 165 | uint8_t payloaduint8_ts[payload.length() + 1]; |
| yihui | 3:4189a10038e6 | 166 | payload.copy((char*)payloaduint8_ts, sizeof(payloaduint8_ts)); |
| yihui | 3:4189a10038e6 | 167 | |
| yihui | 3:4189a10038e6 | 168 | addMimeMediaRecord(mimeType, payloaduint8_ts, payload.length()); |
| yihui | 3:4189a10038e6 | 169 | } |
| yihui | 3:4189a10038e6 | 170 | |
| yihui | 3:4189a10038e6 | 171 | void NdefMessage::addMimeMediaRecord(string mimeType, uint8_t* payload, int payloadLength) |
| yihui | 3:4189a10038e6 | 172 | { |
| yihui | 3:4189a10038e6 | 173 | NdefRecord r = NdefRecord(); |
| yihui | 3:4189a10038e6 | 174 | r.setTnf(TNF_MIME_MEDIA); |
| yihui | 3:4189a10038e6 | 175 | |
| yihui | 3:4189a10038e6 | 176 | uint8_t type[mimeType.length() + 1]; |
| yihui | 3:4189a10038e6 | 177 | mimeType.copy((char*)type, sizeof(type)); |
| yihui | 3:4189a10038e6 | 178 | r.setType(type, mimeType.length()); |
| yihui | 3:4189a10038e6 | 179 | |
| yihui | 3:4189a10038e6 | 180 | r.setPayload(payload, payloadLength); |
| yihui | 3:4189a10038e6 | 181 | |
| yihui | 3:4189a10038e6 | 182 | addRecord(r); |
| yihui | 3:4189a10038e6 | 183 | } |
| yihui | 3:4189a10038e6 | 184 | |
| yihui | 3:4189a10038e6 | 185 | void NdefMessage::addTextRecord(string text) |
| yihui | 3:4189a10038e6 | 186 | { |
| yihui | 3:4189a10038e6 | 187 | addTextRecord(text, "en"); |
| yihui | 3:4189a10038e6 | 188 | } |
| yihui | 3:4189a10038e6 | 189 | |
| yihui | 3:4189a10038e6 | 190 | void NdefMessage::addTextRecord(string text, string encoding) |
| yihui | 3:4189a10038e6 | 191 | { |
| yihui | 3:4189a10038e6 | 192 | NdefRecord r = NdefRecord(); |
| yihui | 3:4189a10038e6 | 193 | r.setTnf(TNF_WELL_KNOWN); |
| yihui | 3:4189a10038e6 | 194 | |
| yihui | 3:4189a10038e6 | 195 | uint8_t RTD_TEXT[1] = { 0x54 }; // TODO this should be a constant or preprocessor |
| yihui | 3:4189a10038e6 | 196 | r.setType(RTD_TEXT, sizeof(RTD_TEXT)); |
| yihui | 3:4189a10038e6 | 197 | |
| yihui | 3:4189a10038e6 | 198 | // X is a placeholder for encoding length |
| yihui | 3:4189a10038e6 | 199 | // TODO is it more efficient to build w/o string concatenation? |
| yihui | 3:4189a10038e6 | 200 | string payloadString = "X" + encoding + text; |
| yihui | 3:4189a10038e6 | 201 | |
| yihui | 3:4189a10038e6 | 202 | uint8_t payload[payloadString.length() + 1]; |
| yihui | 3:4189a10038e6 | 203 | payloadString.copy((char*)payload, sizeof(payload)); |
| yihui | 3:4189a10038e6 | 204 | |
| yihui | 3:4189a10038e6 | 205 | // replace X with the real encoding length |
| yihui | 3:4189a10038e6 | 206 | payload[0] = encoding.length(); |
| yihui | 3:4189a10038e6 | 207 | |
| yihui | 3:4189a10038e6 | 208 | r.setPayload(payload, payloadString.length()); |
| yihui | 3:4189a10038e6 | 209 | |
| yihui | 3:4189a10038e6 | 210 | addRecord(r); |
| yihui | 3:4189a10038e6 | 211 | } |
| yihui | 3:4189a10038e6 | 212 | |
| yihui | 3:4189a10038e6 | 213 | void NdefMessage::addUriRecord(string uri) |
| yihui | 3:4189a10038e6 | 214 | { |
| yihui | 3:4189a10038e6 | 215 | NdefRecord* r = new NdefRecord(); |
| yihui | 3:4189a10038e6 | 216 | r->setTnf(TNF_WELL_KNOWN); |
| yihui | 3:4189a10038e6 | 217 | |
| yihui | 3:4189a10038e6 | 218 | uint8_t RTD_URI[1] = { 0x55 }; // TODO this should be a constant or preprocessor |
| yihui | 3:4189a10038e6 | 219 | r->setType(RTD_URI, sizeof(RTD_URI)); |
| yihui | 3:4189a10038e6 | 220 | |
| yihui | 3:4189a10038e6 | 221 | // X is a placeholder for identifier code |
| yihui | 3:4189a10038e6 | 222 | string payloadString = "X" + uri; |
| yihui | 3:4189a10038e6 | 223 | |
| yihui | 3:4189a10038e6 | 224 | uint8_t payload[payloadString.length() + 1]; |
| yihui | 3:4189a10038e6 | 225 | payloadString.copy((char*)payload, sizeof(payload)); |
| yihui | 3:4189a10038e6 | 226 | |
| yihui | 3:4189a10038e6 | 227 | // add identifier code 0x0, meaning no prefix substitution |
| yihui | 3:4189a10038e6 | 228 | payload[0] = 0x0; |
| yihui | 3:4189a10038e6 | 229 | |
| yihui | 3:4189a10038e6 | 230 | r->setPayload(payload, payloadString.length()); |
| yihui | 3:4189a10038e6 | 231 | |
| yihui | 3:4189a10038e6 | 232 | addRecord(*r); |
| yihui | 3:4189a10038e6 | 233 | delete(r); |
| yihui | 3:4189a10038e6 | 234 | } |
| yihui | 3:4189a10038e6 | 235 | |
| yihui | 3:4189a10038e6 | 236 | void NdefMessage::addEmptyRecord() |
| yihui | 3:4189a10038e6 | 237 | { |
| yihui | 3:4189a10038e6 | 238 | NdefRecord* r = new NdefRecord(); |
| yihui | 3:4189a10038e6 | 239 | r->setTnf(TNF_EMPTY); |
| yihui | 3:4189a10038e6 | 240 | addRecord(*r); |
| yihui | 3:4189a10038e6 | 241 | delete(r); |
| yihui | 3:4189a10038e6 | 242 | } |
| yihui | 3:4189a10038e6 | 243 | |
| yihui | 3:4189a10038e6 | 244 | NdefRecord NdefMessage::getRecord(int index) |
| yihui | 3:4189a10038e6 | 245 | { |
| yihui | 3:4189a10038e6 | 246 | if (index > -1 && index < _recordCount) |
| yihui | 3:4189a10038e6 | 247 | { |
| yihui | 3:4189a10038e6 | 248 | return _records[index]; |
| yihui | 3:4189a10038e6 | 249 | } |
| yihui | 3:4189a10038e6 | 250 | else |
| yihui | 3:4189a10038e6 | 251 | { |
| yihui | 3:4189a10038e6 | 252 | return NdefRecord(); // would rather return NULL |
| yihui | 3:4189a10038e6 | 253 | } |
| yihui | 3:4189a10038e6 | 254 | } |
| yihui | 3:4189a10038e6 | 255 | |
| yihui | 3:4189a10038e6 | 256 | NdefRecord NdefMessage::operator[](int index) |
| yihui | 3:4189a10038e6 | 257 | { |
| yihui | 3:4189a10038e6 | 258 | return getRecord(index); |
| yihui | 3:4189a10038e6 | 259 | } |
| yihui | 3:4189a10038e6 | 260 | |
| yihui | 3:4189a10038e6 | 261 | void NdefMessage::print() |
| yihui | 3:4189a10038e6 | 262 | { |
| yihui | 3:4189a10038e6 | 263 | DMSG("\nNDEF Message "); |
| yihui | 3:4189a10038e6 | 264 | DMSG_INT(_recordCount); |
| yihui | 3:4189a10038e6 | 265 | DMSG(" record"); |
| yihui | 3:4189a10038e6 | 266 | if (_recordCount == 1) { |
| yihui | 3:4189a10038e6 | 267 | DMSG(", "); |
| yihui | 3:4189a10038e6 | 268 | } else { |
| yihui | 3:4189a10038e6 | 269 | DMSG("s, "); |
| yihui | 3:4189a10038e6 | 270 | } |
| yihui | 3:4189a10038e6 | 271 | DMSG_INT(getEncodedSize()); |
| yihui | 3:4189a10038e6 | 272 | |
| yihui | 3:4189a10038e6 | 273 | int i; |
| yihui | 3:4189a10038e6 | 274 | for (i = 0; i < _recordCount; i++) |
| yihui | 3:4189a10038e6 | 275 | { |
| yihui | 3:4189a10038e6 | 276 | _records[i].print(); |
| yihui | 3:4189a10038e6 | 277 | } |
| yihui | 3:4189a10038e6 | 278 | } |
