-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Request] Format Tag when NdefFormatable is found #34
Comments
So i dove into your code and did it myself. public void WriteTag (NdefLibrary.Ndef.NdefMessage message)
{
if (droidTag == null)
{
throw new Exception("Tag Error: No Tag to write, register to NewTag event before calling WriteTag()");
}
Ndef ndef = GetNdef (droidTag);
//Check if the tag can be NDEFformatted
var formatcheck = nfcTag.TechList.Contains(NFCTechs.NdefFormatable);
//Previous check didnt compare both just ndef being null can also mean its not formatted
if (ndef == null && formatcheck == false)
{
throw new Exception("Tag Error: NDEF not supported");
}
//Not formatted but can be formatted
if (ndef == null && formatcheck == true)
{
NdefFormatable formatable = NdefFormatable.Get(droidTag);
//For some reason this could still give null even if formatcheck gave a true so /shrug
if (formatable == null)
{
throw new Exception("Tag Error: NDEFformat not supported");
}
try
{
formatable.Connect();
RaiseTagConnected(nfcTag);
}
catch
{
throw new Exception("Tag Error: No Tag nearby");
}
//old size check.
//int size = message.ToByteArray().Length;
try
{
List<Android.Nfc.NdefRecord> records = new List<Android.Nfc.NdefRecord>();
for (int i = 0; i < message.Count; i++)
{
if (message[i].CheckIfValid())
records.Add(new Android.Nfc.NdefRecord(Android.Nfc.NdefRecord.TnfWellKnown, message[i].Type, message[i].Id, message[i].Payload));
else
{
throw new Exception("NDEFRecord number " + i + "is not valid");
}
};
Android.Nfc.NdefMessage msg = new Android.Nfc.NdefMessage(records.ToArray());
//This Format works with Mifare Classic and NTAG213. Fails with ultralight. these are the chips I tested it with.
//Both with pre used ones and with factory new ones.
formatable.Format(msg);
}
catch (TagLostException tle)
{
throw new Exception("Tag Lost Error: " + tle.Message);
}
catch (IOException ioe)
{
throw new Exception("Tag IO Error: " + ioe.ToString());
}
catch (Android.Nfc.FormatException fe)
{
throw new Exception("Tag Format Error: " + fe.Message);
}
catch (Exception e)
{
//Assume that if we are here the tag is still touching the device, our message is correct, and the tag isnt busted.
try
{
//we close this tech so we can open it as ultralight
formatable.Close();
//check if the connected chip is ultralight.
if (droidTag.GetTechList().Contains(NFCTechs.MifareUltralight))
{
MifareUltralight ultralight = MifareUltralight.Get(droidTag);
if (ultralight != null)
{
try
{
//connect with ultralight tech
ultralight.Connect();
//Found this on a stackoverflow question that had the same problem, apparently this sets it up to be NFC Forum Type 2 tag.
ultralight.Transceive(new byte[]
{
(byte)0xA2,//Write
(byte)0x03,//Page Nr = 3
(byte)0xE1,(byte)0x10,(byte)0x06, (byte)0x00//capability container (mapping version 1.0, 48 bytes for data available, read/ write allowed)
});
ultralight.Transceive(new byte[]
{
(byte)0xA2,//Write
(byte)0x04,//Page nr = 4
(byte)0x03, (byte)0x00,(byte)0xFE,(byte)0x00 // empty NDEF TLV, Terminator TLV
});
}catch(Exception e1)
{
}
finally
{
//Now the tag is formatted to accept NDEF
try
{
//Close this tech connection as this one doesnt have WriteNdef
ultralight.Close();
//Get the tag as Ndef
ndef = GetNdef(droidTag);
//Connect
ndef.Connect();
//Check the message again JIC
List<Android.Nfc.NdefRecord> recordsFormat = new List<Android.Nfc.NdefRecord>();
for (int i = 0; i < message.Count; i++)
{
if (message[i].CheckIfValid())
recordsFormat.Add(new Android.Nfc.NdefRecord(Android.Nfc.NdefRecord.TnfWellKnown, message[i].Type, message[i].Id, message[i].Payload));
else
{
throw new Exception("NDEFRecord number " + i + "is not valid");
}
};
Android.Nfc.NdefMessage msg = new Android.Nfc.NdefMessage(recordsFormat.ToArray());
//Write and close
ndef.WriteNdefMessage(msg);
ndef.Close();
}
catch
{
}
}
}
}
}
catch(Exception eform)
{
//
throw new Exception("Tag Error: " + eform.ToString());
}
}
finally
{
//Used to not have the ultralight code in so i had to close here
//formatable.Close();
RaiseTagTagDisconnected(nfcTag);
}
}
else
{
//Rest as normal
try
{
ndef.Connect();
RaiseTagConnected(nfcTag);
}
catch
{
throw new Exception("Tag Error: No Tag nearby");
}
if (!ndef.IsWritable)
{
ndef.Close();
throw new Exception("Tag Error: Tag is write locked");
}
int size = message.ToByteArray().Length;
if (ndef.MaxSize < size)
{
ndef.Close();
throw new Exception("Tag Error: Tag is too small");
}
else
{
try
{
List<Android.Nfc.NdefRecord> records = new List<Android.Nfc.NdefRecord>();
for (int i = 0; i < message.Count; i++)
{
if (message[i].CheckIfValid())
records.Add(new Android.Nfc.NdefRecord(Android.Nfc.NdefRecord.TnfWellKnown, message[i].Type, message[i].Id, message[i].Payload));
else
{
throw new Exception("NDEFRecord number " + i + "is not valid");
}
};
Android.Nfc.NdefMessage msg = new Android.Nfc.NdefMessage(records.ToArray());
ndef.WriteNdefMessage(msg);
}
catch (TagLostException tle)
{
throw new Exception("Tag Lost Error: " + tle.Message);
}
catch (IOException ioe)
{
throw new Exception("Tag IO Error: " + ioe.ToString());
}
catch (Android.Nfc.FormatException fe)
{
throw new Exception("Tag Format Error: " + fe.Message);
}
catch (Exception e)
{
throw new Exception("Tag Error: " + e.ToString());
}
finally
{
ndef.Close();
RaiseTagTagDisconnected(nfcTag);
}
}
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Like the title says. It would be grand if the WriteTag would include a check if NdefFormatable is present and write to the chip using Android.Nfc.Tech.NdefFormatable.Format.
The text was updated successfully, but these errors were encountered: