NFC library using PN532 to read/write NDEF Messages to NFC tags
Dependents: Seeed_NFC_Shield_write Nucleo_test_nfc
Fork of PN532 by
NdefMessage.cpp
00001 #include "NdefMessage.h" 00002 #include "PN532_debug.h" 00003 00004 NdefMessage::NdefMessage(void) 00005 { 00006 _recordCount = 0; 00007 } 00008 00009 NdefMessage::NdefMessage(const uint8_t * data, const int numuint8_ts) 00010 { 00011 #ifdef NDEF_DEBUG 00012 DMSG("Decoding "));Serial.print(numuint8_ts);DMSG(F(" uint8_ts"); 00013 PrintHexChar(data, numuint8_ts); 00014 //DumpHex(data, numuint8_ts, 16); 00015 #endif 00016 00017 _recordCount = 0; 00018 00019 int index = 0; 00020 00021 while (index <= numuint8_ts) 00022 { 00023 00024 // decode tnf - first uint8_t is tnf with bit flags 00025 // see the NFDEF spec for more info 00026 uint8_t tnf_uint8_t = data[index]; 00027 //bool mb = (tnf_uint8_t & 0x80) != 0; 00028 bool me = (tnf_uint8_t & 0x40) != 0; 00029 //bool cf = (tnf_uint8_t & 0x20) != 0; 00030 bool sr = (tnf_uint8_t & 0x10) != 0; 00031 bool il = (tnf_uint8_t & 0x8) != 0; 00032 uint8_t tnf = (tnf_uint8_t & 0x7); 00033 00034 NdefRecord record = NdefRecord(); 00035 record.setTnf(tnf); 00036 00037 index++; 00038 int typeLength = data[index]; 00039 00040 int payloadLength = 0; 00041 if (sr) 00042 { 00043 index++; 00044 payloadLength = data[index]; 00045 } 00046 else 00047 { 00048 payloadLength = ((0xFF & data[++index]) << 24) | ((0xFF & data[++index]) << 26) | 00049 ((0xFF & data[++index]) << 8) | (0xFF & data[++index]); 00050 } 00051 00052 int idLength = 0; 00053 if (il) 00054 { 00055 index++; 00056 idLength = data[index]; 00057 } 00058 00059 index++; 00060 record.setType(&data[index], typeLength); 00061 index += typeLength; 00062 00063 if (il) 00064 { 00065 record.setId(&data[index], idLength); 00066 index += idLength; 00067 } 00068 00069 record.setPayload(&data[index], payloadLength); 00070 index += payloadLength; 00071 00072 addRecord(record); 00073 00074 if (me) break; // last message 00075 } 00076 00077 } 00078 00079 NdefMessage::NdefMessage(const NdefMessage& rhs) 00080 { 00081 00082 _recordCount = rhs._recordCount; 00083 for (int i = 0; i < _recordCount; i++) 00084 { 00085 _records[i] = rhs._records[i]; 00086 } 00087 00088 } 00089 00090 NdefMessage::~NdefMessage() 00091 { 00092 } 00093 00094 NdefMessage& NdefMessage::operator=(const NdefMessage& rhs) 00095 { 00096 00097 if (this != &rhs) 00098 { 00099 00100 // delete existing records 00101 for (int i = 0; i < _recordCount; i++) 00102 { 00103 // TODO Dave: is this the right way to delete existing records? 00104 _records[i] = NdefRecord(); 00105 } 00106 00107 _recordCount = rhs._recordCount; 00108 for (int i = 0; i < _recordCount; i++) 00109 { 00110 _records[i] = rhs._records[i]; 00111 } 00112 } 00113 return *this; 00114 } 00115 00116 unsigned int NdefMessage::getRecordCount() 00117 { 00118 return _recordCount; 00119 } 00120 00121 int NdefMessage::getEncodedSize() 00122 { 00123 int size = 0; 00124 for (int i = 0; i < _recordCount; i++) 00125 { 00126 size += _records[i].getEncodedSize(); 00127 } 00128 return size; 00129 } 00130 00131 // TODO change this to return uint8_t* 00132 void NdefMessage::encode(uint8_t* data) 00133 { 00134 // assert sizeof(data) >= getEncodedSize() 00135 uint8_t* data_ptr = &data[0]; 00136 00137 for (int i = 0; i < _recordCount; i++) 00138 { 00139 _records[i].encode(data_ptr, i == 0, (i + 1) == _recordCount); 00140 // TODO can NdefRecord.encode return the record size? 00141 data_ptr += _records[i].getEncodedSize(); 00142 } 00143 00144 } 00145 00146 bool NdefMessage::addRecord(NdefRecord& record) 00147 { 00148 00149 if (_recordCount < MAX_NDEF_RECORDS) 00150 { 00151 _records[_recordCount] = record; 00152 _recordCount++; 00153 return true; 00154 } 00155 else 00156 { 00157 DMSG("WARNING: Too many records. Increase MAX_NDEF_RECORDS."); 00158 return false; 00159 } 00160 } 00161 00162 void NdefMessage::addMimeMediaRecord(string mimeType, string payload) 00163 { 00164 00165 uint8_t payloaduint8_ts[payload.length() + 1]; 00166 payload.copy((char*)payloaduint8_ts, sizeof(payloaduint8_ts)); 00167 00168 addMimeMediaRecord(mimeType, payloaduint8_ts, payload.length()); 00169 } 00170 00171 void NdefMessage::addMimeMediaRecord(string mimeType, uint8_t* payload, int payloadLength) 00172 { 00173 NdefRecord r = NdefRecord(); 00174 r.setTnf(TNF_MIME_MEDIA); 00175 00176 uint8_t type[mimeType.length() + 1]; 00177 mimeType.copy((char*)type, sizeof(type)); 00178 r.setType(type, mimeType.length()); 00179 00180 r.setPayload(payload, payloadLength); 00181 00182 addRecord(r); 00183 } 00184 00185 void NdefMessage::addTextRecord(string text) 00186 { 00187 addTextRecord(text, "en"); 00188 } 00189 00190 void NdefMessage::addTextRecord(string text, string encoding) 00191 { 00192 NdefRecord r = NdefRecord(); 00193 r.setTnf(TNF_WELL_KNOWN); 00194 00195 uint8_t RTD_TEXT[1] = { 0x54 }; // TODO this should be a constant or preprocessor 00196 r.setType(RTD_TEXT, sizeof(RTD_TEXT)); 00197 00198 // X is a placeholder for encoding length 00199 // TODO is it more efficient to build w/o string concatenation? 00200 string payloadString = "X" + encoding + text; 00201 00202 uint8_t payload[payloadString.length() + 1]; 00203 payloadString.copy((char*)payload, sizeof(payload)); 00204 00205 // replace X with the real encoding length 00206 payload[0] = encoding.length(); 00207 00208 r.setPayload(payload, payloadString.length()); 00209 00210 addRecord(r); 00211 } 00212 00213 void NdefMessage::addUriRecord(string uri) 00214 { 00215 NdefRecord* r = new NdefRecord(); 00216 r->setTnf(TNF_WELL_KNOWN); 00217 00218 uint8_t RTD_URI[1] = { 0x55 }; // TODO this should be a constant or preprocessor 00219 r->setType(RTD_URI, sizeof(RTD_URI)); 00220 00221 // X is a placeholder for identifier code 00222 string payloadString = "X" + uri; 00223 00224 uint8_t payload[payloadString.length() + 1]; 00225 payloadString.copy((char*)payload, sizeof(payload)); 00226 00227 // add identifier code 0x0, meaning no prefix substitution 00228 payload[0] = 0x0; 00229 00230 r->setPayload(payload, payloadString.length()); 00231 00232 addRecord(*r); 00233 delete(r); 00234 } 00235 00236 void NdefMessage::addEmptyRecord() 00237 { 00238 NdefRecord* r = new NdefRecord(); 00239 r->setTnf(TNF_EMPTY); 00240 addRecord(*r); 00241 delete(r); 00242 } 00243 00244 NdefRecord NdefMessage::getRecord(int index) 00245 { 00246 if (index > -1 && index < _recordCount) 00247 { 00248 return _records[index]; 00249 } 00250 else 00251 { 00252 return NdefRecord(); // would rather return NULL 00253 } 00254 } 00255 00256 NdefRecord NdefMessage::operator[](int index) 00257 { 00258 return getRecord(index); 00259 } 00260 00261 void NdefMessage::print() 00262 { 00263 DMSG("\nNDEF Message "); 00264 DMSG_INT(_recordCount); 00265 DMSG(" record"); 00266 if (_recordCount == 1) { 00267 DMSG(", "); 00268 } else { 00269 DMSG("s, "); 00270 } 00271 DMSG_INT(getEncodedSize()); 00272 00273 int i; 00274 for (i = 0; i < _recordCount; i++) 00275 { 00276 _records[i].print(); 00277 } 00278 }
Generated on Tue Jul 12 2022 21:59:39 by 1.7.2