Comment un ordinateur parle-t-il à un lecteur NFC en USB ?
Par PC/SC, l'interface que les ordinateurs emploient pour les lecteurs de cartes : le programme ouvre un contexte, liste les lecteurs, se connecte à ce qui se trouve sur l'un d'eux et transmet des APDU. Windows l'expose comme winscard, macOS comme CryptoTokenKit. Un tag sans application de carte répond par des commandes que le lecteur implémente.
Où se place le code
Un programme ne parle jamais au périphérique USB. Il parle au gestionnaire de ressources que fournit le système d'exploitation, qui parle au lecteur, qui parle à la carte ou au tag. Les spécifications PC/SC définissent cette chaîne partie par partie et sont publiées en accès libre ; la partie 3 est celle du lecteur lui-même, et c'est là qu'un développeur finit quand un tag se comporte autrement qu'une carte.
Ce qui circule entre le programme et la carte est un APDU, l'unité que décrit la page des APDU. Un lecteur sans contact le porte jusqu'à un tag de type 4 ou une carte sans rien y changer ; tout le reste de cette page existe parce que les autres types de tags ne parlent pas cette langue.
Le même échange, deux systèmes
Sur Windows les appels appartiennent à winscard : un contexte, la liste des lecteurs, puis SCardConnect, qui prend un mode de partage, partagé, exclusif ou direct, et les protocoles que le programme accepte, T=0 ou T=1. SCardTransmit envoie la commande avec la structure de contrôle du protocole correspondant et rend la réponse.
Sur macOS et iOS le même échange passe par CryptoTokenKit. TKSmartCardSlotManager liste les emplacements et exige l'habilitation com.apple.security.smartcard ; TKSmartCard ouvre une session, transmet et la termine, et expose send(ins:p1:p2:data:le:), qui construit l'APDU pour vous, avec cla, useExtendedLength et useCommandChaining à côté.
Depuis iOS 26, le même cadre sait ouvrir un emplacement sur la radio du téléphone lui-même : createNFCSlot(message:completion:) crée un emplacement de carte à puce NFC et présente une interface système, ce qui place un tag derrière l'API qu'un lecteur aurait employée. Core NFC reste le cadre des tags qui ne sont pas des cartes, comme le décrit la page des sessions.
Les tags sans application de carte
Un tag de type 2 ou de type 5 n'a aucune application à sélectionner ni aucun APDU auquel répondre. La partie 3 de la spécification les traite en faisant faire le travail au lecteur : un lecteur conforme doit offrir Read Binary, Update Binary, Load Keys, General Authenticate, Verify pour les cartes à code de sécurité, et Get Data. La spécification dit explicitement que ces commandes viennent de l'industrie et non de l'ISO, et que les fabricants de lecteurs en recueillent le détail auprès des fabricants de puces.
Get Data est celle que tout projet emploie : classe FF, instruction CA, paramètres 00 00, et une longueur attendue de 00 pour l'identifiant entier. La spécification fixe ce qui revient : 4, 7 ou 10 octets pour un tag ISO 14443 A, le PUPI de 4 octets pour une carte 14443 B, 8 octets pour ISO 15693, dans l'ordre reçu pendant l'anticollision, complété plutôt que converti, et 6A 81 quand la carte n'a pas d'identifiant du tout.
Un lecteur qui lit un tag que votre code ne lit pas est donc d'ordinaire un lecteur qui implémente une commande que le vôtre n'envoie pas, et non une meilleure radio.
Ce que le lecteur dit qu'un tag est
Un tag sans contact n'a pas de réponse à la remise à zéro, et les programmes écrits pour des cartes en attendent une. Le lecteur en fabrique donc une de synthèse, dont le supplément à la partie 3 définit les champs : l'identifiant enregistré du PC/SC Workgroup, A0 00 00 03 06, un octet qui nomme la norme, ISO 14443 A partie 3, ISO 15693 partie 1, FeliCa et ainsi de suite, puis deux octets qui nomment la puce d'après un registre que le groupe tient sur demande.
Lisez-la avant d'envoyer quoi que ce soit. Elle dit à votre code quelle famille il tient, et une puce inconnue y paraît comme une absence d'information plutôt que comme un échec, ce qui fait la différence entre un programme qui s'adapte et un programme qui annonce un lecteur en panne.
Questions fréquentes
Puis-je envoyer un APDU à un tag qui n'est pas une carte ?
Pas au tag. Vous envoyez les commandes que le lecteur implémente pour les cartes de stockage, en classe FF, et le lecteur les transforme en ce que le tag comprend.
Comment lire l'identifiant d'un tag ?
Avec Get Data, FF CA 00 00, et une longueur attendue de 00. Elle rend 4, 7 ou 10 octets en ISO 14443 A, le PUPI de 4 octets en 14443 B, et 8 octets en ISO 15693.
Pourquoi un lecteur annonce-t-il un ATR pour un tag qui n'en a pas ?
Parce que les programmes en attendent un. Le lecteur le fabrique d'après le registre PC/SC, en nommant la norme et la famille de puce, pour que le code sache ce qu'il tient.
L'API est-elle la même sur macOS ?
Les appels diffèrent, CryptoTokenKit plutôt que winscard, et il y faut l'habilitation de carte à puce. Les APDU qui y circulent sont les mêmes.