protected override bool WriteContent(byte[] ndef_content) { Trace.WriteLine("Writing the NFC Forum type 2 Tag"); if (ndef_content == null) { return(false); } /* Get the new NDEF TLV to store into the Tag */ NfcTlv ndef_tlv = new NfcTlv(NDEF_MESSAGE_TLV, ndef_content); /* Remove the Terminator TLV (if some) */ while ((_tlvs.Count > 0) && (_tlvs[_tlvs.Count - 1].T == TERMINATOR_TLV)) { _tlvs.RemoveAt(_tlvs.Count - 1); } /* Where shall I put the NDEF TLV in the Tag ? */ if (_tlvs.Count == 0) { _tlvs.Add(ndef_tlv); } else { for (int i = 0; i < _tlvs.Count; i++) { if (_tlvs[i].T == NDEF_MESSAGE_TLV) { /* Replace this one */ _tlvs[i] = ndef_tlv; ndef_tlv = null; break; } } if (ndef_tlv != null) { /* No NDEF in the Tag beforehand? Let's add it the the end */ _tlvs.Add(ndef_tlv); } } CardBuffer actual_content = new CardBuffer(); for (int i = 0; i < _tlvs.Count; i++) { actual_content.Append(_tlvs[i].Serialize()); } if (actual_content.Length > Capacity()) { Trace.WriteLine("The size of the content (with its TLVs) is bigger than the tag's capacity"); return(false); } if ((actual_content.Length + 2) < Capacity()) { /* Add a Terminator at the end */ Trace.WriteLine("We add a TERMINATOR TLV at the end of the Tag"); actual_content.Append((new NfcTlv(TERMINATOR_TLV, null)).Serialize()); } /* And now write */ ushort page = 4; for (long i = 0; i < actual_content.Length; i += 4) { byte[] buffer = new byte[4]; for (long j = 0; j < 4; j++) { if ((i + j) < actual_content.Length) { buffer[j] = actual_content.GetByte(i + j); } } if (!WriteBinary(_channel, page, buffer)) { return(false); } page++; } return(true); }
protected override bool Read() { Trace.WriteLine("Reading the NFC Forum type 2 Tag"); ushort page = 0; if (!Recognize(_channel, ref _formatted, ref _formattable, ref _locked)) { return(false); } CardBuffer buffer = new CardBuffer(); for (page = 0; page < 256; page += 4) { byte[] data = ReadBinary(_channel, page, READ_4_PAGES); if (data == null) { break; } if (page > 0) { bool same_as_header = true; for (int i = 0; i < OFFSET_USER_DATA; i++) { if (data[i] != buffer.GetByte(i)) { same_as_header = false; break; } } if (same_as_header) { break; } } buffer.Append(data); } Trace.WriteLine("Read " + buffer.Length + "B of data from the Tag"); _raw_data = buffer.GetBytes(); _capacity = _raw_data.Length; if (_capacity <= OFFSET_USER_DATA) { _capacity = 0; return(false); } if (!_formatted) { /* Guess the capacity from the read area */ if ((_capacity > 64) && !_formatted) { /* Drop the 16 last bytes if they are not empty (locks on Mifare UltraLight C) */ bool locks_found = false; for (long i = _capacity - 16; i < _capacity; i++) { if (_raw_data[i] != 0) { locks_found = true; break; } } if (locks_found) { Trace.WriteLine("Locks found at the end"); _capacity -= 16; } } _capacity -= OFFSET_USER_DATA; Trace.WriteLine("The Tag is not formatted, capacity=" + _capacity + "B"); } else { /* Read the capacity in the CC */ _capacity = 8 * _raw_data[14]; Trace.WriteLine("The Tag is formatted, capacity read from the CC=" + _capacity + "B"); } /* Is the tag empty ? */ _is_empty = true; for (long i = 0; i < _capacity; i++) { if (_raw_data[OFFSET_USER_DATA + i] != 0) { _is_empty = false; break; } } if (_is_empty) { Trace.WriteLine("The Tag is empty"); return(true); } byte[] ndef_data = null; if (!ParseUserData(buffer.GetBytes(OFFSET_USER_DATA, -1), ref ndef_data)) { Trace.WriteLine("The parsing of the Tag failed"); return(false); } if (ndef_data == null) { Trace.WriteLine("The Tag doesn't contain a NDEF"); _is_empty = true; return(true); } _is_empty = false; Ndef[] t = Ndef.Parse(ndef_data); if (t == null) { Trace.WriteLine("The NDEF is invalid or unsupported"); return(false); } Trace.WriteLine(t.Length + " NDEF record(s) found in the Tag"); /* This NDEF is the new content of the tag */ Content.Clear(); for (int i = 0; i < t.Length; i++) { Content.Add(t[i]); } return(true); }