Ir para o conteúdo
Idioma: PT

Como enviar um comando bruto para uma tag?

Pela classe ou pelo protocolo que corresponde à camada de rádio da tag: NfcA, NfcV ou IsoDep no Android, NFCMiFareTag, NFCISO15693Tag ou NFCISO7816Tag numa sessão de tag do iOS. O código monta os bytes do comando, a plataforma acrescenta o enquadramento, e a resposta volta em bytes que só o código sabe julgar. O Web NFC não envia nenhum.

Escolha o canal pela camada de rádio

No Android, as classes de tecnologia que enviam bytes como eles são expõem todas transceive(). NfcA alcança as tags NFC-A, entre elas toda tag Tipo 2; NfcV alcança as tags ISO/IEC 15693; IsoDep leva APDU até as tags e os cartões ISO/IEC 14443-4. MifareUltralight.transceive() é, segundo a referência dela, o mesmo que conectar por NfcA e chamar o método dessa classe.

No iOS, os comandos brutos precisam de uma sessão de tag, já que uma sessão NDEF não entrega canal de comando algum, como explica a página das sessões. A tag detectada chega como um dos protocolos que o Core NFC define: NFCMiFareTag, cujo sendMiFareCommand serve as tags MIFARE Ultralight, Plus e DESFire mas não o protocolo Crypto1 do MIFARE Classic; NFCISO15693Tag, com um método para cada comando da norma; NFCISO7816Tag, cujo sendCommand(apdu:) envia APDU; e NFCFeliCaTag para o FeliCa.

Uma página web não tem canal nenhum. O Web NFC para no NDEF por projeto, como descreve a página da gravação com Web NFC, então um projeto que precisa de comandos brutos precisa de um aplicativo.

O que os seus bytes contêm

A plataforma enquadra o que o código envia, e cada referência diz onde esse enquadramento para. NfcA.transceive() recebe bytes completos e acrescenta o CRC sozinho: a referência do NfcA diz aos aplicativos para não acrescentá-lo, e exclui os comandos usados na sondagem. NfcV.transceive() espera o byte dos sinalizadores, o código do comando e os parâmetros dele, e acrescenta o CRC também. IsoDep.transceive() recebe a APDU sozinha, sem indicadores de quadro, e divide por conta própria uma que seja longa.

O Core NFC não traça a linha no mesmo lugar. A referência do sendMiFareCommand da Apple pede ao aplicativo que calcule os dois bytes de CRC de um comando da família MIFARE Ultralight e os acrescente, o contrário da regra do Android, então um comando copiado de código Android chega sem eles. Os métodos ISO 15693 montam a requisição inteira, e por padrão a endereçam ao identificador da tag.

Seja qual for a plataforma, um comando que nenhum tipo de tag define pertence a um chip. O código dele e os parâmetros dele vêm da ficha técnica desse chip, que este site deixa para as fichas de chips do wakdev.com.

Ler a resposta

Uma chamada que retorna entregou bytes, e foi só isso que a plataforma conferiu. Se a tag aceitou o comando está escrito dentro desses bytes, num formato que pertence ao protocolo.

Uma tag ISO 15693 abre a resposta dela com um byte de sinalizadores cujo bit mais baixo informa um erro, seguido de um código de erro, segundo as definições da pilha NFC de código aberto do Android. O Core NFC transforma uma resposta dessas num erro cuja informação de usuário carrega NFCISO15693TagResponseErrorKey, com o código da norma.

Uma APDU termina com dois bytes de estado, 90 00 quando o comando foi concluído. A referência do sendCommand da Apple os devolve como sw1 e sw2, sempre válidos, e guarda o erro dela para problemas de comunicação: um cartão que recusa um comando responde normalmente, com a recusa nos bytes de estado. A página das APDU lista os valores comuns.

Dois tipos de falha

Uma falha de transporte quer dizer que nenhuma resposta utilizável chegou. No Android, a chamada lança TagLostException quando a tag saiu do campo e IOException para as outras falhas. No iOS, os códigos de erro incluem readerTransceiveErrorTagConnectionLost, readerTransceiveErrorPacketTooLong para um comando mais longo do que a tag aceita, e readerTransceiveErrorTagResponseError quando a tag respondeu com um erro.

Uma gravação que termina numa falha de transporte tem um resultado desconhecido. O comando pode ter chegado à tag antes de a resposta dele se perder, então releia a memória antes de enviar qualquer coisa de novo, e grave numa ordem que nunca deixe uma mensagem meio válida, o assunto da página das gravações interrompidas.

Os limites valem antes de tudo isso. Quantos bytes uma chamada consegue carregar, e quanto tempo ela espera, diferem de um celular Android para o seguinte, como explica a página dos limites do controlador: um comando que funciona no celular de teste pode falhar em outro antes de chegar à tag.

Perguntas frequentes

Uma página web consegue enviar um comando bruto para uma tag?

Não. O Web NFC só lê e grava NDEF, então os comandos brutos precisam de um aplicativo Android ou iOS.

O meu código acrescenta o CRC?

No Android não, onde NfcA e NfcV o acrescentam. A referência da Apple o pede nos comandos da família MIFARE Ultralight enviados com sendMiFareCommand.

Por que um comando retorna sem fazer nada?

A plataforma informa uma resposta entregue, não um comando aceito. Leia o sinalizador de erro de uma resposta ISO 15693, ou os bytes de estado de uma APDU, antes de confiar no resultado.

De onde vêm os comandos de um chip específico?

Da ficha técnica desse chip. Esta seção cobre os comandos que os tipos de tag do NFC Forum definem, e as fichas de chips do wakdev.com cobrem o resto.