NFC (Near Field Communication) é uma tecnologia de comunicacão sem fio entre dispositivos que estejam em contato físico, ou pelo menos muito próximos. Um dos dispositivos pode ser passivo, sem pilhas ou qualquer outra fonte de eletricidade.
O bisavô do NFC é aquele cartão anti-furto que encontramos nas lojas. O sensor da porta produz um campo magnético. O cartão anti-furto não tem pilhas, mas absorve energia do campo. Esta absorção é detectada e faz soar o alarme.
Em cima deste esquema, surgiu a tecnologia RFID, que não apenas absorve energia mas também transmite alguma informação de volta. O uso "canônico" do RFID é como substituto ou complemento dos códigos de barras, já que podem ser lidos mais facilmente. Há o problema de privacidade: se você compra uma camisa com cartão de crédito, e ela tiver uma etiqueta RFID, você tornou-se facilmente rastreável.
O NFC vai um passo além do RFID; o dispositivo passivo NFC pode ser "inteligente". O potencial do NFC como tecnologia de consumo é enorme, inclui coisas como:
O NFC permite a comunicação entre dois dispositivos "ativos", como dois celulares. Fica fácil trocar contatos e fotos, de forma segura. Basta tocá-los. Isto ainda não funciona tão bem quanto poderia, porque os padrões ainda estão emergindo, e há incompatibilidades entre e.g. Android e Windows Phone.
No jargão NFC, o dispositivo passivo, sem eletricidade própria, é denominado tag, ou "cartão" porque na maioria das vezes realmente possui forma e tamanho de um cartão de crédito. O dispositivo ativo é comumente chamado de leitor, porque tipicamente só faz ler tags.
Tanto leitor como tag possuem bobinas, não antenas do formato usual. Quando a bobina do leitor recebe eletricidade, gera um campo magnético. Quando um tag se aproxima de um leitor, as duas bobinas constituem um transformador, e o tag absorve energia do leitor.
Não sei se você já ouviu aquela história (fictícia?) sobre os moradores de uma favela do Rio, que iluminavam suas casas obtendo energia de uma rádio AM próxima, prejudicando o alcance em regiões distantes. Seja como for, a história serve para ilustrar a diferença entre campo próximo (near field) e campo distante (far field).
O campo distante é o sinal eletromagnético de rádio, que irradia e se propaga por grandes distâncias. Um rádio ligado na minha casa não prejudica a recepção de rádio do vizinho. E a existência de muitos receptores sintonizados numa rádio não aumenta a carga do transmissor; as partes estão desacopladas.
Já o campo próximo é composto dos campos elétrico e magnético que ainda não se combinaram para irradiar. Separados, eles não vão longe. O campo próximo, como o nome sugere, fica bem próximo da antena. Um receptor nesta região, com uma antena em forma de bobina (apropriada para recepção de campo próximo) pode absorver bastante energia e efetivamente prejudicar o alcance.
Um transmissor "sente" o receptor de campo próximo pela mudança de impedância da antena. Se o receptor for acoplado o suficiente, ou houver receptores suficientes, a impedância da antena pode tender a 0 ohms, sobrecarregando o circuito transmissor. (A "impedância do vácuo" é de 377 ohms.)
O comprimento de onda AM é de mais ou menos 500 metros, então a mítica favela carioca teria de estar a menos de 100 metros da antena para a lenda ter alguma chance de ser verdadeira.
O NFC faz bom uso destes efeitos, exatamente para limitar o alcance da comunicação. Como uma bobina é uma péssima antena, pouca energia é desperdiçada na forma de radiação eletromagnética. Os campos elétrico e magnético que não se combinam para irradiar (porque a antena não ajuda) "devolvem" sua energia ao transmissor, assim como um transformador sem carga quase não gasta energia.
Já que o tag não tem energia própria, ele comunica-se com o leitor modulando o seu consumo de energia. Um tag mais "gastador" diminuiu a impedância da antena do transmissor. Monitorando essa impedância, o leitor pode decodificar uma mensagem vinda do tag.
Quando dois dispositivos NFC ativos como dois celulares vão se comunicar, há complicações porque ambos podem tentar transmitir ao mesmo tempo (colisão). O protocolo precisa detectar e tratar colisões.
Para o usuário, o NFC é perfeito. Para o desenvolvedor, o NFC é um pouco mais complicado do que deveria. Isto se deve a um fator "histórico": as especificações do NFC Forum herdaram versões preexistentes e diferentes de NFC (da Philips, da Sony, etc.). O resultado é uma pilha com muitas redundâncias, e uma multiplicidade incômoda de tipos de tag.
Existem diversos "tipos" de tag NFC: tipo A, tipo B... conforme a Figura 1. Em cima destes tipos, temos os "tipos tecnológicos": 1, 2, 3 e 4. Por exemplo, o "tipo tecnológico 1" adota um subconjunto dos recursos presentes no "tipo A".
Cada tipo possui suas capacidades e limitações, como por exemplo a memória no chip, tamanho das mensagens trocadas com o leitor. A propósito, o NFC Forum dá acesso gratuito às especificações; basta fazer um simples cadastro.
Em cima dos tipos, há os padrões comerciais. Por exemplo, o padrão MiFARE possui criptografia embutida no tag.
A boa notícia é que celulares capazes de NFC, como Android ou Windows Phone, conseguem lidar com todos os tipos de tag NFC mencionados na Figura 1.
A pilha de protocolos NFC faz TCP/IP parecer brincadeira de criança. Vide a Figura 2.
Cada tipo de tag oferece um protocolo de enlace específico, e cada tipo de tecnologia adiciona comandos ao protocolo-base. Por exemplo, o NFC-A oferece um conjunto de comandos, e o Type 2 estende-o (uma heresia para quem aprecia a divisão em camadas do TCP/IP).
Devido a isto, há muitos protocolos de enlace (os ganchos de formato quadrado da Figura 2), e os protocolos de transporte ou aplicação podem usar qualquer destes enlaces. Por conta disso, não foi possível desenhar a pilha à moda dos livros didáticos na Figura 2.
Assim, usei "ganchos" de diferentes formatos para indicar quem pode conectar com quem. Por exemplo, o protocolo de transporte NDEF pode usar qualquer um dos "quadradinhos vazados" como enlace, enquanto o protocolo de aplicacão PHDC pode usar tanto NDEF ("flecha") ou LLCP ("bolinha") como transporte.
Felizmente, o padrão mais utilizado em NFC é o NDEF (NFC Data Exchange Format). O NDEF especifica tanto o formato de mensagem (armazenado no tag) quanto o protocolo de acesso (ler e escrever mensagens NDEF num tag).
Ao lidar com NDEF, o desenvolvedor está isento de lidar com a multiplicidade de enlaces, pois normalmente a API esconde este detalhe de baixo nível.
Como o Android é a plataforma que desde o início deu mais ênfase ao NFC, é instrutivo verificar o nível de acesso que a API Android concede à pilha NFC. Procurei fazer isto graficamente, na Figura 3.
O suporte a NDEF é excelente, inclusive para gravar mensagens em tags de qualquer tipo.
Graças ao mecanismo de Intents, é possível configurar um aplicativo para lidar com NDEFs de determinado tipo; quando o celular encosta num tag contendo mensagem do tipo desejado, o aplicativo é carregado automaticamente. O Android também oferece uma API bem completa para o padrão MiFARE.
Há também o extremo oposto: a API de acesso "cru" à camada de enlace. Ela permite lidar com protocolos proprietários, não baseados em NDEF. Mas o grau de dificuldade é alto, porque o desenvolvedor terá de criar as mensagens a partir da camada de enlace, com todos os bits nos devidos lugares... e estas mensagens mudam conforme a tecnologia.
O Android suporta também o protocolo ISO-DEP, um enlace de nível um pouco mais alto, que abstrai os tipos 4A e 4B. O protocolo PICC, parte da pilha FeLiCa, pode ser suportado mas tem de ser implementado manualmente, usando o acesso direto ao NFC-F.
Não há acesso ao protocolo NFC-DEP, que abstrai os tipos 2 e 3. Também não há acesso ao LLCP, um protocolo de transporte que reutiliza conceitos da Ethernet (padrão 802.3), atribuindo inclusive endereços MAC.
O LLCP oferece serviços de datagrama e conexão, de forma análoga a UDP e TCP, e muito mais semelhante ao que nós desenvolvedores já temos visto em TCP/IP e Bluetooth. Visa atender mais à comunicação bidirecional entre dois dispositivos NFC ativos, como dois celulares. (A comunicação com tags passivos tende a ser ser curta e grossa: leitura de uma mensagem NDEF e fim.)
O Android não dá acesso ao LLCP na API, mas faz uso dele internamente. O protocolo SNEP (Simple NDEF Exchange Protocol) usa o LLCP como transporte. O SNEP é a base do "Android Beam", que transmite contatos e fotos entre dois celulares. Curiosamente, o resultado final de uma conexão SNEP é simplesmente uma mensagem NDEF unidirecional. Não se pode estabelecer uma conexão bidirecional contínua por meio da API do SNEP.
Como parte do meu trabalho é relacionado a equipamentos médicos, adicionei o protocolo PHDC na Figura 2. O PHDC faz o mesmo papel da classe PHDC do USB e do perfil HDP do Bluetooth: transmite mensagens médicas no formato IEEE 11073-20601. O PHDC pode usar tanto LLCP quanto NDEF como transporte. Como a troca de mensagens NDEF não estabelece por si só uma conexão duradoura, o PHDC prescreve uma "telegrafia" de mensagens de parte a parte, várias vezes por segundo.
Normalmente um dispositivo médico vai ter sua própria fonte de eletricidade, mas o suporte a transporte NDEF deixa a porteira aberta para dispositivos 100% passivos. Um termômetro é um exemplo didático de dispositivo médico NFC que poderia funcionar sem pilhas.
Finalmente, há protocolos proprietários, que fazem uso direto de pacotes de enlace, sem qualquer dos confortos das APIs de nível mais alto. Minhas condolências para quem tiver de lidar com eles.
Como o NDEF tem papel central no NFC, é interessante examiná-lo mais detidamente. Um bom texto a respeito pode ser encontrado aqui mas vou falar dos principais aspectos.
Uma mensagem NDEF é composta por um ou mais registros NDEF. Cada registro é uma estrutura com diversos campos, tais como:
A presença de todos estes elementos em cada registro resolve muitos problemas. Uma mensagem pode ser transmitida em fragmentos (usando os bits MB e ME); mensagens de diferentes tipos podem ser recebidas pelo mesmo canal e direcionadas a aplicativos diferentes; mensagens diferentes podem ser transmitidas ao mesmo tempo, de forma intercalada, desde que tenham identificadores distintos.
O meta-tipo URI deixa a porta aberta para tipos particulares das aplicações. Por exemplo, eu posso definir um tipo com a URI "urn:nfc:ext:epxx.co:boo", utilizado apenas em minhas aplicações. Naturalmente, cada tipo impõe um formato ao payload da mensagem.
O protocolo tem duas operações básicas: ler NDEF e gravar NDEF, que se apóiam no tipo de tecnologia empregado pelo tag. O documento normativo de cada tipo (Type 1, 2, 3 ou 4) especifica como o NDEF deve ser lido, gravado e armazenado no tag.
As operações NDEF foram concebidas para ler e, eventualmente, gravar tags passivos. A iniciativa é sempre do leitor. Se uma comunicação mais elaborada, bidirecional, tiver de ser implementada com base nestas primitivas, o leitor tem de "pollar", ou seja, ficar lendo periodicamente até receber um NDEF com conteúdo substancial. É o que faz o protocolo PHDC.
Há diversos projetos e bibliotecas de pilha NFC por aí. Um projeto que parece particularmente adequado para aprendizado, prototipagem e testes é o NFCPy. Seus grandes atrativos são: escrito em Python, não depender de drivers de kernel, e funcionar em qualquer sistema operacional.