Site menu Bluetooth: SDP e profiles

Bluetooth: SDP e profiles

Profiles

Os projetistas do Bluetooth gostam de "empilhar" protocolos: RFCOMM sobre L2CAP sobre ACL sobre HCI sobre o rádio Bluetooth que é complicado pra c@$#*.

E o empilhamento prossegue acima do L2CAP e do RFCOMM também. O Bluetooth usa o conceito de "profile", ou perfil, para implementar determinado serviço.

A rigor, não é necessário haver um perfil para haver comunicação. No código em Python do artigo anterior, ninguém falou de perfil; especificamos a porta RFCOMM 10 e pronto. Mas também ficou por nossa conta definir qual o protocolo de aplicação, e para que ele vai servir. A existência dos perfis facilita a interoperabilidade.

Por exemplo, o perfil SPP (Serial Port Profile) é extremamente simples. Ele define um serviço que simula um cabo serial, e impõe o uso do RFCOMM como transporte. Nada mais que isso.

Os perfis podem ser "empilhados" também. Por exemplo, o perfil DUN (Dial-Up Networking) é uma especialização do SPP. O serviço DUN especifica que haverá um modem no lado servidor, que serve para discar à Internet.

Como o DUN é empilhado em cima do SPP, as definições do SPP continuam valendo para o DUN: é um serviço semelhante a cabo serial, em cima de RFCOMM.

O perfil OPUSH implementa um serviço para troca de objetos (normalmente, mensagens e arquivos), utilizando o protocolo OBEX sobre transporte RFCOMM.

Existem inúmeros perfis, para impressoras, fax, mouse, teclado, emulação de LAN. Há diversos perfis "proprietários", dedicados a apenas um tipo de dispositivo, ou a um fabricante (exemplos: NGAGE, PCSUITE, WIIMOTE).

Uma parte importante do perfil, é que ele especifica como os outros dispositivos em volta vão "achar" o serviço. Para isto, dependemos do protocolo SDP.

SDP - Service Discovery Protocol

O SDP faz papel análogo ao Bonjour do Mac OS X. Ele viabiliza a descoberta de serviços nos dispositivos próximos, bem como suas portas RFCOMM, PSMs L2CAP, e nomes descritivos dos serviços. (Os nomes dos dispositivos são obtidos de outra forma, portanto o SDP não é análogo ao DNS.)

Todo dispositivo BT que não esteja oculto deve implementar o SDP, que sempre atende na mesma porta (L2CAP, PSM 1). O protocolo SDP é no estilo TLV (type, length, value), e pode conter diversos tipos de dados, bem como seqüências. Por ser tão genérico, o SDP permite a difusão de praticamente qualquer tipo de dado.

Aqui entra a importância dos perfis; são eles que ditam o formato dos dados difundidos via SDP. Cada perfil especifica um formato de "ficha de serviço" (service record). Nesta ficha, podem ser encontrados os dados essenciais à conexão (porta, PSM). A padronização garante que o lado cliente, interessado em determinado perfil, será capaz de interpretar a ficha de serviço sem problemas.

Quando um aplicativo deseja prestar um determinado serviço, ele deve criar a ficha no formato ditado pelo perfil, e solicitar a publicação da ficha via SDP. Idealmente, se houver um outro dispositivo próximo interessado em conectar àquele serviço, ele descobrirá os dispositivos à sua volta, obterá as fichas de serviço via SDP, descobrirá o serviço recém-publicado e fará conexão.

Exemplo de ficha SDP

Se quiséssemos que aquele "servidor" em Python do artigo anterior aparecesse no SDP, a forma mais simples de conseguir isto é usando o sdptool. Não muito profissional, mas funciona.

epx@neosaldina:~$ sdptool add --channel=10 SP
Serial Port service registered

epx@neosaldina:~$ sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
...
Service Name: Serial Port
Service Description: COM Port
Service Provider: BlueZ
Service RecHandle: 0x10008
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 10
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100

A ficha acima é exibida num formato bastante mastigado e legível. Internamente, cada item corresponde a um bytecode e a ficha toda ocupa uns poucos bytes. Note que no "Protocol Descriptor List", menciona-se L2CAP e RFCOMM, mas apenas o RFCOMM possui uma porta mencionada (10).

Para termos mais controle sobre o conteúdo da ficha, teríamos de usar uma API "séria" para criá-la e publicá-la. No caso do BlueZ, a API recomendada é a via D-BUS, e a ficha é especificada num formato XML. (Também existe uma API C, mas seu uso é desaconselhado.)