Wie schreibt man einen Tag, damit ein Abbruch nicht als gültig durchgeht?
Setzen Sie die Länge der Nachricht zuerst auf null, schreiben Sie die Nachricht, und schreiben Sie die wirkliche Länge zuletzt. Ein Abbruch vor dem letzten Schritt hinterlässt einen Tag, der leer gelesen wird, statt einer Länge, die Bytes ankündigt, die nie ankamen. Der quelloffene NFC-Stack von Android schreibt NDEF auf Type-2-, Type-4- und Type-5-Tags in dieser Reihenfolge.
Ein Schreibvorgang ist viele Befehle
Ein Type-2-Tag nimmt vier Bytes je Befehl. Die Referenz zu MifareUltralight dokumentiert writePage() als das Beschreiben einer Seite und sagt, dass das Protokoll immer eine Seite auf einmal beschreibt, eine Nachricht von hundert Bytes braucht also etwa fünfundzwanzig Befehle. Ein Tag, der zwischen zweien davon geht, behält die schon beschriebenen Seiten neben den Seiten, die er vorher trug.
Was über das Ergebnis entscheidet, ist das Längenfeld. Zuerst mit seinem neuen Wert geschrieben, kündigt es die neue Nachricht an, während spätere Seiten noch die alte tragen, und ein Lesegerät liest die Mischung als Nachricht: Die Seite zum Abbruch auf halbem Weg beschreibt den Tag, der dann beschädigt gelesen wird oder auf halbem Weg aufhört. Zuletzt geschrieben, gibt es einem Lesegerät nichts zu lesen, bis die Nachricht vollständig ist.
Die Reihenfolge, Typ für Typ
Der quelloffene NFC-Stack von Android wendet auf jeden Typ dieselben drei Schritte an, und seine Quelle zeigt sie:
| Typ | Längenfeld | Schritte im Stack |
|---|---|---|
| Type 2 | Die Länge des NDEF-TLV-Blocks | Schreibt den Block, der sie trägt, mit einer Länge von null, dann die Nachricht, dann den Block erneut mit der wirklichen Länge, in rw_t2t_ndef.cc |
| Type 4 | NLEN, am Anfang der NDEF-Datei | Setzt NLEN auf 0000, schreibt die Nachricht dahinter, dann NLEN, in rw_t4t.cc |
| Type 5 | Die Länge des NDEF-TLV-Blocks | Setzt die Länge auf null, schreibt die Nachricht und den Terminator-Block, dann die Länge, in rw_i93.cc |
Ein Abbruch nach dem ersten Schritt hinterlässt eine NDEF-Nachricht der Länge null. Lesegeräte melden einen leeren Tag, und die Anwendung, die ihn beschrieben hat, kann erkennen, dass ihr Schreibvorgang nicht fertig wurde.
Die Reihenfolge schützt die Nachricht und nicht die Seite, die beim Abbruch gerade beschrieben wird. Was ein Chip in einer Seite hält, deren eigener Schreibvorgang abgeschnitten wurde, ist eine Eigenschaft des Chips, und die Reihenfolge verengt dieses Risiko auf den letzten Schreibvorgang, den, der die Länge setzt.
Wenn die Plattform für Sie schreibt
Unter Android übergibt Ndef.writeNdefMessage() die Nachricht dem NFC-Stack, der sie in der Reihenfolge oben schreibt, und Code, der es benutzt, hat nichts hinzuzufügen als ein Zurücklesen. Ein Telefonhersteller kann einen geänderten Stack ausliefern, das Zurücklesen ist also die Prüfung, die auf jedem Telefon hält.
Unter iOS beschreibt Apples Referenz zu writeNDEF die Reihenfolge ihres Schreibers nicht. Eine Anwendung erfährt von einer misslungenen Aktualisierung über ndefReaderSessionErrorTagUpdateFailure oder eine verlorene Verbindung, wie die Seite zum Schreiben unter iOS erklärt, und liest den Tag zurück, um zu wissen, was er jetzt hält.
Wenn Ihr Code die Seiten schreibt
Code, der Seiten roh schreibt, um nach einer Authentifizierung einen geschützten Tag zu beschreiben oder um Daten abzulegen, die kein NDEF sind, übernimmt die Aufgabe des Stacks. Für NDEF folgt er der Tabelle: die Länge auf null, die Nachricht schreiben, die Länge schreiben. Die Seite, die die Länge trägt, trägt meist auch die ersten Bytes der Nachricht, der letzte Schreibvorgang schreibt diese Seite also mit beidem neu, wie der Stack von Android es tut.
Für Daten, die kein NDEF sind, braucht derselbe Gedanke ein eigenes Feld der Anwendung, eine Länge, eine Fassung oder eine Prüfsumme, hinter den Daten geschrieben, die der lesende Code prüft, bevor er irgendetwas glaubt. Ohne das sieht ein abgerissener Schreibvorgang genau wie Daten aus.
Lesen Sie dann zurück und vergleichen Sie. Ein Schreibvorgang, dessen letzter Befehl in einer Ausnahme endete, hat ein unbekanntes Ergebnis, und die Seite zum Abbruch auf halbem Weg erklärt, warum das Lesen vor jedem zweiten Versuch kommt.
Häufige Fragen
Schreibt Ndef.writeNdefMessage schon in dieser Reihenfolge?
Im quelloffenen NFC-Stack von Android ja, auf Type-2-, Type-4- und Type-5-Tags. Lesen Sie den Tag trotzdem zurück, da ein Telefonhersteller den Stack ändern kann.
Was sieht ein Lesegerät nach einem abgebrochenen Schreibvorgang?
Eine NDEF-Nachricht der Länge null, wenn der Abbruch zwischen dem ersten und dem letzten Schritt kam. Anwendungen melden ihn als leeren Tag.
Kann der letzte Schreibvorgang der Länge selbst abgebrochen werden?
Ja, und keine Reihenfolge schützt diesen einen Befehl. Die Reihenfolge verengt das Risiko auf einen einzigen Schreibvorgang, und was eine mitten im Schreiben abgeschnittene Seite hält, hängt am Chip.
Schreibt iOS NDEF in derselben Reihenfolge?
Apples Referenz sagt es nicht. Prüfen Sie das Ergebnis, indem Sie den Tag nach dem Schreiben zurücklesen.