Aller au contenu
Langue : FR

Comment écrire un tag pour qu'une écriture interrompue ne passe pas pour valide ?

En mettant d'abord la longueur du message à zéro, en écrivant le message, et en écrivant la vraie longueur en dernier. Une interruption avant la dernière étape laisse un tag qui se lit comme vide, au lieu d'une longueur qui annonce des octets jamais arrivés. La pile libre d'Android procède ainsi sur les types 2, 4 et 5.

Une écriture est faite de nombreuses commandes

Un tag de type 2 prend quatre octets par commande. La référence de MifareUltralight documente writePage() comme écrivant une page et dit que le protocole écrit toujours une page à la fois, si bien qu'un message de cent octets prend quelque vingt-cinq commandes. Un tag qui part entre deux d'entre elles garde les pages déjà écrites à côté des pages qu'il portait avant.

Ce qui décide du résultat est le champ de longueur. Écrit d'abord avec sa nouvelle valeur, il annonce le nouveau message alors que des pages plus loin portent encore l'ancien, et un lecteur analyse le mélange comme un message : la page de l'écriture interrompue décrit le tag qui se lit alors comme corrompu ou s'arrête en chemin. Écrit en dernier, il ne donne à un lecteur rien à analyser tant que le message n'est pas complet.

L'ordre, type par type

La pile NFC libre d'Android applique les mêmes trois étapes à chaque type, et sa source les montre :

Comment la pile NFC d'Android ordonne une écriture NDEF
TypeChamp de longueurÉtapes dans la pile
Type 2La longueur du bloc TLV du NDEFÉcrit le bloc qui la porte avec une longueur de zéro, puis le message, puis le bloc à nouveau avec la vraie longueur, dans rw_t2t_ndef.cc
Type 4NLEN, au début du fichier NDEFMet NLEN à 0000, écrit le message après lui, puis écrit NLEN, dans rw_t4t.cc
Type 5La longueur du bloc TLV du NDEFMet la longueur à zéro, écrit le message et le bloc Terminator, puis pose la longueur, dans rw_i93.cc

Une interruption après la première étape laisse un message NDEF de longueur zéro. Les lecteurs signalent un tag vide, et l'application qui l'a écrit peut savoir que son écriture n'est pas allée au bout.

L'ordre protège le message, pas la page en cours d'écriture au moment de l'interruption. Ce qu'une puce garde dans une page dont l'écriture a été coupée est une propriété de la puce, et l'ordre réduit ce risque à la seule écriture finale, celle qui pose la longueur.

Quand la plateforme écrit pour vous

Sur Android, Ndef.writeNdefMessage() remet le message à la pile NFC, qui l'écrit dans l'ordre ci-dessus, et un code qui l'emploie n'a rien à ajouter qu'une relecture. Un fabricant de téléphones peut livrer une pile modifiée, donc la relecture est le contrôle qui tient sur tous les téléphones.

Sur iOS, la référence d'Apple pour writeNDEF ne décrit pas l'ordre qu'emploie son écrivain. Une application apprend l'échec d'une mise à jour par ndefReaderSessionErrorTagUpdateFailure ou par une connexion perdue, comme l'explique la page de l'écriture sur iOS, et relit le tag pour savoir ce qu'il porte désormais.

Quand votre code écrit les pages

Un code qui écrit des pages brutes, pour écrire un tag protégé après s'être authentifié ou pour ranger des données qui ne sont pas du NDEF, reprend le travail de la pile. Pour du NDEF, il suit le tableau : longueur à zéro, écriture du message, écriture de la longueur. La page qui porte la longueur porte d'ordinaire aussi les premiers octets du message, donc la dernière écriture réécrit cette page avec les deux, comme le fait la pile Android.

Pour des données qui ne sont pas du NDEF, la même idée demande un champ propre à l'application, une longueur, une version ou une somme de contrôle écrite après les données, que le code de lecture vérifie avant de faire confiance à quoi que ce soit. Sans lui, une écriture arrachée ressemble exactement à des données.

Relisez ensuite et comparez. Une écriture dont la dernière commande a fini sur une exception a une issue inconnue, et la page de l'écriture interrompue explique pourquoi la lecture vient avant toute nouvelle tentative.

Questions fréquentes

Ndef.writeNdefMessage écrit-elle déjà dans cet ordre ?

Dans la pile NFC libre d'Android, oui, sur les tags de type 2, 4 et 5. Relisez quand même le tag, un fabricant de téléphones pouvant modifier la pile.

Que voit un lecteur après une écriture interrompue ?

Un message NDEF de longueur zéro, quand l'interruption est venue entre la première et la dernière étape. Les applications le signalent comme un tag vide.

L'écriture finale de la longueur peut-elle être interrompue elle aussi ?

Oui, et aucun ordre ne protège cette commande-là. L'ordre réduit le risque à une seule écriture, et ce que porte une page coupée pendant sa propre écriture dépend de la puce.

iOS écrit-il le NDEF dans le même ordre ?

La référence d'Apple ne le dit pas. Vérifiez le résultat en relisant le tag après l'écriture.