Saltar al contenido
Idioma: ES

¿Cómo se envía un comando en bruto a una etiqueta?

Por la clase o el protocolo que corresponde a la capa de radio de la etiqueta: NfcA, NfcV o IsoDep en Android, y NFCMiFareTag, NFCISO15693Tag o NFCISO7816Tag en una sesión de etiqueta de iOS. El código construye los bytes, la plataforma añade el encuadre, y la respuesta vuelve como bytes que solo el código juzga.

Elige el canal por la capa de radio

En Android, las clases de tecnología que envían bytes tal cual exponen todas transceive(). NfcA llega a las etiquetas NFC-A, entre ellas todas las de tipo 2; NfcV llega a las etiquetas ISO/IEC 15693; IsoDep lleva APDU a las etiquetas y tarjetas ISO/IEC 14443-4. MifareUltralight.transceive() es, según su referencia, lo mismo que conectarse mediante NfcA y llamar a su método.

En iOS, los comandos en bruto necesitan una sesión de etiqueta, ya que una sesión NDEF no entrega ningún canal de comandos, como explica la página de las sesiones. La etiqueta detectada llega como uno de los protocolos que define Core NFC: NFCMiFareTag, cuyo sendMiFareCommand sirve a las etiquetas MIFARE Ultralight, Plus y DESFire pero no al protocolo Crypto1 de MIFARE Classic; NFCISO15693Tag, con un método por cada comando normalizado; NFCISO7816Tag, cuyo sendCommand(apdu:) envía APDU; y NFCFeliCaTag para FeliCa.

Una página web no tiene ningún canal. Web NFC se para en el NDEF por diseño, como describe la página de la escritura con Web NFC, así que un proyecto que necesita comandos en bruto necesita una aplicación.

Lo que contienen tus bytes

La plataforma encuadra lo que el código envía, y cada referencia dice dónde se detiene ese encuadre. NfcA.transceive() toma bytes completos y añade ella misma el CRC: la referencia de NfcA pide a las aplicaciones que no lo añadan, y descarta los comandos que sirven para el sondeo. NfcV.transceive() espera el byte de marcas, el código del comando y sus parámetros, y también añade el CRC. IsoDep.transceive() toma la APDU sola, sin indicadores de trama, y parte ella misma una larga.

Core NFC no traza la línea en el mismo sitio. La referencia de sendMiFareCommand de Apple pide a la aplicación que calcule los dos bytes de CRC de un comando de la familia MIFARE Ultralight y los añada, lo contrario de la regla de Android, así que un comando copiado de código Android llega sin ellos. Los métodos ISO 15693 construyen la petición entera, y por omisión la dirigen al identificador de la etiqueta.

Sea cual sea la plataforma, un comando que ningún tipo de etiqueta define pertenece a un chip. Su código y sus parámetros salen de la hoja de datos de ese chip, que este sitio deja a las fichas de chips de wakdev.com.

Leer la respuesta

Una llamada que vuelve ha entregado bytes, y eso es todo lo que la plataforma comprobó. Si la etiqueta aceptó el comando está escrito dentro de esos bytes, en un formato que pertenece al protocolo.

Una etiqueta ISO 15693 abre su respuesta con un byte de marcas cuyo bit más bajo declara un error, seguido de un código de error, según las definiciones del código abierto de la pila NFC de Android. Core NFC convierte una respuesta así en un error cuya información de usuario lleva NFCISO15693TagResponseErrorKey, con el código de la norma.

Una APDU termina con dos bytes de estado, 90 00 cuando el comando se completó. La referencia de sendCommand de Apple los devuelve como sw1 y sw2, siempre válidos, y guarda su error para los problemas de comunicación: una tarjeta que rechaza un comando responde con normalidad, con el rechazo en los bytes de estado. La página de las APDU enumera los valores corrientes.

Dos clases de fallo

Un fallo de transporte quiere decir que no llegó ninguna respuesta utilizable. En Android, la llamada lanza TagLostException cuando la etiqueta ha salido del campo e IOException para los demás fallos. En iOS, los códigos de error incluyen readerTransceiveErrorTagConnectionLost, readerTransceiveErrorPacketTooLong para un comando más largo de lo que la etiqueta acepta, y readerTransceiveErrorTagResponseError cuando la etiqueta respondió con un error.

Una escritura que termina en un fallo de transporte tiene un resultado desconocido. El comando puede haber llegado a la etiqueta antes de que su respuesta se perdiera, así que vuelve a leer la memoria antes de enviar nada más, y escribe en un orden que nunca deje un mensaje a medio validar, el tema de la página de las escrituras interrumpidas.

Los límites se aplican antes que nada de esto. Cuántos bytes lleva una llamada, y cuánto espera, cambian de un teléfono Android a otro, como explica la página de los límites del controlador: un comando que funciona en el teléfono de pruebas puede fallar en otro antes de llegar a la etiqueta.

Preguntas frecuentes

¿Puede una página web enviar un comando en bruto a una etiqueta?

No. Web NFC lee y escribe solo NDEF, así que los comandos en bruto necesitan una aplicación de Android o de iOS.

¿Mi código añade el CRC?

En Android no, donde NfcA y NfcV lo añaden. La referencia de Apple lo pide en los comandos de la familia MIFARE Ultralight enviados con sendMiFareCommand.

¿Por qué un comando vuelve sin haber hecho nada?

La plataforma declara una respuesta entregada, no un comando aceptado. Lee el bit de error de una respuesta ISO 15693, o los bytes de estado de una APDU, antes de fiarte del resultado.

¿De dónde salen los comandos de un chip concreto?

De la hoja de datos de ese chip. Esta sección cubre los comandos que definen los tipos de etiqueta del NFC Forum, y las fichas de chips de wakdev.com cubren el resto.