to colorize a colorful pixel with a simple touch using nfc technology

Dependencies:   Chainable_RGB_LED mbed

use Arch, NFC Shield and Grove - Chainable RGB LED to DIY a touch pixel. Then use an Android with NFC support to colorize it.

The project is on https://github.com/Seeed-Studio/TouchPixel

Committer:
yihui
Date:
Fri Dec 27 01:46:32 2013 +0000
Revision:
0:88960f3eeb2c
initial

Who changed what in which revision?

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