Por que um código escrito para um chip quebra em outro do mesmo tipo?
Porque o tipo de tag fixa os comandos, não o mapa de memória. Duas tags Tipo 2 respondem ao mesmo READ e põem a configuração em páginas diferentes, e um endereço fixado no código que funcionava numa cai na memória de usuário da outra. Leia o que a tag informa em vez disso.
O que o tipo fixa
Um tipo de tag do NFC Forum é um contrato sobre comandos: quais um leitor pode enviar, como a memória é endereçada, como uma mensagem NDEF é encontrada. A página do Tipo 2 e a página do Tipo 4 expõem esses dois contratos.
O que ele não fixa é tudo o que um chip acrescenta: quantas páginas existem, onde a configuração mora, se há um contador, um espelho ou uma senha, e que comandos extras respondem. Esses pertencem ao chip, e este site os deixa para as fichas de chips, como a página da configuração faz para as páginas depois da área de dados.
O que a tag informa
A maior parte do que o código precisa se lê em vez de se supor. No Android, Ndef responde a três perguntas sem tocar no rádio: getType() devolve o tipo do NFC Forum, getMaxSize() a maior mensagem que a tag aceita, e isWritable() se ela ainda aceita uma gravação. MifareUltralight.getType() distingue uma Ultralight de uma Ultralight C, e devolve desconhecido quando não consegue dizer.
Abaixo disso, a própria tag responde. O contêiner de capacidade de uma tag Tipo 2 dá o tamanho da área de dados e a condição de acesso dela, e o Get System Information numa tag ISO/IEC 15693 dá o tamanho de bloco e a contagem de blocos, o que a página da 15693 lê antes de tudo. Um programa que pergunta a essas três fontes tem muito pouco a supor.
A mesma família, dois mapas
O caso mais claro é uma família só. Uma NTAG213 tem 45 páginas, os bytes de bloqueio dinâmicos dela na página 40 e a configuração dela nas páginas 41 a 44; uma NTAG215 tem 135 páginas e guarda os mesmos ajustes nas páginas 130 a 134, como descrevem as fichas delas no wakdev.com. A página 41 é configuração numa e memória de usuário comum na outra.
Um código que grava uma configuração por número de página corrompe portanto conteúdo no chip errado, em silêncio, e a tag continua lendo como se nada tivesse acontecido. Que é a razão de a página da configuração pedir que o chip seja identificado antes de a sequência rodar.
Ler primeiro, gravar depois
Detecte recursos em vez de modelos. Pergunte à tag o que ela é e o que ela oferece, ajuste, e recuse continuar quando a resposta não for uma que o seu código conhece: uma recusa explícita é um relato de defeito, uma gravação silenciosa é um lote corrompido.
E guarde uma tag de cada chip no conjunto de teste, o que a página do conjunto de teste pede de qualquer jeito. Uma tag de um segundo tamanho na mesma família acha essa classe de defeito num minuto, e nada mais a acha antes de a produção achar.
Perguntas frequentes
O tipo de tag não basta para escrever código portável?
Para o NDEF, basta. Para qualquer coisa abaixo dele, não: páginas, tamanhos e endereços de configuração pertencem ao chip em vez de pertencerem ao tipo.
O que dá para ler em vez de supor?
O tipo, o tamanho máximo e a possibilidade de gravação pela plataforma, o contêiner de capacidade numa tag Tipo 2, e a informação de sistema numa tag ISO/IEC 15693.
Por que a minha gravação de configuração corrompeu o conteúdo?
O número de página pertencia a outro chip da mesma família. Num chip maior esse endereço é memória de usuário.
Como pegar isso antes da produção?
Guarde dois chips do mesmo tipo e de tamanhos diferentes no conjunto de teste, e rode a sequência nos dois.