Como um computador fala com um leitor NFC USB?
Pelo PC/SC, a interface que os computadores usam para leitores de cartão: o programa abre um contexto, lista os leitores, conecta ao que estiver num deles e transmite APDU. O Windows o expõe como winscard, o macOS como CryptoTokenKit. Uma tag sem aplicação de cartão responde por comandos que o leitor implementa.
Onde o código fica
Um programa nunca fala com o aparelho USB. Ele fala com o gerenciador de recursos que o sistema operacional oferece, que fala com o leitor, que fala com o cartão ou com a tag. As especificações PC/SC definem essa cadeia parte por parte e são publicadas abertamente; a parte 3 é a que trata do leitor em si, e é onde um desenvolvedor vai parar quando uma tag se comporta de outro jeito que um cartão.
O que viaja entre o programa e o cartão é uma APDU, a unidade que a página das APDU descreve. Um leitor por aproximação a leva até uma tag Tipo 4 ou um cartão sem mudar nada; todo o resto desta página existe porque os outros tipos de tag não falam essa língua.
A mesma troca, dois sistemas
No Windows as chamadas pertencem ao winscard: um contexto, a lista de leitores, depois SCardConnect, que recebe um modo de compartilhamento, compartilhado, exclusivo ou direto, e os protocolos que o programa aceita, T=0 ou T=1. SCardTransmit envia o comando com a estrutura de controle de protocolo correspondente e devolve a resposta.
No macOS e no iOS a mesma troca passa pelo CryptoTokenKit. TKSmartCardSlotManager lista os slots e exige a autorização com.apple.security.smartcard; TKSmartCard abre uma sessão, transmite e a encerra, e expõe send(ins:p1:p2:data:le:), que monta a APDU para você, com cla, useExtendedLength e useCommandChaining ao lado.
A partir do iOS 26, o mesmo framework consegue abrir um slot no próprio rádio do celular: createNFCSlot(message:completion:) cria um slot de cartão inteligente NFC e apresenta uma interface do sistema, o que põe uma tag atrás da API que um leitor teria usado. O Core NFC continua sendo o framework para as tags que não são cartões, como descreve a página das sessões.
Tags sem aplicação de cartão
Uma tag Tipo 2 ou Tipo 5 não tem aplicação a selecionar nem APDU a responder. A parte 3 da especificação as trata fazendo o leitor trabalhar: um leitor conforme tem de suportar Read Binary, Update Binary, Load Keys, General Authenticate, Verify para cartões com código de segurança, e Get Data. A especificação é explícita que esses comandos vêm da indústria em vez de virem da ISO, e que os fabricantes de leitores juntam os detalhes com os fabricantes de chips.
Get Data é o que todo projeto usa: classe FF, instrução CA, parâmetros 00 00, e um tamanho esperado de 00 para o identificador inteiro. A especificação fixa o que volta: 4, 7 ou 10 bytes para uma tag ISO 14443 A, o PUPI de 4 bytes para um cartão 14443 B, 8 bytes para a ISO 15693, na ordem recebida durante a anticolisão, preenchidos em vez de convertidos, e 6A 81 quando o cartão não tem identificador algum.
Então um leitor que lê uma tag que o seu código não lê costuma ser um leitor que implementa um comando que o seu não envia, e não um rádio melhor.
O que o leitor diz que uma tag é
Uma tag por aproximação não tem resposta a reinício, e os programas escritos para cartões esperam uma. O leitor constrói então uma sintética, cujos campos o suplemento da parte 3 define: o identificador registrado do PC/SC Workgroup, A0 00 00 03 06, um byte que nomeia a norma, ISO 14443 A parte 3, ISO 15693 parte 1, FeliCa e assim por diante, depois dois bytes que nomeiam o chip a partir de um registro que o workgroup mantém mediante pedido.
Leia isso antes de enviar qualquer coisa. Ela diz ao seu código que família ele está segurando, e um chip desconhecido aparece como nenhuma informação fornecida em vez de aparecer como uma falha, que é a diferença entre um programa que se adapta e um que informa um leitor quebrado.
Perguntas frequentes
Dá para enviar uma APDU a uma tag que não é um cartão?
Não à tag. Você envia os comandos que o leitor implementa para cartões de armazenamento, na classe FF, e o leitor os transforma no que a tag entende.
Como ler o identificador de uma tag?
Com Get Data, FF CA 00 00, e um tamanho esperado de 00. Ele devolve 4, 7 ou 10 bytes na ISO 14443 A, o PUPI de 4 bytes na 14443 B, e 8 bytes na ISO 15693.
Por que um leitor informa uma resposta a reinício para uma tag que não tem?
Porque os programas esperam uma. O leitor a constrói a partir do registro do PC/SC, nomeando a norma e a família do chip, para o código saber o que está segurando.
A API é a mesma no macOS?
As chamadas diferem, CryptoTokenKit em vez de winscard, e exige a autorização de cartão inteligente. As APDU que viajam por ela são as mesmas.